vue 之 watch

vue中watch的应用

vue中的watch可以侦听属性的变化,即属性变化的回调

先来一个简单的应用:

  data() {
    return {
      str: "text"
    }
  },
  watch:{
    str(v,ov){//页面加载不走
      console.log('value :>> ', v, ov);
    }
  }

  其中只要str发生变化就会走watch中的str这个方法,方法第一个参数是变化后的数据,第二个参数是变化之前的参数

 

如果监听的是一个对象的某个属性,用以上方式就没办法实现了:

data() {
    return {
      str: "text",
      persion: {
        firstName: "zhang",
        lastName: "san",
        fullName:''
      }
    };
  },
  computed: {
    fullName() {//用这种方式可以实现监听数据变化
      return this.persion.firstName + this.persion.lastName;
    }
  },
  watch:{
    str(v,ov){//页面加载不走
      console.log('value :>> ', v, ov);
    }
    //这样是监听不到的
    // firstName(v){
    //   console.log('v :>> ', v)
    // }
    //这样语法是错误的
    // persion.firstName(v){
    //   console.log('v :>> ', v)
    // }
  },

  监听对象的某个属性用computed可以实现,但和watch还是有区别的,可能并不是你的预期效果

 

监听对象的属性也可以用深度监听的方法,写法稍微不太一样:

data() {
    return {
      str: "text",
      persion: {
        firstName: "zhang",
        lastName: "san",
        fullName:''
      }
    };
  },
  computed: {
    fullName() {
      return this.persion.firstName + this.persion.lastName;
    }
  },
  watch:{
    persion:{
      immediate: true,//页面加载就走
      deep:true,//深度监听
      handler(val,old){
        console.log('val :>> ', val);
        console.log('old :>> ', old);
        this.persion.fullName = this.persion.firstName + this.persion.lastName;
      }
    },
    str(v,ov){//页面加载不走
      console.log('value :>> ', v, ov);
    }
    //这样是监听不到的
    // firstName(v){
    //   console.log('v :>> ', v)
    // }
  },

  另外加上immediate属性还可以实现,页面加载时候走,

 

以下附上全部代码:

<script>
export default {
  name: "WithoutHtmlView",
  data() {
    return {
      str: "text",
      persion: {
        firstName: "zhang",
        lastName: "san",
        fullName: ""
      }
    };
  },
  computed: {
    fullName() {
      return this.persion.firstName + this.persion.lastName;
    }
  },
  methods: {
    handleClick() {
      console.log("123 :>> ", 123);
    }
  },
  watch: {
    persion: {
      immediate: true, //页面加载就走
      deep: true, //深度监听
      handler(val, old) {
        console.log("val :>> ", val);
        console.log("old :>> ", old);
        this.persion.fullName = this.persion.firstName + this.persion.lastName;
      }
    },
    str(v, ov) {
      //页面加载不走
      console.log("value :>> ", v, ov);
    }
    //这样是监听不到的
    // firstName(v){
    //   console.log('v :>> ', v)
    // }
    ,'persion.firstName':function(v,ol){
      console.log('v :>> ', v);
      console.log('ol :>> ', ol);
    }
  },
  render(createElement) {
    const self = this;
    return createElement(
      "div",
      {
        on: {
          click: self.handleClick
        },
        class: "home"
      },
      [
        createElement("div", {
          ref: "mask",
          staticClass: "mask",
          // DOM 属性
          domProps: {
            innerHTML: self.str
          }
        }),
        createElement("p", {
          domProps: {
            // innerHTML: self.persion.firstName
            innerHTML: "name:" + self.persion.fullName
            // innerHTML: self.fullName
          }
        }),
        createElement("input", {
          staticClass: "ipt",
          domProps: {},
          on: {
            input: function(event) {
              self.persion.firstName = event.target.value;
              self.$emit("input", event.target.value);
            }
          },
          attrs: {
            value: self.persion.firstName
          }
        }),
        createElement("input", {
          staticClass: "ipt",
          staticStyle: "margin-top:20px;",
          domProps: {},
          on: {
            input: function(event) {
              self.str = event.target.value;
              self.$emit("input", event.target.value);
            }
          },
          attrs: {
            value: self.str
          }
        })
      ]
    );
  }
};
</script>
<style scope>
.home {
  width: 200px;
  height: 400px;
  padding: 50px;
  background-color: #98a0b0;
  box-sizing: border-box;
}
.mask {
  width: 100px;
  height: 100px;
  background-color: #d8d900;
  text-align: center;
  line-height: 100px;
  color: aliceblue;
  font-size: 22px;
}
.ipt {
  width: 100px;
  height: 40px;
  line-height: 40px;
}
</style>

  有兴趣的可以看下vue源码时怎么实现的:https://www.cnblogs.com/rainbowLover/p/13572949.html

posted on 2020-06-03 11:15  rainbowLover  阅读(207)  评论(0编辑  收藏  举报