前言:
目前正在学习vue或者对vue部分使用不太熟悉的可以跟着的我文章,打开编辑器,安装vue-cli一步步的练习,不会安装vue-cli脚手架的小伙伴可以先看这篇文章https://blog.csdn.net/m0_51062476/article/details/119826598?spm=1001.2014.3001.5501
以下也是个人练习和学习做的分享,如有问题大家可以留言交流
一、初识监听事件
<template>
<!-- 这里是子组件模板 -->
<!-- <template>里面一定要加div,没有会报错 -->
<div class="about">
<p>{{ onWatch }}</p>
<!-- 创建一个v-model双向绑定进行监听 -->
<input v-model="onWatch" />
<p>{{ onEventText }}</p>
</div>
</template>
<script>
export default {
//data函数用来声明变量
data() {
return {
onEventText: "",
onWatch: "开始",
};
},
watch: {
// 创建监听事件,监听后面有两个参数(新修改值,被修改的旧值)
onWatch(newQuestion, oldQuestion) {
console.log("新:", newQuestion, "旧:", oldQuestion);
},
},
};
</script>
结果渲染展示:
在输入框没有输入时
删除input中内容,查看控制台打印结果
输入123,查看控制台打印结果
二、通过监听双向绑定内容触发创建事件
<template>
<!-- 这里是子组件模板 -->
<!-- <template>里面一定要加div,没有会报错 -->
<div class="about">
<p>{{ onWatch }}</p>
<!-- 创建一个v-model双向绑定进行监听 -->
<input v-model="onWatch" />
<p>{{ onEventText }}</p>
</div>
</template>
<script>
export default {
//data函数用来声明变量
data() {
return {
onEventText: "",
onWatch: "开始",
};
},
watch: {
// 创建监听事件,监听后面有两个参数(新修改值,被修改的旧值)
onWatch(newQuestion) {
//这里做一个通过事件监听来驱动事件,这要加this否则会报错
this.onEvent(newQuestion);
},
},
methods: {
//创建事件,将事件监听中获取的最新值赋值给onEventText进行动态渲染
onEvent(a) {
this.onEventText = a;
},
},
};
</script>
初始页面展示
输入框中编辑文字后的页面展示
三、事件监听用命令式vm.$watch API写法
<template>
<!-- 这里是子组件模板 -->
<!-- <template>里面一定要加div,没有会报错 -->
<div class="about">
<p>{{ onWatch }}</p>
<!-- 创建一个v-model双向绑定进行监听 -->
<input v-model="onWatch" />
<p>{{ onEventText }}</p>
</div>
</template>
<script>
export default {
//data函数用来声明变量
data() {
return {
onEventText: "",
onWatch: "开始",
};
},
// 需要在页面渲染前创建监听事件实例
created() {
// 创建监听事件,监听后面有两个参数(新修改值,被修改的旧值)
this.$watch("onWatch", (newQuestion) => {
//这里做一个通过事件监听来驱动事件,这要加this否则会报错
this.onEvent(newQuestion);
});
},
methods: {
//创建事件,将事件监听中获取的最新值赋值给onEventText进行动态渲染
onEvent(a) {
this.onEventText = a;
},
},
};
</script>
最后结果与之前案例是一样的效果
三、监听对象或数组数据,触发监听情况
以上监听事件触发,如果是对象或数组内部改变是不会触发的,除非替换整个对象或数组内容
<template>
<!-- 这里是子组件模板 -->
<!-- <template>里面一定要加div,没有会报错 -->
<div class="about">
<!-- 创建渲染对象中的文本 -->
<label> 对象中文本<input type="text" v-model="object.text" /> </label>
<!-- 创建渲染对象中的数字 -->
<label> 对象中数字<input type="text" v-model="object.num" /> </label>
<label>
<!-- 循环渲染input并双向绑定,这里需要注意的是,数组内为对象,如果是存数组集合会报错 -->
数组<input
type="text"
v-for="(item, index) in list"
:key="index"
v-model="item.letter"
/>
</label>
<!-- 创建渲染集合中的数据,双向绑定修改时查看变化 -->
<div type="text" v-for="(item, index) in list" :key="index">
{{ item.letter }}
</div>
<!-- 创建事件,观察什么情况下触发事件监听,什么情况下不触发事件监听 -->
<div>对象修改是否被触发:<span v-show="objectShow">触发</span></div>
<button @click="objectClick">修改整个对象</button>
<div>数组修改是否被触发:<span v-show="listShow">触发</span></div>
<button @click="listClick">修改整个数组</button>
</div>
</template>
<script>
export default {
//data函数用来声明变量
data() {
return {
objectShow: false,
listShow: false,
object: {
text: "我是文本",
num: "123456",
},
list: [
{ letter: "a" },
{ letter: "b" },
{ letter: "c" },
{ letter: "d" },
{ letter: "e" },
],
};
},
// 需要在页面渲染前创建事件监听实例
created() {
// 创建对象事件监听
this.$watch("object", () => {
this.objectShow = true;
});
// 创建数组事件监听
this.$watch("list", () => {
this.listShow = true;
});
},
methods: {
// 替换对象数据
objectClick() {
this.object = {
text: "我是被修改的文本",
num: "7891011",
};
},
// 替换数组数据
listClick() {
this.list = [
{ letter: "f" },
{ letter: "g" },
{ letter: "h" },
{ letter: "i" },
{ letter: "j" },
];
},
},
};
</script>
初始渲染展示
修改对象中文本与数字,未触发事件监听
修改数组所有,双向绑定生效,未触发事件监听
点击修改整个对象,触发点击事件替换整个对象内容,事件监听被触发
点击修改整个数组,触发点击事件替换整个数组内容,事件监听被触发
四、事件监听选项deep
如果需要在修改对象内或数组内值的时候触发事件监听,需要添加deep: true,代码如下
// 需要在页面渲染前创建事件监听实例
created() {
// 创建对象事件监听
this.$watch(
"object",
() => {
this.objectShow = true;
},
{
deep: true,
}
);
// 创建数组事件监听
this.$watch(
"list",
() => {
this.listShow = true;
},
{
deep: true,
}
);
}
在修改对象中的值和数组中的值,触发结果
五、事件监听选项immediate
在没有添加immediate的时候,事件监听需要触发条件才会执行,添加immediate:true后或默认执行一次
<template>
<!-- 这里是子组件模板 -->
<!-- <template>里面一定要加div,没有会报错 -->
<div class="about">
<!-- 创建渲染对象中的文本 -->
<label> 对象中文本<input type="text" v-model="object.text" /> </label>
<!-- 创建渲染对象中的数字 -->
<label> 对象中数字<input type="text" v-model="object.num" /> </label>
<div>被触发次数{{ watchNum }}</div>
</div>
</template>
<script>
export default {
//data函数用来声明变量
data() {
return {
objectShow: false,
listShow: false,
object: {
text: "我是文本",
num: "123456",
},
// 创建触发次数变量
watchNum: "",
};
},
// 需要在页面渲染前创建事件监听实例
created() {
// 创建对象事件监听
this.$watch(
"object",
() => {
this.objectShow = true;
// 每触发一次加1
this.watchNum = this.watchNum * 1 + 1;
},
{
deep: true,
immediate: true,
}
);
},
};
</script>
首次渲染默认执行一次
首次渲染后在修改后触发执行
六、事件监听选项flush
这个选项我也没太弄明白,所有没有介绍,等我弄清楚了再修改这个位置。如果有知道的大佬也可以留言分享下这个选项的作用,相互交流非常感谢。
七、取消监听 unwatch()
下面演示一个错误写法,当事件监听中含有immediate: true的时候,unwatch会报错
created() {
// 创建对象事件监听
// 在创建的监听前面添加事件名,事件名可以自定义
var unwatch = this.$watch(
"object",
() => {
this.objectShow = true;
// 每触发一次加1
this.watchNum = this.watchNum * 1 + 1;
//销毁事件可以直接引用函数
unwatch();
},
{
deep: true,
immediate: true,
}
);
}
因为在第一次执行的时候unwatch事件还没有生成
如果事件中一定要加上immediate: true,需要在内部做一个判断
created() {
// 创建对象事件监听
// 在创建的监听前面添加事件名,事件名可以自定义
var unwatch = this.$watch(
"object",
() => {
this.objectShow = true;
// 每触发一次加1
this.watchNum = this.watchNum * 1 + 1;
//销毁事件可以直接引用函数,正确写法
if (unwatch) {
unwatch();
}
},
{
deep: true,
immediate: true,
}
);
}
这是在事件内部通过条件执行关闭事件监听,如果想通过其他自定义事件关闭监听的这么写
<template>
<!-- 这里是子组件模板 -->
<!-- <template>里面一定要加div,没有会报错 -->
<div class="about">
<!-- 创建渲染对象中的文本 -->
<label> 对象中文本<input type="text" v-model="object.text" /> </label>
<!-- 创建渲染对象中的数字 -->
<label> 对象中数字<input type="text" v-model="object.num" /> </label>
<div>被触发次数{{ watchNum }}</div>
<button @click="off">点我关闭事件监听</button>
</div>
</template>
<script>
export default {
//data函数用来声明变量
data() {
return {
objectShow: false,
listShow: false,
object: {
text: "我是文本",
num: "123456",
},
// 创建触发次数变量
watchNum: "",
// 将事件监听存在变量中
unwatch: "",
};
},
// 需要在页面渲染前创建事件监听实例
created() {
// 创建对象事件监听
// 在创建的监听前面添加事件名,事件名可以自定义
this.unwatch = this.$watch(
"object",
() => {
this.objectShow = true;
// 每触发一次加1
this.watchNum = this.watchNum * 1 + 1;
//销毁事件可以直接引用函数,正确写法
},
{
deep: true,
immediate: true,
}
);
},
methods: {
// 点击关闭按钮触发事件监听关闭
off() {
this.unwatch();
},
},
};
</script>
结果渲染展示
在未点击按钮事件监听是一致在触发的
当我点击以后,不在触发事件监听
当然这里取消了监听事件就无法重新激活监听事件了,我在网上搜了一下还是没找到解决方法,如果有大佬知道欢迎留言。