watch的使用

template中

 <div>名字:{{name}},年龄:{{age}}</div>

script中

 export default {
     props: {  name: String  },
     data() {  return {  age: 10  } },
     watch: {
         name(newValue, oldValue) {},
         age(newValue, oldValue) {}
     },
 }

这种情况通过watch监听的数据,当字段被第一次赋值时是不会执行监听函数的。只有值再次发生改变才会执行监听。那如何才能在第一次赋值时就执行监听函数呢?这里就需要用到immediate和handler

immediate和handler使用

在选项参数中指定 immediate: true 将立即以表达式的当前值触发回调
也就是说immediate值为true,则首次赋值时就执行handler函数,immediate值为false,则首次赋值时就不执行handler函数

 watch: {
     name: {
         handler(newValue, oldValue) {},
         immediate: true,
     },
     age: {
         handler(newValue, oldValue) {},
         immediate: true,
     },
 }

首次赋值监听时,oldValue值为undefined

deep 深度监听

当需要监听一个对象的改变时(注意这里监听的是整个对象),正常的watch无法监听到对象内部属性的改变,此时需要使用deep对对象进行深度监听

父组件

  people:{
      name:"露西"
  }

  btnClick() {
     this.people.name = "宙斯";
  }

子组件

  props: {
      people: {
          type: Object,
          //对象或数组的默认值必须从一个工厂函数返回。
          default: () => ({
              name: ""
          })
      }
  },
  watch: {
      people: {
          handler(newValue, oldValue) {
          },
          // immediate: true,  加上则首次也监听
          deep: true, //必须加上才能监听到people的变化
      },
  },

当对一个对象进行监听时,需要添加deep:true属性,此时修改对象内任意属性值都会被监听到。如果只想对对象中某一个属性进行监听,则可以使用字符串的形式监听对象某一个属性,如:

  watch: {
       'people.name': {
           handler(newValue, oldValue) {},
           deep: true,
       },
  }

deep和immediate可同时使用,表示首次绑定就触发监听函数

注意事项

1:数组的变动可直接进行监听,不需要deep属性,操作如下,若首次监听则需加immediate: true

  this.list.unshift({name: "宙斯"}) //添加到数组头部
  this.list.push({name: "宙斯"}) //添加到数组尾部

  this.list.shift() //删除数组头部一个元素
  this.list.pop() //删除数组尾部一个元素

  this.$set(this.list, 0, {name:"宙斯"}); //修改数组角标为0的数据

数组的splice方法,可用于插入、删除、替换操作,具体操作可移步到前端杂谈之splice用法

2:通过props传递对象或数组时,对象或数组的默认值必须从一个工厂函数返回,否则就会报

Invalid default value for prop “xxx”: Props with type Object/Array must use a factory function to return the default value.

  people: {
     type: Object,
     default: ()=>{}
  }

  list: {
     type: Array,
     default: ()=>[]
  }

props传递对象时,未传递的字段如何使用默认值

1:通过computed计算属性再定义一个对象,再用assign合并默认值和传递的对象,组件内则使用新定义的对象来展示数据,如

子组件

  <div> 姓名:{{privatePeople.name}} 年龄:{{privatePeople.age}} </div>

  props: {
      people: {
          type: Object,
          //数组/对象的默认值应当由一个工厂函数返回
          default: () => {}
      }
  },

  computed: {
      privatePeople() {
          let defaultPeople = {
              name: "露西",
              age: 10
          };
          return Object.assign({}, defaultPeople, this.people);
      }
  },
2:使用不带参数的v-bind=xxx

父组件

  <watch-components v-bind=people></watch-components>

  people: {
      name: "宙斯"
  }

子组件

  props: {
      name:{
          type:String,
          default:"露西"
      },
      age:{
          type:Number,
          default: 10
      }
  }
3:使用vuex对状态进行统一管理,子组件通过computed的计算属性获取存储在store中的变量

computed、watch、methods的区别和使用

computed计算属性-引用官网的示例

可监听data和props中的属性

主要用于当一些数据需要随着其它数据变动而变动时使用。如:购物车总金额

  computed: {
    fullName: function () {
      return this.firstName + ' ' + this.lastName
    }
  }
特点
1:计算属性是基于它们的响应式依赖进行缓存的。只在 相关响应式依赖 发生改变时它们才会重新求值。也就是说当computed函数所依赖的属性值没有发生改变时,调用的结果就会从缓存中读取。

这也同样意味着下面的计算属性将不再更新,因为 Date.now() 不是响应式依赖:

  computed: {
    now: function () {
      return Date.now()
    }
  }
2:计算属性必须有return返回
watch侦听属性-引用官网的示例

可监听data和props中的属性
主要用于当需要在数据变化时执行异步或开销较大的操作时使用,如搜素框

  watch: {
    question(newValue, oldValue) {
      this.axios() //执行异步逻辑
    }
  }
特点
1:watch中的函数名称必须和data或props中的属性名称一致
2:watch中函数有两个参数,第一个是newValue新值,第二个是oldValue旧值。
methods:函数方法

主要用于写一段业务逻辑

区别
  • computed计算属性结果会被缓存,只有依赖的属性发生改变才会重新计算,主要用于当一些数据需要随着其它数据变动而变动时使用
  • watch侦听属性用来侦听对象或属性的变化,然后执行对应回调,回调函数内主要用于执行某些业务逻辑,如异步操作或开销较大的操作
Logo

前往低代码交流专区

更多推荐