美文网首页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