• 687 vue3 Composition API:computed,watchEffect,watch


    computed


    01_computed的使用.vue

    <template>
      <div>
        <h2>{{ fullName }}</h2>
        <button @click="changeName">修改firstName</button>
      </div>
    </template>
    
    <script>
      import { ref, computed } from "vue";
    
      export default {
        setup() {
          const firstName = ref("Kobe");
          const lastName = ref("Bryant");
    
          // 1.用法一: 传入一个getter函数
          // computed的返回值是一个ref对象
          const fullName = computed(() => firstName.value + " " + lastName.value);
    
          // 2.用法二: 传入一个对象, 对象包含getter/setter
          const fullName = computed({
            get: () => firstName.value + " " + lastName.value,
            set(newValue) {
              const names = newValue.split(" ");
              firstName.value = names[0];
              lastName.value = names[1];
              // [firstName.value, lastName.value] = names
            },
          });
    
          const changeName = () => {
            // firstName.value = "James"
            fullName.value = "haha xixi";
          };
    
          return {
            fullName,
            changeName,
          };
        },
      };
    </script>
    
    <style scoped></style>
    

    侦听数据的变化


    watchEffect


    02_watchEffect基本使用.vue

    <template>
      <div>
        <h2>{{ name }}-{{ age }}</h2>
        <button @click="changeName">修改name</button>
        <button @click="changeAge">修改age</button>
      </div>
    </template>
    
    <script>
      import { ref, watchEffect } from "vue";
    
      export default {
        setup() {
          // watchEffect: 自动收集响应式的依赖
          const name = ref("why");
          const age = ref(18);
    
          const changeName = () => (name.value = "kobe");
          const changeAge = () => age.value++;
    
          // watchEffect会立即执行一次
          watchEffect(() => {
            console.log("name:", name.value, "age:", age.value);
          });
    
          return {
            name,
            age,
            changeName,
            changeAge,
          };
        },
      };
    </script>
    
    <style scoped></style>
    

    watchEffect的停止侦听


    03_watchEffect停止侦听.vue

    <template>
      <div>
        <h2>{{ name }}-{{ age }}</h2>
        <button @click="changeName">修改name</button>
        <button @click="changeAge">修改age</button>
      </div>
    </template>
    
    <script>
      import { ref, watchEffect } from "vue";
    
      export default {
        setup() {
          // watchEffect: 自动收集响应式的依赖
          const name = ref("why");
          const age = ref(18);
    
          // 【停止监听,但是界面数据继续更新】
          // watchEffect():返回的是一个函数
          const stop = watchEffect(() => {
            console.log("name:", name.value, "age:", age.value);
          });
    
          const changeName = () => (name.value = "kobe");
          const changeAge = () => {
            age.value++;
            if (age.value > 25) {
              stop(); // age.value > 25时,停止监听
            }
          };
    
          return {
            name,
            age,
            changeName,
            changeAge,
          };
        },
      };
    </script>
    
    <style scoped></style>
    

    watchEffect清除副作用


    04_watchEffect清除副作用.vue

    <template>
      <div>
        <h2>{{ name }}-{{ age }}</h2>
        <button @click="changeName">修改name</button>
        <button @click="changeAge">修改age</button>
      </div>
    </template>
    
    <script>
      import { ref, watchEffect } from "vue";
    
      export default {
        setup() {
          // watchEffect: 自动收集响应式的依赖
          const name = ref("why");
          const age = ref(18);
    
          const stop = watchEffect((onInvalidate) => {
            // 【这里用定时器模拟网络请求】
            const timer = setTimeout(() => {
              console.log("网络请求成功~");
            }, 2000);
    
            // 根据name和age两个变量发送网络请求
            // 在这个函数中清除额外的副作用 
            // 【组件销毁,监听器也随着销毁,并执行onInvalidate的回调函数,可在这里做清理相关工作。】
            onInvalidate(() => {
              // request.cancel() // 【取消上次的网络请求】
              clearTimeout(timer);
              console.log("onInvalidate---------");
            });
    
            console.log("name:", name.value, "age:", age.value);
          });
    
          const changeName = () => (name.value = "kobe");
          const changeAge = () => {
            age.value++;
            if (age.value > 25) {
              stop();
            }
          };
    
          return {
            name,
            age,
            changeName,
            changeAge,
          };
        },
      };
    </script>
    
    <style scoped></style>
    

    setup中使用ref


    watchEffect的执行时机


    调整watchEffect的执行时机


    05_watchEffect执行时机ref引用.vue

    <template>
      <div>
        <h2 ref="title">哈哈哈</h2>
      </div>
    </template>
    
    <script>
      import { ref, watchEffect } from "vue";
    
      export default {
        setup() {
          // 【常量名要和ref="title"中的title一致,否则打印的值都是null。】
          const title = ref(null);
    
          watchEffect(
            // 【副作用函数】
            () => {
              console.log(title.value); // <h2>哈哈哈</h2>
              // 哈哈哈, 通过innerHTML拿到DOM元素的值
              console.log(title.value.innerHTML); 
            },
            {
              // pre: 提前执行;  post:DOM挂载、更新完后执行
              flush: "post",
            }
          );
    
          return {
            title,
          };
        },
      };
    </script>
    
    <style scoped></style>
    

    Watch的使用


    侦听单个数据源


    06_watch侦听的数据源类型.vue

    <template>
      <div>
        <h2 ref="title">{{ info.name }}</h2>
        <button @click="changeData">修改数据</button>
      </div>
    </template>
    
    <script>
      import { ref, reactive, watch } from "vue";
    
      export default {
        setup() {
          // watchEffect是直接在函数里使用即可,不用管有哪些依赖
          const info = reactive({ name: "why", age: 18 });
    
          // 1.侦听watch时,传入一个getter函数 【() => info.name就是getter函数。】
          watch(
            () => info.name,
            (newValue, oldValue) => {
              console.log("newValue:", newValue, "oldValue:", oldValue);
            }
          );
    
          // 2.传入一个可响应式对象: reactive对象/ref对象
          // 情况一: reactive对象获取到的newValue和oldValue本身都是reactive对象
          // watch(info, (newValue, oldValue) => {
          //   console.log("newValue:", newValue, "oldValue:", oldValue);
          //   console.log("newValue:", newValue.name, "oldValue:", oldValue.name);
          // })
    
          // 如果希望newValue和oldValue是一个普通的对象
          watch(
            // 简写:() => ({...info})
            () => {
              return { ...info };
            },
            (newValue, oldValue) => {
              // 【此时,newValue和oldValue是一个普通的对象】
              console.log("newValue:", newValue, "oldValue:", oldValue);
              // console.log("newValue:", newValue.name, "oldValue:", oldValue.name);
            }
          );
    
          // 情况二: ref对象获取newValue和oldValue是value值的本身
          const name = ref("why");
          // watch(name, (newValue, oldValue) => {
          //   // 【这里不是newValue.value】
          //   console.log("newValue:", newValue, "oldValue:", oldValue);
          // })
    
          const changeData = () => {
            info.name = "kobe";
          };
    
          return {
            changeData,
            info,
          };
        },
      };
    </script>
    
    <style scoped></style>
    

    侦听多个数据源


    侦听响应式对象


    07_watch侦听多个数据源.vue

    <template>
      <div>
        <h2 ref="title">{{ info.name }}</h2>
        <button @click="changeData">修改数据</button>
      </div>
    </template>
    
    <script>
      import { ref, reactive, watch } from "vue";
    
      export default {
        setup() {
          // 1.定义可响应式的对象
          const info = reactive({ name: "why", age: 18 });
          const name = ref("haha");
    
          // 2.侦听器watch
          // 【变成普通的对象,如果不加圆括号,编译器就不知道是要返回...info,还是{ ...info}。】
          watch(
            [() => ({ ...info }), name],
            ([newInfo, newName], [oldInfo, oldName]) => {
              console.log(newInfo, newName);
              console.log(oldInfo, oldName);
            }
          );
    
          const changeData = () => {
            info.name = "kobe";
          };
    
          return {
            changeData,
            info,
          };
        },
      };
    </script>
    
    <style scoped></style>
    

    watch的选项


    08_深度监听.vue

    <template>
      <div>
        <h2 ref="title">{{info.name}}</h2>
        <button @click="changeData">修改数据</button>
      </div>
    </template>
    
    <script>
      import { ref, reactive, watch } from 'vue';
    
      export default {
        setup() {
          // 1.定义可响应式的对象
          const info = reactive({
            name: "why", 
            age: 18,
            friend: {
              name: "kobe"
            }
          });
    
          // 2.侦听器watch
          watch(() => ({...info}), (newInfo, oldInfo) => {
            console.log(newInfo, oldInfo);
          }, {
            // 【默认是可以深度监听的,源码中,当监听的数据源是reactive时,deep=true。】
            deep: true,
            immediate: true
          })
    
          const changeData = () => {
            info.friend.name = "james";
          }
    
          return {
            changeData,
            info
          }
        }
      }
    </script>
    

  • 相关阅读:
    hdu 4534 郑厂长系列故事——新闻净化 夜
    poj 1185 炮兵阵地 夜
    hdu 2586 How far away ? 夜
    C. Shaass and Lights 夜
    hdu 4536 XCOM Enemy Unknown 夜
    根据BAPI_PO_CREATE1创建采购订单
    301、404、200、304、500HTTP状态
    js检查Page.IsValid
    查看linq的生成语句
    uploadfile和Image实现图片预览
  • 原文地址:https://www.cnblogs.com/jianjie/p/14919591.html
Copyright © 2020-2023  润新知