记录vue中的独有的生命周期,语法糖
自定义v-model时间名及value
1 2 3 4
| <ChildComponent v-model="pageTitle" /> ========================================= <ChildComponent :title="pageTitle" @change="pageTitle = $event" />
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| export default { model: { prop: 'title', event: 'change' }, props: { value: String, title: { type: String, default: 'Default title' } } }
|
动态的指令参数
事件可以动态绑定 根据动态生成的事件名去调用相同事件
1 2 3 4 5 6 7
| <my-button @[someEvent]="handleSomeEvent()"/> data(){ return{ ... someEvent: variable ? "click" : "dblclick" } },
|
hookEvent(钩子事件监听)
1
| <List @hook:updated="handleTableUpdated"></List >
|
监听销毁事件,提高代码可读性
1 2 3 4 5 6 7
| vm.$on('hooks:created', cb) vm.$once('hooks:created', cb) mounted(){ this.$on('hooks:beforeDestroy'),()=>{ //执行销毁事件的逻辑 } }
|
v-cloak 解决页面闪烁问题
页面异步加载 Dom元素未渲染完毕时先隐藏 直到元素上关联实例结束编译
1 2 3 4 5 6 7 8 9
| // template 中 <div class="#app" v-cloak> <p>{{value.name}}</p> </div>
// css 中 [v-cloak] { display: none; }
|
函数式组件
1 2 3 4 5 6 7 8 9 10 11 12
| Vue.component('my-component', { functional: true, // Props 是可选的 props: { // ... }, // 为了弥补缺少的实例 // 提供第二个参数作为上下文 render: function (createElement, context) { // ... } })
|
this.$options.filters(使用定义好的filters)
声明式指令
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
| // 只能输入正整数,0-9的数字 Vue.directive('enterIntNumber', { inserted: function (el) { let trigger = (el, type) => { const e = document.createEvent('HTMLEvents') e.initEvent(type, true, true) el.dispatchEvent(e) } el.addEventListener("keyup", function (e) { let input = e.target; let reg = new RegExp('^\\d{1}\\d*$'); //正则验证是否是数字 let correctReg = new RegExp('\\d{1}\\d*'); //正则获取是数字的部分 let matchRes = input.value.match(reg); if (matchRes === null) { // 若不是纯数字 把纯数字部分用正则获取出来替换掉 let correctMatchRes = input.value.match(correctReg); if (correctMatchRes) { input.value = correctMatchRes[0]; } else { input.value = ""; } } trigger(input, 'input') }); } }); //使用指令 <!--限制输入正整数--> <input v-enterIntNumber placeholder="0" type="number"> 来源于作者:Gopal 原文链接:https://juejin.im/post/6872128694639394830
|
子组件传出单个参数时:
1 2 3 4
| this.$emit('test',this.param)
@test='test($event,userDefined)'
|
子组件传出多个参数时:
1 2 3 4
| this.$emit('test',this.param1,this.param2, this.param3)
@test='test(arguments,userDefined)'
|
对于异步请求的异常处理
1 2 3 4 5 6 7 8 9 10 11
| methods: { async getUserPageData() { try { const res = await Promise()/api请求 } catch(error) { } } }
|
这里 watch 的一个特点是,最初绑定的时候是不会执行的,要等到 firstName 改变时才执行监听计算。那我们想要一开始就让他最初绑定的时候就执行改怎么办呢?我们需要修改一下我们的 watch 写法,修改过后的 watch 代码如下:
1 2 3 4 5 6 7 8 9 10
| watch: { firstName: { handler(newName, oldName) { this.fullName = newName + ' ' + this.lastName; }, immediate: true } } 复制代码
|
注意到handler了吗,我们给 firstName 绑定了一个handler方法,之前我们写的 watch 方法其实默认写的就是这个handler,Vue.js会去处理这个逻辑,最终编译出来其实就是这个handler。
而immediate:true代表如果在 wacth 里声明了 firstName 之后,就会立即先去执行里面的handler方法,如果为 false就跟我们以前的效果一样,不会在绑定的时候就执行。
解决导航栏重复点击跳转报错报错
1 2 3 4
| const originalPush = Router.prototype.push; Router.prototype.push = function push(location) { return originalPush.call(this, location).catch(err => err); };
|
在组件中监听滚动事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| mounted() { window.addEventListener("scroll", this.handleScroll, true); }, methods: { handleScroll() { var scrollTop = document.querySelector("#main").scrollTop; var offsetTop = document.querySelector("#component").offsetTop; var clientHeight = document.querySelector("#component").clientHeight; }, } beforeDestroy() { window.removeEventListener("scroll", this.handleScroll, true); },
|
在 window.addEventListener 的第三个参数加上true,默认值为 false, 即冒泡传递,当值为 true 时, 事件使用捕获传递。beforeDestroy销毁也需要加上此属性
vue中对于页面刷新时事件的监听
使用原生的属性onbeforeunload
1 2 3 4 5 6 7 8 9 10 11
| window.onbeforeunload = function (e) { e = e || window.event; if (e) { e.returnValue = '关闭提示'; } return '关闭提示'; };
|
在methods中定义事件
1 2 3 4 5
| methods: { beforeunloadHandler (e) { } }
|
在 mounted,created 钩子中注册事件
1
| window.addEventListener('beforeunload', e => this.beforeunloadHandler(e))
|
在页面销毁destroyed 时清除监听
1 2 3
| destroyed() { window.removeEventListener('beforeunload', e => this.beforeunloadHandler(e)) }
|
vue中使用的防抖和节流
定义utils.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| let timeout = null let timer = null let start = 0 export const debounce = (func, delay) => { if (timeout !== null) clearTimeout(timeout) timeout = setTimeout(func, delay) }
export const Throttle = (func, wait, trailing) => { let now = new Date() if ((now - start) >= wait) { timer && clearTimeout(timer) timer = null start = now return func() } else if (!timer && trailing) { timer = setTimeout(() => { timer = null return func }, wait) } }
|
在组件中使用
1 2 3 4 5 6 7 8 9 10
| import {debounce,Throrrle} from "@/utils.js" debounce(() => { if (error.response.status === 400 || String(error).indexOf('code 400') !== -1) { debounce(() => { Message.error(error.response.data.message) }, 100) return Promise.reject(error.response.data) } }, 1000);
|
this.$set 为了设置一个数组的新属性添加在vm上进行响应式
Proxy(vue3的响应拦截)
1 2 3 4
| new Proxy(data, { get(key) { }, set(key, value) { }, })
|
defineProperty(vue2的响应拦截)
1 2 3 4
| Object.defineProperty(data, 'count', { get() {}, set() {}, })
|
