Vue3中的计算属性与监视

  • computed函数

    • 与Vue2.x中computed配置功能一致

    • 写法:有两种形式 简写形式  和完整写法 不管是那种写法我们都需要在组件中先引入computed方法在使用

    • 引入computed 方法
      import { computed } from 'vue'
    • 下面我们通过代码来具体演示它的用法  

    • 我们在setup方法中声明了一个data对象,  对象中我们提供了一个人的姓(firstName) 和 名(lastName) 然后我们通过计算属性计算出全名 并渲染到页面

    • 简写形式(没有考虑计算属性被修改的情况)

    • <template>
        <div>
          <p>姓:{{data.firstName}}</p>
          <p>名:{{data.lastName}}</p>
          <p>名:{{data.fullName}}</p>
        </div>
      </template>
      
      <script>
      import { reactive, computed } from 'vue'
      export default {
        name: 'App',
        setup() {
          let data = reactive({
            firstName: '张',
            lastName: '三'
          })
          // 计算属性简写形式 计算全名
          data.fullName = computed(() => {
            // 将计算结果返回
            return data.firstName + '-' + data.lastName
          })
      
          return {
            data
          }
        }
      }
      </script>
      

      在页面中我们可以看到 数据都被渲染出来了

    •  

    • 完整形式 (实现读写操作)

    • 我们在组件中将全名用双向数据绑定v-bind绑定在一个输入框中 通过修改输入框中的内容来实现写入操作 

    • computed配置对象中配置set方法 和get方法 通过set方法是实现修改效果 当我们修改计算属性的值时就会触发配置对象中set方法 来修改对应数据

    • ...
      <input v-model="data.fullName" />
      ...
      
      ...
      // 计算属性的完整写法
      data.fullName = computed({
        // 读取数据
        get() {
          return data.firstName + "-" + data.lastName;
        },
        // 修改数据
        set(value) {
          const nameArr = value.split("-");
          data.firstName = nameArr[0];
          data.lastName = nameArr[1];
        },
      });
      ...

      在浏览器中 我们修改计算属性的值可以看到对应的数据也会发送相应的变化

    •                              

  • watch函数

    • 与Vue2.x中watch配置功能一致

    • 两个小“坑”:

      • 监视reactive定义的响应式数据时:oldValue无法正确获取、强制开启了深度监视(deep配置失效)。

      • 监视reactive定义的响应式数据中某个属性时:deep配置有效。

    • 代码演示

      • 在watch()方法中可以传递三个参数:

        • 第一个参数是:要监视的属性

        • 第二个参数是:要执行的函数

        • 第三个参数是:监视属性的配置对象

      • 监视ref定义的响应式数据

      • <template>
          <div>
            <h2>年龄:{{ age }}</h2>
          <button @click="age++">点击年龄增加</button>
          </div>
        </template>
        
        <script>
        import { ref, reactive ,watch} from "vue";
        export default {
          name: "App",
          setup() {
            let age = ref(0)
            watch(age, (newValue,oldValue) => {
              console.log(`年龄发生变化---最新的年龄是${newValue} --- 修改之前的年龄是${oldValue}`);
            },{immediate:true})
            return {
              age
            };
          },
        };
        </script>
        

        通过监视属性监视age属性的变化 在浏览器中我们可以看到可以监视到age的变化

      • 监视多个ref定义的响应式数据

      • setup() {
            let age = ref(0)
            let name = ref("张三")
            
            watch([age, name], (newValue,oldValue) => {
              console.log('属性变化了',newValue, oldValue)
            },{immediate:true})
        
            return {
              age,
              name
            };
          },

        如果要监视多个数据 可以使用数组的写法,将要监视的属性写在数组里,newValue,oldValue参数将也会变成数组 按被照监听属性的顺序排列

      •  监视reactive定义的响应式数据

        • 若watch监视的是reactive定义的响应式数据,则无法正确获得oldValue!!

        • 若watch监视的是reactive定义的响应式数据,则强制开启了深度监视 

      •   setup() {
            let person = reactive({
              name : '张三',
              age: 20
            })
            watch(person, (newValue,oldValue) => {
              console.log('属性变化了',newValue, oldValue)
            }, {deep: false})   // deep被强制开启 此处的deep配置不再奏效
        
            return {
              person
            };
          },

        在浏览器中打印oldValue 我们可以看到无法获得正确的值了 (正确age值应该为20)

      • 监视reactive定义的响应式数据中的某个属性  (因为监视的是一个属性是基本数值类型所以oldValue好用) 

        • 定义的响应式数据中的某个属性 参数需要写成一个函数 并把要监视的属性返回 

        • watch(()=> person.age, (newValue,oldValue) => {
             console.log('属性变化了',newValue, oldValue)
          })

           

      • 监视reactive定义的响应式数据中的某些属性

        • 使用数组的方式传递监视属性的函数

        • watch([()=> person.age, ()=> person.name], (newValue,oldValue) => {
            console.log('属性变化了',newValue, oldValue)
          })

      • 监视reactive定义的响应式数据中的属性值是对象形式 (需要开启深度监视)
        • 我么在对象中添加了一个属性 属性值是一个对象 并定义了监听 我们之后修改对象内的属性 需要开启深度监视
        • <template>
            <div>
              <h2>姓名:{{ person.name }}</h2>
              <h2>年龄:{{ person.age }}</h2>
              <h2>年龄:{{ person.hobby.smoking.a }}</h2>
            <button @click="person.age++">点击年龄增加</button>
            <button @click="person.hobby.smoking.a += '~'">点击修改smoking</button>
            </div>
          </template>
          
          <script>
          import { ref, reactive ,watch} from "vue";
          export default {
            name: "App",
            setup() {
              let person = reactive({
                name : '张三',
                age: 20,
                hobby: {
                  smoking: {
                    a: '黄鹤楼'
                  }
                }
              })
              watch(() => person.hobby, (newValue,oldValue) => {
                console.log('属性变化了',newValue, oldValue)
              },{deep: true})  // 开启了深度监视
          
              return {
                person
              };
            },
          };
          </script>
          

          如果不开启深度监视 将无法监视到该属性的修改  开启后属性修改将被监视到

           

  • watchEffect函数

    • watch的套路是:既要指明监视的属性,也要指明监视的回调。

    • watchEffect的套路是:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性。

    • watchEffect有点像computed:

      • 但computed注重的计算出来的值(回调函数的返回值),所以必须要写返回值。

      • 而watchEffect更注重的是过程(回调函数的函数体),所以不用写返回值。

    • 代码演示

      • <template>
          <div>
            <h2>姓名:{{ person.name }}</h2>
            <h2>年龄:{{ person.age }}</h2>
            <h2>年龄:{{ person.hobby.smoking.a }}</h2>
            <button @click="person.age++">点击年龄增加</button>
            <button @click="person.hobby.smoking.a += '~'">点击修改smoking</button>
          </div>
        </template>
        
        <script>
        import { ref, reactive, watch, watchEffect } from "vue";
        export default {
          name: "App",
          setup() {
            let person = reactive({
              name: "张三",
              age: 20,
              hobby: {
                smoking: {
                  a: "黄鹤楼",
                },
              },
            });
            watchEffect(() => {
              //函数内使用了的属性都会被监视并触发该含函数
              const x1 = person.age;
              const x2 = person.hobby.smoking.a;
              console.log("watchEffect配置的回调执行了");
            });
        
            return {
              person,
            };
          },
        };
        </script>
        

        我们在代码中定义了一个watchEffect函数 在函数内使用了person.age属性和 person.hobby.smoking.a 但我么修改这两个属性的时候 就会触发watchEffect方法中的回调函数 

         

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李公子丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值