Vue实例方法 - 数据 (vm.$watch、vm.$set、vm.$delete)

本文详细介绍了Vue实例的$data操作方法,包括$watch用于监听数据变化,$set用于动态设置响应式属性,$delete用于删除属性。通过示例代码展示了如何监听对象、属性、函数返回值以及数组的变化,并提供了测试代码进行验证。同时强调了直接修改data中对象属性可能无法触发视图更新的问题。

Vue实例方法 - 数据 (vm.$watch、vm.$set、vm.$delete)

一、官网链接

vue 实例方法 - 数据

二、为什么使用?

  确保能触发 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}

      是否监听第一次变化

(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 />
    &emsp; &emsp; name:&ensp;{{obj.name}}
    <br />
    }
  </div>
  <div>
    obj.name:<input v-model="newName"/>&ensp;<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">
      &emsp; &emsp; {{key}}:&ensp;{{value}}
      <br />
    </div>
    }
  </div>
  <div>
    删除属性:<input v-model="pName"/>&ensp;<button @click="deleteObjProps">删除</button>
  </div>
  <br />
  <div>
    <div>2、数组内容</div>
    array: [
    <br />
    <div v-for="(item, index) in array">
      &emsp; &emsp; {{index}}:&ensp;{{item}}
      <br />
    </div>
    ]
  </div>
  <div>
    删除位置:<input v-model="aPos"/>&ensp;<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>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值