Vue3 监听属性

本章节,我们将为大家介绍 Vue3 监听属性 watch,我们可以通过 watch 来响应数据的变化。

以下实例通过使用 watch 实现计数器:

实例

<div id ="app">
    <p style ="font-size:25px;">计数器:{{ counter }}</p>
    <button @click ="counter++" style ="font-size:25px;">点我</button>
</div>
   
<script>
const app ={
  data(){
    return{
      counter:1
    }
  }
}
vm = Vue.createApp(app).mount('#app')
vm.$watch('counter',function(nval, oval){
    alert('计数器值的变化 :'+ oval +' 变为 '+ nval +'!');
});
</script>

尝试一下 »

以下实例进行千米之间的换算:

实例

<div id ="app">
    千米 :<input type ="text" v-model ="kilometers"  @focus="currentlyActiveField = 'kilometers'">
    米 :<input type ="text" v-model ="meters"@focus="currentlyActiveField = 'meters'">
</div>
<p id="info"></p>    
<script>
const app ={
  data(){
    return{
      kilometers :0,
      meters:0
    }
  },
  watch :{
    kilometers:function(newValue, oldValue){
      // 判断是否是当前输入框
      if(this.currentlyActiveField==='kilometers'){
        this.kilometers= newValue;
        this.meters= newValue *1000
      }
    },
    meters :function(newValue, oldValue){
      // 判断是否是当前输入框
      if(this.currentlyActiveField==='meters'){
        this.kilometers= newValue/1000;
        this.meters= newValue;
      }
    }
  }
}
vm = Vue.createApp(app).mount('#app')
vm.$watch('kilometers',function(newValue, oldValue){
  // 这个回调将在 vm.kilometers 改变后调用
  document.getElementById("info").innerHTML="修改前值为: "+ oldValue +",修改后值为: "+ newValue;
})
</script>

尝试一下 »

点击 "尝试一下" 按钮查看在线实例

以上代码中我们创建了两个输入框,data 属性中, kilometers 和 meters 初始值都为 0。watch 对象创建了 data 对象的两个监控方法: kilometers 和 meters。

当我们再输入框输入数据时,watch 会实时监听数据变化并改变自身的值。可以看下如下视频演示:

异步加载中使用 watch

异步数据的加载 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。

以下实例我们使用 axios 库,后面会具体介绍。

实例

<!-- 因为 AJAX 库和通用工具的生态已经相当丰富,Vue 核心代码没有重复 -->
<!-- 提供这些功能以保持精简。这也可以让你自由选择自己更熟悉的工具。 -->
<script src="https://cdn.staticfile.org/axios/0.27.2/axios.min.js"></script>
<script src="https://cdn.staticfile.org/vue/3.2.37/vue.global.min.js"></script>
<script>
  const watchExampleVM = Vue.createApp({
    data(){
      return{
        question:'',
        answer:'每个问题结尾需要输入 ? 号。'
      }
    },
    watch:{
      // 每当问题改变时,此功能将运行,以 ? 号结尾,兼容中英文 ?
      question(newQuestion, oldQuestion){
        if(newQuestion.indexOf('?')>-1|| newQuestion.indexOf('?')>-1){
          this.getAnswer()
        }
      }
    },
    methods:{
      getAnswer(){
        this.answer='加载中...'
        axios
          .get('/try/ajax/json_vuetest.php')
          .then(response =>{
            this.answer= response.data.answer
          })
          .catch(error =>{
            this.answer='错误! 无法访问 API。 '+ error
          })
      }
    }
  }).mount('#watch-example')
</script>

尝试一下 »