Vue相关设置和基础用法
零碎集
1. 多个锚点
有时候页面内容过多,要在侧栏做个导航栏:参考地址
2. 监听页面滚动
1 2 3 4 5 6 7 8 9 10 11 12
| methods: { handleScroll(){ console.log("I am scroll !!!") } }, created(){ window.addEventListener("scroll", this.handleScroll) }, destroyed(){ window.removeEventListener("scroll", this.handleScroll) } ;
|
3. 图片相对地址
如果用../../assets/example.png
插入.vue
文件,一旦文件变动,地址可能也要改。所以用vue-loader
的转换规则
@
在build/webpack.base.config.js
中可配置
1
| <img src="~@/assets/example.png">
|
ElementUI
1 2 3 4 5
| import ElementUI from "element-ui" import "element-ui/lib/theme-chalk/index.css"
ElementUI.Dialog.props.appendToBody.default = true; Vue.use(ElementUI);
|
内容较多,另开文章说明:第一版、第二版
VCharts
单个引入
1 2 3
| import VeLine from 'v-charts/lib/line' Vue.component(VeLine.name,VeLine);
|
1
| <ve-line :data="chartData" :settings="chartSettings" :extend="chartExtend" :grid="chartGrid" :colors="chartColor0"></ve-line>
|
所遇到相关问题:不点不知道
Emojify
1 2 3 4 5 6 7 8 9 10 11 12
| import Emojify from 'emojify.js'
import 'emojify.js/dist/css/sprites/emojify.min.css' Emojify.setConfig({ mode: 'sprite' }) Emojify.run() Vue.prototype.$emoji = Emojify;
let code = ":rose:", that = this, emojify = code.replace(/\:\w+\:/g,(str) => { return that.$emoji.replace(str) });
|
引入自定义组件
1 2
| import ReturnBack from '@/components/returnback' Vue.component('sl-back',ReturnBack);
|
全局过滤器
1. 时间戳转换
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| Vue.filter("Timer", (val, is_time, is_second) => {
if(!val){ return val } let stamp = new Date(parseInt(val)), year = stamp.getFullYear(), month = (stamp.getMonth()+1 < 10 ? '0'+(stamp.getMonth()+1) : stamp.getMonth()+1), day = (stamp.getDate() < 10 ? '0'+stamp.getDate() : stamp.getDate()), hour = (stamp.getHours() < 10 ? '0'+stamp.getHours() : stamp.getHours()), minute = (stamp.getMinutes() < 10 ? '0'+stamp.getMinutes() : stamp.getMinutes()), second = (stamp.getSeconds() <10 ? '0' + stamp.getSeconds() : stamp.getSeconds()), tims = year+"-"+month+"-"+day; if(is_time){ tims += " "+hour+":"+minute; tims = is_second ? times+":"+second : times; } return times; });
|
2. 筛选键值对
1 2 3 4 5 6 7 8 9 10 11 12 13
| Vue.filter("ValueToName", (val, list, key, name) => {
if(val || val == 0){ let arr = list.filter((v) => v[key] == val); return arr.length !== 0 ? arr[0][name] : val; }else{ return val } });
|
=> 栗子
1
| <div>{{ params.levelNo | ValueToName(levellist,'levelNo','levelName') }}</div>
|
3. 手机号码部分隐藏
1 2 3 4 5 6 7
| Vue.filter("BlurMobile", (val) => { if(val.length == 11){ return val.substr(0, 3) + '****' + val.substr(7) }else{ return val } });
|
4. 数字转换成千分位
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| Vue.filter("ToThousands", (val) => { if(typeof val !== 'number' && !isNaN(val)){ val = Number(val) } if(!val || val === 0 || isNaN(val)){ return val }else{ let num = 0; if(val.toString().indexOf ('.') !== -1){ num = val.toLocaleString() }else{ num = val.toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,'); } return num; } });
|
全局指令
1. 限制输入小数位数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
|
let FindElement = (parent, selector) => { return parent.tagName.toLowerCase() === selector ? parent : parent.querySelector(selector); }
let setValue = function(exp, value, context) { value = isNaN(value) ? '' : value new Function('context', 'value', `context.${exp} = value`)(context, value) }
let InputNumDigit = { bind: function(el, { expression }, { context }){ let $input = FindElement(el, 'input'); el.$input = $input;
$input.lastValue = $input.value
let allowDot = !!$input.dataset.dotrange, keys = $input.dataset.keys || -1, dotRange = $input.dataset.dotrange || `{0,2}`, pattern = `^[0-9]+${allowDot ? `(.[0-9]${dotRange})?` : ''}$`, new_expression = expression; if (!expression) { throw new TypeError('请绑定expression') }
if(keys !== -1){ new_expression = expression.replace(/\[.*?\]/, `[${keys}]`) } console.log(new_expression)
$input.handleInputEvent = function(e) { setTimeout(() => { if (e.target.value === '') { setValue(new_expression, '', context) e.target.value = '' } else if (e.target.value !== '' && !new RegExp(pattern).test(e.target.value)) { setValue(new_expression, parseFloat(e.target.lastValue), context) e.target.value = e.target.lastValue if (allowDot) { let num = dotRange.replace(/[}{]/g, '').split(',')[1]; if(num || num === 0){ $input.title = `小数点后最多${num}位` } } } e.target.lastValue = e.target.value }, 0) } $input.addEventListener('input', $input.handleInputEvent, false) }, unbind(el) { el && el.$input.removeEventListener('input', el.$input.handleInputEvent, false) } }; Vue.directive('num-digit', InputNumDigit)
|
=> 栗子:
1 2 3 4 5
| <el-input v-model.number="setForm.price" v-num-digit="setForm.price" data-dotrange="{0,2}" type="number" class="non-arrow"></el-input>
|
2. 防止按钮重复点击
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const deafultClock = 1000; let StopDoubleClick = { inserted: function(el, binding){ el.addEventListener("click", () => { console.log("———— stop double click ————") if(!el.disabled){ el.disabled = true setTimeout(() => { el.disabled = false }, binding.value || deafultClock) } }) } }; Vue.directive('stop-dbclick', StopDoubleClick)
|
=> 栗子
1
| <el-button v-stop-dbclick>保存</el-button>
|
Cookie
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| var getCookie = (name) => { let arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)"); arr = document.cookie.match(reg); return arr !== null ? decodeURIComponent(arr[2]) : null; } Vue.prototype.getCookie = getCookie; Vue.prototype.setCookie = (name,val,expir) => { let _date = new Date(); _date.setDate(_date.getDate() + expir); document.cookie = name + "=" + encodeURIComponent(val) + ((expir == null) ? "" : ";expires="+_date.toGMTString()); } Vue.prototype.delCookie = (name) => { let val = getCookie(name); if(val !== null){ document.cookie = name + "=" + val + ";expires=Thu, 01 Jan 1970 00:00:01 GMT;"; } }
this.setCookie("TOKEN",response.data); this.getCookie("TOKEN"); this.delCookie("TOKEN");
|
Vuex
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| import Vuex from 'vuex' import { Axios } from '@/axios' Vue.use(Vuex)
let GET_LIST = 'GET_LIST';
const Setting = { namespaced: true, state: { userlist: [] }, mutations: { SET_USER(state, list){ state.userlist = list } } } export default new Vuex.Store({ state: { api: { city: '/city.act' }, citylist: [] }, modules: { Setting, }, mutations: { [GET_LIST](state, { context, val }){ Axios.get(state.api[val.apiName], val.params).then((response) => { console.log(response) if(response.code){ state[listName] = response.data } }) } }, actions: { [GET_LIST](context, val){ context.commit(GET_LIST, { context, val }) } } });
|
栗子 => 模块命名空间
1
| this.$store.commit("Setting/SET_USER", []);
|
栗子 => 异步分发
1 2 3 4 5
| this.$store.dispatch('GET_LIST', { params: {enable: true}, apiName: 'city', listName: 'citylist' });
|
VueRouter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| import Router from 'vue-router' Vue.use(Router) export default new Router({ mode: 'history', base: '/home/', scrollBehavior(to, from, savedPosition){ if(savedPosition){ return savedPosition }else{ if(to.hash){ return { selector: to.hash } }else{ return { x: 0, y: 0 } } } }, routes: [{ path: '', name: 'login', component: (resolve) => require(['@/view/login'], resolve) },{ path: 'password', name: 'password', component: () => import('@/view/password') },{ path: 'container', name: 'container', component: (resolve) => require(['@/view/container'], resolve), meta: { keepAlive: true }, beforeEnter: (to, from, next) => { if(!localStorage.ACCOUNT || localStorage.ACCOUNT == ''){ next({ name: 'login' }) }else{ next() } } }] });
|
栗子 => 路由缓存
1 2 3 4
| <keep-alive> <router-view v-if="$route.meta.keepAlive"></router-view> </keep-alive> <router-view v-if="!$route.meta.keepAlive"></router-view>
|
栗子 => 缓存登录信息
1 2 3 4 5 6
| this.$http.post('login.api',userparam).then((response) => { if(response.data){ localStorage.removeItem("ACCOUNT"); localStorage.setItem("ACCOUNT",JSON.stringify(userparam)); } });
|
添加百度统计
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| router.afterEach((to, from, next) => { setTimeout(() => { var _hmt = _hmt || []; (function() { document.getElementById("BaiduStatis") && document.getElementById("BaiduStatis").remove(); var hm = document.createElement("script"); hm.id = "BaiduStatis"; hm.src = "https://hm.baidu.com/hm.js?id"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); },0) });
|
Webpack
1. 打包后移除console
in build/webpack.prod.conf.js
1 2 3 4 5 6 7 8 9 10
| new webpack.optimize.UglifyJsPlugin({ compress: { warning: false, dead_code: true, pure_funcs: ['console.log'], }, sourceMap: true });
|
2. 本机IP可访问项目
in build/webpack.dev.conf.js
1 2 3
| devServer: { host: '0.0.0.0' };
|
3. 打包时不包含.map文件
in config/index.js
1 2 3
| build: { productionSourceMap: false };
|
4. 第三方组件单独打包DLLPlugin
1. 新增文件
new build/webpack.dll.config.js 参考文章
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| var path = require('path'); var webpack = require('webpack');
module.exports = { entry: { vendor: ['vue/dist/vue.esm.js', 'axios', 'vue-router', 'element-ui', 'emojify.js', 'awe-dnd', 'echarts'] }, output: { path: path.join(__dirname, '../static/js'), filename: '[name].dll.js', library: '[name]_library' }, plugins: [ new webpack.DllPlugin({ path: path.join(__dirname, '.', '[name]-manifest.json'), name: '[name]_library', context: __dirname }), new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false, dead_code: true, pure_funcs: ['console.log'] } }) ] }
|
2. 新增插件
in build/webpack.dev.conf.js and build/webpack.prod.conf.js
1 2 3 4 5 6
| plugins: [ new webpack.DllReferencePlugin({ context: __dirname, manifest: require('./vendor-manifest.json') }) ]
|
3. 新增命令
in package.json
1 2 3
| "scripts": { "dll": "webpack --config ./build/webpack.dll.config.js" };
|
4. 引入DLL文件
in index.html
1
| <script src="/static/js/vendor.dll.js"></script>
|
5. 打包构建
1 2
| npm run dll npm run dev / npm run build
|
Vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import Vue from 'vue' import App from './App' new Vue({ el: "#app", router, store, render: h => h(App), watch: { '$route': 'handleRouter' }, methods: { handleRouter(){ console.log("路由变化...") } } });
|