抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

Mr.wang

Time flies and people come and go

记录vue中的独有的生命周期,语法糖

自定义v-model时间名及value

1
2
3
4
<!-- ParentComponent.vue -->
<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
// ChildComponent.vue
export default {
model: {
prop: 'title',
event: 'change'
},
props: {
// 这将允许 `value` 属性用于其他用途
value: String,
// 使用 `title` 代替 `value` 作为 model 的 prop
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)
// 父组件 arguments 是以数组的形式传入
@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) {
// 失败的情况写在catch中
}
}
}

handler方法和immediate属性

这里 watch 的一个特点是,最初绑定的时候是不会执行的,要等到 firstName 改变时才执行监听计算。那我们想要一开始就让他最初绑定的时候就执行改怎么办呢?我们需要修改一下我们的 watch 写法,修改过后的 watch 代码如下:

1
2
3
4
5
6
7
8
9
10
watch: {
firstName: {
handler(newName, oldName) {
this.fullName = newName + ' ' + this.lastName;
},
// 代表在wacth里声明了firstName这个方法之后立即先去执行handler方法
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;
//if (scrollTop - offsetTop - clientHeight + 500 > 0) {
// this.ForecastFixed = false;
// } else if (scrollTop > offsetTop - 50) {
// this.ForecastFixed = true;
//} else {
// this.ForecastFixed = false;
// }
},
}
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;

// 兼容IE8和Firefox 4之前的版本
if (e) {
e.returnValue = '关闭提示';
}

// Chrome, Safari, Firefox 4+, Opera 12+ , IE 9+
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
//函数防抖(debounce)
let timeout = null
let timer = null
let start = 0
export const debounce = (func, delay) => {
if (timeout !== null) clearTimeout(timeout)
timeout = setTimeout(func, delay)
}
//函数节流(Throttle)
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() {},
})

在这里插入图片描述

评论