Vue实例方法 - 数据 (vm.$watch、vm.$set、vm.$delete)
一、官网链接
二、为什么使用?
确保能触发 Vue 更新视图。(详见Vue.set等)
(说明:如果组件创建完成后,直接this.xxx的形式给data中对象增加新属性,可能无法被vue监听到。)
三、用法:
1、vm.$watch:
(1) 用法:vm.$watch( expOrFn, callback, [options] )
(2)参数:
- expOrFn:{Function | string}
被监听的:data/props中的变量 | 有返回值的函数体(注意使用方式)
- callback:{Function | Object}
回调函数 (newVal, oldVal)
- [options]:{Object}
监听选项:- deep:{boolean}
是否深度监听对象(数组)的属性
- immediate:{boolean}
是否监听第一次变化
- deep:{boolean}
(3)返回:unwatch 函数。执行该函数会取消监听。
(4)示例:
- 监听 data 中对象变量属性 / 对象变量
// vue 组件内部
...
data: () => ({
obj: {
name: '123'
}
}),
created () {
this.$watch('obj.name', (newV, oldV) => console.log(newV, oldV))
this.$watch('obj', (newV, oldV) => console.log(newV, oldV), {
immediate: true,
deep: true // 监听对象需启用深度监听。
})
}
...
- 监听 有返回值的函数体(注意使用方式)
// vue 组件内部
...
data: () => ({
obj: {
name: '123'
}
}),
created () { // 注意不要写 this.getName()
this.$watch(this.getName, (newV, oldV) => console.log(newV, oldV))
},
methods: {
getName () { return this.obj.name }
}
...
2、vm.$set
(1) 用法:vm.$set( target, propertyName/index, value )
(2)参数:
- target:{Object | Array}
被修改 对象 | 数组
- propertyName/index:{string | number}
对象属性 | 数组索引
- value:{any}
修改的值
(3)返回:修改的值。
(4)示例:
- 修改 data 中对象变量属性的值 / 数组指定位置的值
// vue 组件内部
...
data: () => ({
obj: {
name: '123'
},
array: [1, 2, 3]
}),
created () {
this.$set(this.obj, "name", "新的名字") // obj {name: '新的名字'}
this.$set(this.array, 0, 666) // array [666, 2, 3]
}
...
3、vm.$delete
(1) 用法:vm.$delete( target, propertyName/index )
(2)参数:
- target:{Object | Array}
被修改 对象 | 数组
- propertyName/index:{string | number}
被删除 对象属性 | 数组索引
(3)返回:无。
(4)示例:
- 删除 data 中对象变量属性的值 / 数组指定位置的值
// vue 组件内部
...
data: () => ({
obj: {
name: '123',
age: 21
},
array: [1, 2, 3]
}),
created () {
this.$delete(this.obj, "name") // obj {age: 21}
this.$delete(this.array, 0) // array [2, 3]
}
...
四、测试代码
1、vm.$watch
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
.show{
display: inline-block;
width: auto;
height: 20px;
border: 1px solid #a6a6a6;
color: black;
line-height: 20px;
white-space: nowrap;
}
</style>
</head>
<body >
<div id="delete">
<div>
<p>1、监听 对象 (obj)</p>
<div>对象:{{obj}}</div>
<div>修改obj.name:<input v-model="obj.name"/></div>
<div>你修改的值:<div class="show">{{str1}}</div></div>
<div>
<br />
<button @click="watchFn(0)">开始监听</button>
<button @click="unwatchFn(0)">取消监听</button>
</div>
</div>
<div>
<p>2、监听 对象属性 (obj.name)</p>
<div>对象:{{obj2}}</div>
<div>修改obj.name:<input v-model="obj2.name"/></div>
<div>你修改的值:<div class="show">{{str2}}</div></div>
<div>
<br />
<button @click="watchFn(1)">开始监听</button>
<button @click="unwatchFn(1)">取消监听</button>
</div>
</div>
<div>
<p>3、监听 带返回值函数</p>
<div>对象:{{obj3}}</div>
<div>修改obj.name:<input v-model="obj3.name"/></div>
<div>你修改的值:<div class="show">{{str3}}</div></div>
<div>
<br />
<button @click="watchFn(2)">开始监听</button>
<button @click="unwatchFn(2)">取消监听</button>
</div>
</div>
<div>
<p>4、监听 数组</p>
<div>数组:{{array}}</div>
<div>修改第一个数:<input v-model="array[0]"/></div>
<div>你修改的值:<div class="show">{{str4}}</div></div>
<div>
<br />
<button @click="watchFn(3)">开始监听</button>
<button @click="unwatchFn(3)">取消监听</button>
</div>
</div>
</div>
<script>
new Vue({
el: '#delete',
data: () => ({
unwatch: ['','','',''],
str1: '',
str2: '',
str3: '',
str4: '',
obj: {
name: 'obj',
},
obj2: {
name: 'obj2',
},
obj3: {
name: 'obj3',
},
array: [1,2,3]
}),
methods: {
getName () {
return this.obj3.name
},
watchFn (type) {
switch (type) {
case 0:
(!this.unwatch[type]) && (()=>{
this.unwatch[type] = this.$watch("obj", (v)=>this.str1=v.name, {deep: true, immediate: true})
})()
break;
case 1:
(!this.unwatch[type]) && (()=>{
this.unwatch[type] = this.$watch("obj2.name", (v)=>this.str2=v, {deep: true, immediate: true})
})()
break;
case 2:
(!this.unwatch[type]) && (()=>{
this.unwatch[type] = this.$watch(this.getName, (v)=>this.str3=v, {deep: true, immediate: true})
})()
break;
case 3:
(!this.unwatch[type]) && (()=>{
this.unwatch[type] = this.$watch("array", (v)=>this.str4=v[0], {deep: true, immediate: true})
})()
break;
default:
break;
}
},
unwatchFn (type) {
this.unwatch[type] && (()=>{this.unwatch[type](); this.unwatch[type] = ''})()
},
}
})
</script>
</body>
</html>
2、vm.$set
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body >
<div id="set">
<div>
<div>1、修改对象属性</div>
obj:{
<br />
    name: {{obj.name}}
<br />
}
</div>
<div>
obj.name:<input v-model="newName"/> <button @click="setObjName">修改</button>
</div>
<br />
<div>
<div>2、修改数组属性</div>
array:{{array}}
</div>
<div>index:<input v-model="aIndex"/> ( 0, 1, 2, ... )</div>
<div>value:<input v-model="aValue"/></div>
<div><button @click="setArray">修改</button></div>
</div>
<script>
new Vue({
el: '#set',
data: () => ({
newName: '',
aIndex: '',
aValue: '',
obj: {
name: '123',
age: 123
},
array: [
1,2,3
]
}),
methods: {
setObjName () {
this.$set(this.obj, 'name', this.newName)
},
setArray () {
this.$set(this.array, parseInt(this.aIndex), this.aValue)
}
}
})
</script>
</body>
</html>
3、vm.$delete
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body >
<div id="delete">
<div>
<div>1、对象属性</div>
obj: {
<br />
<div v-for="(value,key) in obj">
    {{key}}: {{value}}
<br />
</div>
}
</div>
<div>
删除属性:<input v-model="pName"/> <button @click="deleteObjProps">删除</button>
</div>
<br />
<div>
<div>2、数组内容</div>
array: [
<br />
<div v-for="(item, index) in array">
    {{index}}: {{item}}
<br />
</div>
]
</div>
<div>
删除位置:<input v-model="aPos"/> <button @click="deleteArrayPos">删除</button>
</div>
</div>
<script>
new Vue({
el: '#delete',
data: () => ({
pName: '',
aPos: '',
obj: {
name: '123',
age: 123,
a: 'a1',
b: 'b1',
c: 'c1'
},
array: [
1,2,3
]
}),
methods: {
deleteObjProps () {
console.log(this.$delete(this.obj, this.pName))
},
deleteArrayPos () {
this.$delete(this.array, this.aPos)
}
}
})
</script>
</body>
</html>
本文详细介绍了Vue实例的$data操作方法,包括$watch用于监听数据变化,$set用于动态设置响应式属性,$delete用于删除属性。通过示例代码展示了如何监听对象、属性、函数返回值以及数组的变化,并提供了测试代码进行验证。同时强调了直接修改data中对象属性可能无法触发视图更新的问题。
2978

被折叠的 条评论
为什么被折叠?



