参考文档 $watch

什么时候使用它?

我们都知道,当父组件向子组件传值时,子组件通过props 可以接收到父组件传过来的值
但这样只能接收父组件的静态值:比如以下代码:
下边是个数字框组件展示这个问题:

父组件

<template>
  <div id="app">
    <one v-model="value" :max='10' :min="0"></one>
  </div>
</template>
<script>
import one from './components/one'
export default {
  components:{
    one
  },
  data(){
    return{
      value:5
    }
  }
}
</script>


子组件

<template>
    <div class="three">
        {{currentValue}}
    </div>
</template>
<script>
export default {
    props:{
      max:{
        type:Number,
        default:Infinity
      },
      min:{
        type:Number,
        default:-Infinity
      },
      value:{
        type:Number,
        default:0
      }
    },
    data(){
      return{
        currentValue:this.value
      }
    }
};
</script>
以上父子组件,当你手动改变父组件中的 value 值得时候,在子组件都能立马展示出来,
且数据立马会更新出来!但实际开发中我们的数据都是动态传给子组件的,

接着你就会发现一个问题来,当我们传一个动态的数据时,发现子组件的数据竟然没有变化?
怎么解决呢,这时候就要用到vue的$watch了
----------------------------------------
贴个代码演示 动态数据 传入子组件中  子组件的数据不会改变

在刚才的父组件中加入一个点击事件,我们让这个数字每次点击+1

<template>
  <div id="app">
    <one v-model="value" :max='10' :min="0"></one>
    <button @click="addvalue">+</button>
  </div>
</template>
<script>

import one from './components/one'


export default {
  components:{
    one
  },
  data(){
    return{
      value:5
    }
  },
  methods:{
    addvalue(){
    //每次点击数据都加了1
      this.value++
    }
  }
}
</script>

子组件不变

<template>
    <div class="three">
        {{currentValue}}
    </div>
</template>
<script>
export default {
    props:{
      max:{
        type:Number,
        default:Infinity
      },
      min:{
        type:Number,
        default:-Infinity
      },
      value:{
        type:Number,
        default:0
      }
    },
    data(){
      return{
        currentValue:this.value
      }
    }
};
</script>
完整代码 ,数据改变 watch监听 (一个数字框输入框组件)

父组件

<template>
  <div id="app">
    <one v-model="value" :max='10' :min="0"></one>
    <br>
    {{ value }}
    <br>
    <button @click="addvalue">+</button>
  </div>
</template>
<script>

import one from './components/one'

export default {
  components:{
    one
  },
  data(){
    return{
      value:5
    }
  },
  methods:{
    addvalue(){
      this.value++
    }
  }
}
</script>


子组件

<template>
    <div class="three">
        <!-- {{currentValue}}z -->
        <input type="text" :value="currentValue" @change="handelChange">
        <button @click="handelDown" :disabled="currentValue <= min">-</button>   
        <button @click="handelUp" >+</button>   
    </div>
</template>
<script>
// 判断是不是数字
function isValueNumber(value){
  return (/(^-?[0-9]+\.{1}\d+$)|(^-?[1-9][0-9]*$)|(^-?0{1}$)/).test(value +'')
}
export default {
    props:{
      max:{
        type:Number,
        default:Infinity
      },
      min:{
        type:Number,
        default:-Infinity
      },
      value:{
        type:Number,
        default:0
      }
    },
    data(){
      return{
        currentValue:this.value
      }
    },
    // 加入 watch 监听数据变化 
    watch:{
      // 接收两个参数 第一个是改变后的新值newvalue,第二个是老值oldvalue,
      // 只写一个,默认是新值
      value(val){
        // 这样重新赋值后,就得到了父组件动态改变的数据
        this.currentValue = val
      },
      // 实际业务中,当子组件值改变时,有时候也会通知父组件,这时我们也要监听子组件的数据变化
      currentValue(val){
        this.$emit('input',val)
      }
    },
    mounted () {
      this.updataValue(this.value)
    },
    methods:{
      // 点击-1时,得到更新的值,告诉父组件
      handelDown(){
        if(this.currentValue <= this.min) return;
        this.currentValue -=1;
      },
      // 点击+1 ,得到更新后的值告诉父组件
      handelUp(){
        if(this.currentValue >= this.max) return;
        this.currentValue +=1;
      },

      updataValue(val){
        if(val > this.max) val = this.max
        if(val <this.min) val = min
        this.currentValue = val
      },
      // 失去焦点时,得到更新后的值
      handelChange(){
        let val = event.target.value.trim();
        console.log(val)
        let max = this.max;
        let min = this.min;
        if(isValueNumber(val)){
          val = Number(val)
          this.currentValue = val
          if(val > max){
            this.currentValue = max
          }else if(val < min){
            this.currentValue = min
          }else{
            event.target.value = min
          }
        }else{
          event.target.value = this.currentValue
        }
      }
    }
};
</script>

Logo

前往低代码交流专区

更多推荐