美文网首页react & vue & angularvue
Vue3.0 基础学习自我理解(五)

Vue3.0 基础学习自我理解(五)

作者: coderhzc | 来源:发表于2022-07-03 17:24 被阅读0次

    1.computed的基本使用

    <template>
      <div>
        <!-- 1.直接显示,这种拼接是可以实现响应式 -->
        <h1>{{ lastName }} {{ fristName }}</h1>
    
        <hr />
        <!-- 2. 拼接的方式显示 ---这种拼接的不是响应式的  -->
        <h1>{{ fullName }}</h1>
    
        <!-- 3. setup中使用computed可以实现响应式 一   get函数的使用 -->
        <h1>{{ fullsNameOne }}</h1>
    
        <button @click="changeName">改变姓名</button>
      </div>
    </template>
    
    <script>
    import { ref, computed } from "vue";
    export default {
      // vue 2.0的写法
      // computed: {}
      setup() {
        const fristName = ref("zhenchu");
        const lastName = ref("hu");
    
        // 2.这种拼接的不是响应式的
        const fullName = lastName.value + "  " + fristName.value;
    
        // 3. 在setup中使用计算属性,这个地方直接对应的是一个get 使用方式一 get函数的使用
        const fullsNameOne = computed(() => lastName.value + " " + fristName.value);
    
        const changeName = () => {
          lastName.value = "wang";
        };
        return {
          fristName,
          lastName,
          fullName,
          fullsNameOne,
    
          changeName,
        };
      },
    };
    </script>
    
    <style>
    </style>
    

    实际截图

    image.png

    2. computed对象的使用

    <template>
      <div>
        <!-- 4. setup中使用computed可以实现响应式 二   对象的使用 -->
        <h1>{{ fullsNameTwo }}</h1>
        <button @click="changeName">改变姓名</button>
      </div>
    </template>
    
    <script>
    import { ref, computed } from "vue";
    export default {
      setup() {
        const fristName = ref("zhenchu");
        const lastName = ref("hu");
    
        // 1. 在setup中使用计算属性,这个地方直接对应的是一个get 使用方式二 对象的使用 对象包含getter/setter
        const fullsNameTwo = computed({
          get: () => lastName.value + "  " + fristName.value,
    
          set(newValue) {
            console.log(newValue);
            const names = newValue.split(" ");
            console.log(names);
            fristName.value = names[0];
            lastName.value = names[1];
          },
        });
    
        const changeName = () => {
          fullsNameTwo.value = "coder hu";
        };
        return {
          fullsNameTwo,
    
          changeName,
        };
      },
    };
    </script>
    
    <style>
    </style>
    

    实际截图

    image.png

    3. watch侦听器-watchEffect的基本使用

    <template>
      <div>
        <h1>{{ names }} -- {{ age }}</h1>
    
        <button @click="changeName">修改name</button>
        <button @click="changeAge">修改age</button>
      </div>
    </template>
    
    <script>
    import { ref, watchEffect } from "vue";
    export default {
      // watchEffect用于自动收集响应式数据的依赖;
      setup() {
        const names = ref("hzc");
        const age = ref(18);
        const changeName = () => (names.value = "wang");
        const changeAge = () => age.value++;
    
        // 需求: 我现在想监听 names 和age的发生的变化: 方式一: 使用watchEffect函数
        /**
         * PS: 注意watchEffect回调函数: 默认在第一次不管三七二十会先执行一次的,
         *     因为这个函数会在刚开始的时候就是立即执行一次,他会先观察那些数据是响应式的数据
         *
         * **/
        watchEffect(() => {
          console.log("names:", names.value);
          console.log("age:", age.value);
        });
        return {
          names,
          age,
          changeName,
          changeAge,
        };
      },
    };
    
    
    /**
     *  ps: 当侦听到某些响应式数据变化时,我们希望执行某些操作,这个时候可以使用 watchEffect。
     *      -- 首先,watchEffect传入的函数会被立即执行一次,并且在执行的过程中会收集依赖;
     *      -- 其次,只有收集的依赖发生变化时,watchEffect传入的函数才会再次执行;
     * 
     * **/
    </script>
    
    <style>
    </style>
    

    实际截图

    image.png

    4.watchEffect的停止侦听

    <template>
      <div>
        <h1>{{ names }} -- {{ age }}</h1>
        <button @click="changeAgeMore20StopWatch">修改年纪大于20 停止侦听</button>
      </div>
    </template>
    
    <script>
    import { ref, watchEffect } from "vue";
    export default {
      /**
       * PS: 如果在发生某些情况下,我们希望停止侦听,这个时候我们可以获取watchEffect的返回值函数,调用该函数即可
       *     当age达到20的时候就停止侦听:
       *
       *
       * **/
    
      setup() {
        const names = ref("huzhenchu");
        const age = ref(18);
    
        // 当你在调用 watchEffect 这个函数的时候 他是有一个返回值的,他返回的是一个函数
        const stopWatch = watchEffect(() => {
          console.log("names:", names.value, "age:", age.value);
        });
        console.log(stopWatch); // stopWatch他是一个函数
    
        const changeAgeMore20StopWatch = () => {
          age.value++;
          if(age.value > 25) stopWatch(); // 当age.value 大于25 以后 上面侦听器中的打印不会再执行了, 但是html中的年纪是会变化的
        };
        return {
          names,
          age,
          changeAgeMore20StopWatch,
        };
      },
    };
    </script>
    
    <style>
    </style>
    

    实际截图

    image.png

    5. watchEffect清除副作用

    <template>
      <div>
        <h1>{{ names }} -- {{ age }}</h1>
        <button @click="changeAgeMore20StopWatch">修改年纪大于20 停止侦听</button>
      </div>
    </template>
    
    <script>
    import { ref, watchEffect } from "vue";
    export default {
      /**
       * PS: 什么是清除副作用呢?
       *     -- 比如在开发中我们需要在侦听函数中执行网络请求,但是在网络请求还没有请求回来的时候,
       *        我们停止了侦听器,或者侦听器侦听函数被再次执行了。
       *     -- 那么上一次的网络请求应该被取消掉,这个时候我们就可以清除上一次的副作用;
       *
       *
       * 1. 在我们给watchEffect传入的函数被回调时,其实可以获取到一个参数:onInvalidate
       *    -- 当副作用即将重新执行 或者 侦听器被停止 时会执行该函数传入的回调函数;
       *    -- 我们可以在传入的回调函数中,执行一些清除工作;
       * **/
    
      setup() {
        const names = ref("huzhenchu");
        const age = ref(18);
    
        // 在我们给watchEffect传入的函数被回调时,其实可以获取到一个参数:onInvalidate 他本身也是一个回调函数
        const stopWatch = watchEffect((onInvalidate) => {
          // 根据names 和age 两个变量发送网络请求
          const timer = setTimeout(() => {
            console.log("300ms后执行的操作");
          }, 300);
          onInvalidate(() => {
            // 在这个函数中清除额外的副作用
            clearTimeout(timer);
          });
          console.log("names:", names.value, "age:", age.value);
        });
    
        const changeAgeMore20StopWatch = () => {
          age.value++;
          if (age.value > 25) stopWatch(); // 当age.value 大于25 以后 上面侦听器中的打印不会再执行了, 但是html中的年纪是会变化的
        };
        return {
          names,
          age,
          changeAgeMore20StopWatch,
        };
      },
    };
    </script>
    
    <style>
    </style>
    

    实际截图

    image.png

    6.setup中使用ref

    <template>
      <div>
        <!-- 1.Vue2.0的获取方式:  -->
        <h1 ref="title">哈哈哈哈</h1>
        <button @click="foo">获取h1标签的内容信息</button>
    
        <hr />
        <!-- 2.Vue3.0的获取方式:在setup中如何使用ref获取元素获取组件  -->
        <h1 ref="setupTitle">嘿嘿嘿黑</h1>
        <button @click="setupGetTitle">在setup中获取h1标签的内容信息</button>
    
        <!-- 把获取到的值放入到 div盒子中 -->
        <div class="context-box">{{ getH1InnerHTML }}</div>
      </div>
    </template>
    
    <script>
    import { ref } from "vue";
    export default {
      // 2.在setup中如何使用ref获取元素获取组件?
      setup() {
        const setupTitle = ref(null);
        const getH1InnerHTML = ref();
    
        const setupGetTitle = () => {
          console.log(setupTitle.value.innerHTML); // 嘿嘿嘿黑
          getH1InnerHTML.value = setupTitle.value.innerHTML;
        };
        return {
          setupTitle,
    
          getH1InnerHTML,
    
          setupGetTitle,
        };
      },
    
      // 1. 以前在Vue 2.0 中 获取一个html 的元素 或者 标签 一般是使用: this.$refs.xxx
      methods: {
        foo() {
          console.log(this.$refs.title.innerHTML); // 哈哈哈哈
        },
      },
    };
    </script>
    
    <style scoped>
    .context-box {
      width: 200px;
      height: 200px;
      background-color: pink;
      color: red;
      font-weight: bold;
      margin-top: 10px;
      text-align: center;
      line-height: 180px;
      font-size: 28px;
    }
    </style>
    

    实际截图

    image.png

    7. setup中使用ref使用watchEffect来监听一

    <template>
      <div>
        <!-- 2.Vue3.0的获取方式:在setup中如何使用ref获取元素获取组件  -->
        <h1 ref="setupTitle">嘿嘿嘿黑</h1>
      </div>
    </template>
    
    <script>
    import { ref, watchEffect } from "vue";
    export default {
      // 2.在setup中如何使用ref获取元素获取组件?
      setup() {
        const setupTitle = ref(null);
        /**
         * 我们会发现打印结果打印了两次:
         *    -- 这是因为setup函数在执行时就会立即执行传入的副作用函数,这个时候DOM并没有挂载,所以打印为null;
         *    -- 而当DOM挂载时,会给title的ref对象赋值新的值,副作用函数会再次执行,打印出来对应的元素;
         * **/
        watchEffect(() => {
          console.log("setupTitle:", setupTitle.value);
        });
        return {
          setupTitle,
        };
      },
    };
    </script>
    
    <style>
    </style>
    

    实际截图

    image.png

    8. setup中使用ref使用watchEffect来监听二

    <template>
      <div>
        <!-- 2.Vue3.0的获取方式:在setup中如何使用ref获取元素获取组件  -->
        <h2 ref="setupTitle">嘿嘿嘿黑</h2>
      </div>
    </template>
    
    <script>
    import { ref, watchEffect } from "vue";
    export default {
      setup() {
        const setupTitle = ref(null);
        /**
         * 我们会发现打印结果打印了两次:
         *    -- 这是因为setup函数在执行时就会立即执行传入的副作用函数,这个时候DOM并没有挂载,所以打印为null;
         *    -- 而当DOM挂载时,会给title的ref对象赋值新的值,副作用函数会再次执行,打印出来对应的元素;
         * 
         * 
         * 
         * 需求: 如果我们希望在第一次的时候就打印出来对应的元素呢?
         *      -- 这个时候我们需要改变副作用函数的执行时机;
         *      -- 它的默认值是pre,它会在元素 挂载 或者 更新 之前执行;
         *      -- 所以我们会先打印出来一个空的,当依赖的title发生改变时,就会再次执行一次,打印出元素;
         * 
         * 我们可以设置副作用函数的执行时机:
         * **/
        watchEffect(() => {
          console.log("setupTitle:", setupTitle.value);
        },{
          flush: "post" // sync:不推荐使用, pre: 提前执行, post: 希望demo 挂载完成以后 再执行
        });
        return {
          setupTitle,
        };
      },
    };
    
    /**
     * PS: watchEffect 第一个参数是: 回调函数;
     *                 第二个参数是: flush (flush 选项还接受 sync,这将强制效果始终同步触发。然而,这是低效的,应该很少需要)
     * 
     * **/
    </script>
    
    <style>
    </style>
    

    实际截图

    image.png

    9.setup中使用-watch-reactive对象

    <template>
      <div>
        <h2>{{info.name }}</h2>
        <button @click="changeData">修改数据</button>
      </div>
    </template>
    
    <script>
    import { reactive, watch } from "vue";
    export default {
      /**
       * Watch的使用:
       *   -- watch的API完全等同于组件watch选项的Property:
       *   -- watch需要侦听特定的数据源,并在回调函数中执行副作用;
       *   -- 默认情况下它是惰性的,只有当被侦听的源发生变化时才会执行回调;
       *
       * 区别:
       * 与watchEffect的比较,watch允许我们:
       *   -- 懒执行副作用(第一次不会直接执行);
       *   -- 更具体的说明当哪些状态发生变化时,触发侦听器的执行;
       *   -- 访问侦听状态变化前后的值;
       * **/
    
      /**
       * 侦听单个数据源:
       *   -- watch侦听函数的数据源有两种类型:
       *   -- 一个getter函数:但是该getter函数必须引用可响应式的对象(比如reactive或者ref)
       *   -- 直接写入一个可响应式的对象,reactive或者ref(比较常用的是ref);
       * **/
      setup() {
        const info = reactive({ name: "huzhenchu", age: 18 });
        // 参数一: 监听的对象源头, 参数二: 回调函数 
        // reactive对象获取到的newValue和oldValue本身都是reactive对象
        watch(info, (newValue, oldValue) => {
          console.log("newValue:", newValue);
          console.log("oldValue:", oldValue);
        });
    
        console.log(info);
    
        const changeData = () => {
          info.name = "chuchuhu";
        };
    
        return {
          changeData,
          info
        };
      },
    };
    </script>
    
    <style>
    </style>
    

    实际截图

    image.png

    10. setup中使用-watch-单个数据的侦听

    <template>
      <div>
        <h2>{{info.name }}</h2>
        <button @click="changeData">修改数据</button>
      </div>
    </template>
    
    <script>
    import { reactive, watch } from "vue";
    export default {
      /**
       * 侦听单个数据源:
       *   -- watch侦听函数的数据源有两种类型:
       *   -- 一个getter函数:但是该getter函数必须引用可响应式的对象(比如reactive或者ref)
       *   -- 直接写入一个可响应式的对象,reactive或者ref(比较常用的是ref);
       * **/
      setup() {
        const info = reactive({ name: "huzhenchu", age: 18 });
        // 参数一: 监听的对象源头, 回调函数
        watch(()=> info.name, (newValue, oldValue) => {
          console.log("newValue:", newValue); // newValue: chuchuhu
          console.log("oldValue:", oldValue); // oldValue: huzhenchu
        });
    
        // console.log(info);
    
        const changeData = () => {
          info.name = "chuchuhu";
        };
    
        return {
          changeData,
          info
        };
      },
    };
    </script>
    
    <style>
    </style>
    

    实际截图

    image.png

    11.setup中使用-watch-ref对象

    <template>
      <div>
        <h2>{{ name }}</h2>
        <button @click="changeData">修改数据</button>
      </div>
    </template>
    
    <script>
    import { ref, watch } from "vue";
    export default {
      /**
       * 侦听单个数据源:
       *   -- watch侦听函数的数据源有两种类型:
       *   -- 一个getter函数:但是该getter函数必须引用可响应式的对象(比如reactive或者ref)
       *   -- 直接写入一个可响应式的对象,reactive或者ref(比较常用的是ref);
       * **/
      setup() {
        const name = ref("chuchuhu");
        
        watch(name, (newValue, oldValue) => {
          console.log("newValue:", newValue);
          console.log("oldValue:", oldValue);
        });
        const changeData = () => {
          name.value = "guxiaohu"
        };
        return {
          name,
          changeData,
        };
      },
    };
    </script>
    
    <style>
    </style>
    

    实际截图

    image.png

    12. setup中使用-watch-侦听多个数据源

    <template>
      <div>
        <h1>{{ name }}</h1>
        <button @click="changeName">修改名称</button>
      </div>
    </template>
    
    <script>
    import { reactive, ref, watch } from "vue";
    export default {
      setup() {
        const name = ref("chuchuhu");
        const info = reactive({ name: "guxiaohu", age: 18 });
        const changeName = () => {
          name.value = "楚楚胡";
        };
    
        // 侦听多个数据
        watch([info, name], ([newInfo, newName], [oldInfo, oldName]) => {
          console.log(newInfo);
          console.log(newName);
          console.log(oldInfo);
          console.log(oldName);
        });
        return {
          name,
          changeName,
        };
      },
    };
    </script>
    
    <style>
    </style>
    

    实际截图

    image.png

    13.setup中使用-watch-深度侦听

    <template>
      <div>
        <h1>{{ info.friend.name }}</h1>
        <button @click="changeName">修改名称</button>
      </div>
    </template>
    
    <script>
    import { reactive, ref, watch } from "vue";
    export default {
      setup() {
        const info = reactive({
          name: "guxiaohu",
          age: 18,
          friend: {
            name: "Kobe",
          },
        });
    
        // 1.侦听多个数据,这种默认是可以侦听的
        // watch(info, (newValue, oldValue) => {
        //   console.log(newValue);
        //   console.log(oldValue);
        // });
    
        // 2.这种是不会默认侦听的,所以要加上第三个参数了他是一个对象
        watch(()=> ({...info}),(newValue,oldValue)=> {
          console.log(newValue,oldValue);
        },{
          deep:true, // 设置深度侦听
          immediate: true // 设置这个的时候就是当你进来的第一次就会执行 里面的监听操作
        })
    
        const changeName = () => {
          info.friend.name = "乔丹";
        };
        return {
          info,
          changeName,
        };
      },
    };
    </script>
    
    <style>
    </style>
    

    实际截图

    image.png

    相关文章

      网友评论

        本文标题:Vue3.0 基础学习自我理解(五)

        本文链接:https://www.haomeiwen.com/subject/cdxrbrtx.html