Vue学习计划-Vue2--Vue核心(四)watch监听属性、动态绑定class、style,set方法的使用

1. 监听(watch): 监听一个属性的变化,又叫监听器,侦听器

  1. 监视属性watch:

    1. 当监视的属性变化时,回调函数自动调用,进行相关操作
    2. 监视的属性必须存在,才能进入监视
    3. 监视的两种写法:
      1. new Vue时传入watch配置
      2. 通过vm.$watch()监视
    4. immediate初始化时让handler调用一下
  2. 深度监视:

    1. Vue中的watch默认不监视对象内部值的变化(只监视一层)
    2. 配置deep:true可以监视对象内部值变化(监视多层结构)
  3. 监视watch有两种完整写法:

  1. 在Vue实例内部
  const vm = new Vue({
      el: "#app",
      watch:{
          immediate: true, // 初始化时让handler调用一下
          deep: true, // 深度监听
          handler(newValue, oldValue){
              console.log(newValue, oldValue)
          }
      }
  })
  2.  实例身上调用$watch API
  vm.$watch('isSHow',{
      immediate: true, // 初始化时让handler调用一下
      deep: true, // 深度监听
      handler(newValue, oldValue){
          console.log(newValue, oldValue)
      }
  })
  1. 监视对应的有两种简写:当确定不使用immediatedeep属性时可以简写
    1. 写在Vue实例内部 
    const vm = new Vue({
	    el: "#app",
	    watch:{
	        isShow(newValue, oldValue){
	            console.log(newValue, oldValue)
	        }
	    }
    })
    2. 实例身上调用$watch API
    vm.$watch('isSHow', function(newValue, oldValue){
    	console.log(newValue, oldValue)
    })
  1. 备注:

    1. Vue自身可以监视对象内部值得变化,但Vue提供的watch默认不可以
    2. 使用watch时,根据数据的具体结构,决定是否采用深度监听
  2. 计算属性(computed)、方法methods、监听(watch)的区别?

    computed、watch、methods专人干专事

    1. 计算属性computed:
      1. 目的是得到一个计算结果,必须要有return,一个状态值受多个状态值影响。
      2. 有缓存,当依赖状态值变化是,才会重新计算。
      3. 不能异步
      4. 本身不支持传参,可以使用闭包
    2. 事件methods
      1. 绑定的事件处理,非必须return
      2. 没有缓存
    3. 监听watch:
      1. 一个状态的改变 影响多条数据,没有return
      2. 没有缓存
      3. 可以异步
      4. 不传参

2. 标签体上动态class和style绑定

  1. class样式 写法: :class = "xxx", xxx可以是字符串、对象、数组
    1. 字符串写法适用于:类名不确定,要动态获取
    2. 对象写法适用于:要绑定多个样式,个数不确定,名字也不确定
    3. 数组写法适用于:要绑定多个样式,个数确定,名字也确定
  2. style样式
    :style = "{fontSize: xxx}" 其中xx是动态的
    :style = "[a, b]" 其中a, b是样式对象
    
    示例:
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./vue.js"></script>
    <style>
      /* #region */
      .red{
        color: red;
      }
      .blue{
        color: blue;
      }
      .green{
        color: green
      }
      .yellow{
        color: yellow
      }
      /* #endregion */
      .bold{
        font-weight: bold;
      }
      .size{
        font-size: larger;
      }
    </style>
    </head>
    <body>
    <div id="app">
      <!-- 1. 绑定字符串 -->
      <!-- 1.1.1 固定切换class名称 -->
      <p :class="name">这是一个动态class</p>
      <button @click="changClass">点击单次切换class名</button>
      <br>
      <!-- 1.1.2 随机切换class名称 -->
      <!-- class 和:class 可以绑定多个class名称 -->
      <p class="bold" :class="name">这是一个动态class</p>
      <button @click="changClass2">点击数组切换class名</button>
      <br>
        <!-- 1.1.3 三元表达式表达式切换class名称 -->
        <p :class="isName ? 'red' : 'blue'">这是一个动态class</p>
        <button @click="isName = !isName">表达式切换class名</button>
      <hr>
      <!-- 2. 绑定对象 -->
      <!-- <p :class="{bold: true, size: false}">这是一个对象绑定的class类名</p> -->
      <p :class="objClass">这是一个对象绑定的class类名</p>
      <button @click="objClassChange">表达式切换class名</button>
      <hr>
      <!-- 3. 绑定数组 -->
      <!-- <p :class="['blue', 'bold', 'size']">这是一个对象绑定的class类名</p> -->
      <p :class="arrClass">这是一个对象绑定的class类名</p>
      <button @click="arrClassChange">表达式切换class名</button>
    
    </div>
    <script>
      const vm = new Vue({
        el: '#app',
        data: {
          name: 'red',
          isName: true,
          arr:['red', 'blue', 'green'],
          // 对象class名称
          objClass:{
            red: true,
            bold: true
          },
          // 数组class名称
          arrClass:[ 'blue', 'bold', 'size']
        },
        methods: {
          // #region 字符串绑定
          changClass(){
            this.name = 'blue'
          },
          changClass2(){
            const a = Math.floor(Math.random() * 3)
            console.log(this.arr[a]);
            this.name = this.arr[a]
          },
          // #endregion
          objClassChange(){
            // this.objClass.size = true
            // 解决方法 $set方法
            // this.$set(this.objClass, 'size', true)
            Vue.set(this.objClass, 'size', true)
    
          },
          arrClassChange(){
            // this.arrClass.splice(0, 1, 'yellow')
            // 存在问题?为何vm中的arrClass值改变了,页面却没有渲染 => Vue内部监视原理
            // this.arrClass[0] = 'yellow'
            // 解决方法
            // this.$set(this.arrClass, 0, 'yellow')
            this.$set(this.arrClass, 0, 'yellow')
          }
        },
      })
    </script>
    
    </body>
    </html>
    

3. set方法的使用

  1. Vue会监视data中所有层次的数据。
  2. 如何监视对象的数据? 通过setter实现监视,且要在new Vue时就传入要监测的内容
    • 对象中后追加的属性,Vue默认不做响应式处理
    • 如需要给后添加的属性做响应式,使用如下API:
      Vue.set(target, propertyName/index, value)
      vm.$set(target, propertyName/index, value)
      

示例:

<body>
	<div id="app">
	  {{ obj }}
	  <button @click="changeObj">点击改变obj值</button>
	</div>
	<script>
		const vm = new Vue({
		  el: '#app',
		  data:{
		    obj:{
		      name: '小明'
		    }
		  },
		  methods: {
		    changeObj(){
		      // this.obj.banji = 'xx班级' // 后添加的数据不会是响应式的
		      // 解决方法
		      // this.$set(this.obj, 'banji', 'xx班级')
		      Vue.set(this.obj, 'banji', 'xx班级')
		    },
		  },
		})
	</script>
</body>
  1. 如何监视数组中的数据? 通过包裹数组更新元素的方法实现,本质就是做两件事
    1. 调用原生对应的方法对数组进行更新
    2. 重新解析模板,进而更新页面
  • 在Vue修改数组中的某个元素一定要用如下方案:
    1. 使用这些API:push(), pop(), shift(), unshift(), sort(), reverse(), splice()
  1. **Vue.set()或者vm.$set()**的使用场景
    • 给对象新添的属性处理成响应式数据
    • 给数组的添加响应式数据

    特别注意:Vue.set()和vm.$set()不能给vm或者vm的根数据对象添加属性!!

示例:

<body>
	<div id="app">
	  {{ arr }}
	  <button @click="changeArr">点击改变arr值</button>
	  <hr>
	  {{ arr2 }}
	  <span v-once>{{ arr2 }}</span>
	  <button @click="changeArr2">点击改变arr顺序sort方法</button>
	  <hr>
	  {{ arr3 }}
	  <button @click="changeArr3">点击翻转arr</button>
	</div>
	<script>
	const vm = new Vue({
	  el: '#app',
	  data:{
	    arr:['小亮', 10],
	    arr2:[ 10, 40, 5, 30],
	    arr3:[ 1, 2, 3, 4]
	  },
	  methods: {
	    changeArr(){
	      // this.arr[0] = '小白'
	      // 解决方法一: set
	      // this.$set(this.arr, 2, 'xx班级')
	      // Vue.set(this.arr, 2, 'xx班级')
	
	      // this.arr[2] = '小白'
	      // 解决方法二:内置函数
	      // 1. 数组后添加值
	      // this.arr.push('小白')
	      // 2. 数组后删除值
	      // this.arr.pop()
	      // 3. 从头往后删除数组
	      // this.arr.shift()
	      // 4. 数组前面加值
	      // this.arr.unshift('小小')
	      
	    },
	    // 数组排序
	    changeArr2(){
	      // 5. sort()
	      // 正序
	      this.arr2.sort((a,b) =>{
	        console.log('--');
	        console.log(a, b);
	        return a-b
	      })
	      // this.arr2.sort((a,b) =>{
	      //   return b - a
	      // })
	    },
	    // 翻转数组
	    changeArr3(){
	      // this.arr3.reverse()
	      // this.arr3.splice(1, 2, 'a', 'b', 'v')
	      // 注意: 禁止给vm或者vm的跟数据对象添加属性
	      // console.log(vm._data)
	      // this.$set(vm._data, 'name', 'ssss')
	      // this.$set(vm, 'name', 'ssss')
	    }
	  },
	})
	</script>
</body>
  • 16
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值