• 【Vue3】--setup两个属性+computed+watch【练习代码已上传至Gitee】


    二、 setup的两个注意点

    2-1-1 set的两个参数: props,context

    1. setup执行的时机:

      • 在beforeCreate之前执行一次,this是undefined
    2. setup的两个参数:

      • props: 值为对象,包含:组件外部传递过来,且组件内部声明接受了的属性
        • attrs帮忙兜底
      • context: 上下文对象
        • attrs: z值为对象,包含: 组件外部传递过来,但没有在props配置中声明的属性,相当于this.$attrs
        • slots:收到的插槽内容,相当于: this.$slots
        • emit: 分发自定义事件的函数,相当于this.$emit
    3. 两个参数

      setup(props, context) {
        console.log("--setup--", props);
        console.log("--setup--", context); 
     }
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    2-1-2 props与emits【子像父传递参数,父向子传递参数】

    2-1-2-1 父组件App.vue
    <template>
      <div id="app">
        <h1>我是Vue2写的效果h1>
        <Demo @hello="showHelloMsg" msg="信息" school="TYUT">
          <template v-slot:qwe>
            <span>具名插槽一span>
          template>
          
        Demo>
      div>
    template>
    
    <script>
    import Demo from "./components/Demo.vue";
    export default {
      name: "App",
      components: { Demo },
      setup() {
        function showHelloMsg(value) {
          alert(`你好啊,我出发了hello事件,我收到的参数是${value}`);
        }
        return {
          showHelloMsg,
        };
      },
    };
    script>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    2-1-2-2 子组件Demo.vue
    <template>
      <div>
        <h1>一个人的信息h1>
        <button @click="test">测试触发一下Demo组件的Hello事件button>
      div>
    template>
    
    <script>
    import { reactive } from "vue";
    export default {
      name: "Demo",
      props: ["msg"],
      emits: ["hello"],
    
      setup(props, context) {
        console.log("--setup--", props);
        console.log("--setup--", context); // attrs,emit,slots
    
        // 数据
        let person = reactive({
          name: "张三",
          age: 18,
        });
    
        // 方法
        function test() {
          context.emit("hello", 777);
        }
    
        return {
          person,
          test,
        };
      },
    };
    script>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    在这里插入图片描述

    三、计算属性computed + watch

    3-1 computed

    1. import {reactive,computed} from 'vue'
      export default {
          name: 'Demo',
          setup() {
              let person = reactive({
                  fN: '张',
                  lN: '三'
              })
              // 计算属性:没有考虑计算属性被修改的情况
              person.fullName = computed(() => {
                  return person.firstName + '-' + person.lastName
              })
              // 计算属性-完整写法
      		person.fullName = computed({
                  get() {
                      return person.fN + '_' + person.lN
                  },
                  set(value) {
                      const nameArr = value.split('_')
                      person.fN = nameArr[0]
                      person.fN = nameArr[1]
                  }
              })
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25

    3-2 watch

    3-2-1 两个小坑

    1. 两个小坑

      • 监视reactive所定义的一个响应式数据时:

        • oldValue无法获取、强制开启了深度监视(deep配置失效)
      • 监视reactive定义的响应式数据中某个属性时:deep配置有效

    3-2-2 监视的几种情况及结果展示

    1. 监视的几种情况【总的例子】
      <template>
      <div>
        <h1>当前求和为: {{ sum }}</h1>
        <h1>msg:{{ msg }}</h1>
        <button @click="sum++">点我+1</button>
        <h2>姓名: {{ person.name }}</h2>
        <h2>年龄: {{ person.age }}</h2>
        <button @click="person.age++">增长年龄</button>
      </div>
    </template>
    
    <script>
    import { ref, watch, reactive } from "vue";
    export default {
      name: "Demo",
      // vue2
      // watch: {
      //   sum(oldValue, NewValue) {
      //     console.log("sum的值改变了,newValue,oldValue");
      //   },
      //   // sum: {
      //   //   immediate: true,
      //   //   deep: true,
      //   //   handler(newValue, oldValue) {},
      //   // },
      // },
      setup() {
        // 数据
        let sum = ref(0);
        let msg = ref("你好");
        let person = reactive({
          name: "张三",
          age: 18,
        });
    
        // 监视
        // 情况一:监视ref所定义的多个响应式数据
        watch(
          [sum, msg],
          (newValue, oldValue) => {
            console.log("sum变了", newValue, oldValue);
          },
          { immediate: true }
        );
        // 情况二:监视reactive所定义的一个响应式数据的全部属性
        // 此处无法正确获取oldValue
        // 强制开启了深度监视(deep配置无效)
        watch(person, (nV, oV) => {
          console.log("person变化了", nV, oV);
        });
        // 情况三:监视reactive所定义的一个响应式数据中的某个属性
        watch(
          () => person.age,
          (nV, oV) => {
            console.log("person变化了", nV, oV);
          },
          { deep: false }
        );
        // 情况四:监视reactive所定义的一个响应式数据中的某些属性
        watch([() => person.name, () => person.age], (newValue, oldValue) => {
          console.log("person的name或age变化了", newValue, oldValue);
        });
        // 特殊情况,监视person.job
        watch(
          () => person.job,
          (nV, oV) => {
            console.log("person的job变化了", newValue, oldValue);
          },
          { deep: true } // 此处由于监视的时reactive定义的对象中的某个属性,所以deep配置有效
        );
    
        // 返回一个对象
        return {
          sum,
          msg,
          person,
        };
      },
    };
    </script>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    1. 情况一:监视ref所定义的多个响应式数据
        watch(
          [sum, msg],
          (newValue, oldValue) => {
            console.log("sum变了", newValue, oldValue);
          },
          { immediate: true }
        );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    1. 情况二:监视reactive所定义的一个响应式数据的全部属性
        // 此处无法正确获取oldValue
        // 强制开启了深度监视(deep配置无效)
        watch(person, (nV, oV) => {
          console.log("person变化了", nV, oV);
        },{deep:false});   // deep配置无效
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    1. 情况三:监视reactive所定义的一个响应式数据中的某个属性
        watch(
          () => person.age,
          (nV, oV) => {
            console.log("person变化了", nV, oV);
          },
          { deep: false }
        );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1. 情况四:监视reactive所定义的一个响应式数据中的某些属性
        watch([() => person.name, () => person.age], (newValue, oldValue) => {
          console.log("person的name或age变化了", newValue, oldValue);
        });
    
    • 1
    • 2
    • 3

    在这里插入图片描述

    3-2-3 watch时value的问题

    1. 在这里插入图片描述
    2. 在这里插入图片描述

    3-3 watchEffect

    1. watchEffect(() => {
           const x1 = sum.value;
           const x2 = person.job;
           console.log("watchEffect所指定的回调执行了");
         });
      
      • 1
      • 2
      • 3
      • 4
      • 5

      在这里插入图片描述

      • watch的套路: 既要指明监视的属性,也要指明监视的回调
      • watchEffect的套路是:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性
      • watchEffect有点像computed:
        • 但computed注重的计算出来的值(回调函数的返回值),所以必须要写返回值
        • 而watchEffect更注重的是过程(回调函数的函数体),所以不用写返回值

    四、生命周期

    4-1-1

    请添加图片描述

      • beforeCreate —> setup()
      • created —> setup()
      • beforeMount ===> onBeforeMount
      • mounted —> onMounted
      • beforeUpdate —>onBeforeUpdate
      • updated —> onUpdated
      • beforeUnmount —> onBeforeUnmount
      • unmounted-----> onUnmounted

    4-1-2

    1. 配置项及组合API的生命周期钩子
    <template>
      <div>
        <h1>当前求和为: {{ sum }}</h1>
        <h1>msg:{{ msg }}</h1>
        <button @click="sum++">点我+1</button>
      </div>
    </template>
    
    <script>
    import {
      ref,
      onBeforeMount,
      onMounted,
      onBeforeUpdate,
      onUpdated,
      onBeforeUnmount,
      onUnmounted,
    } from "vue";
    export default {
      name: "Demo",
    
      setup() {
        let sum = ref(0);
        let msg = ref("你好");
    
        onBeforeMount(() => {
          console.log("---beforeMount--");
        });
        onMounted(() => {
          console.log("---mounted--");
        });
        onBeforeUpdate(() => {
          console.log("---beforeUpdata--");
        });
        onUpdated(() => {
          console.log("---updated--");
        });
        onBeforeUnmount(() => {
          console.log("---beforeUpdata--");
        });
        onUnmounted(() => {
          console.log("---updated--");
        });
        return {
          sum,
          msg,
        };
      },
      // // 通过配置项的形式使用生命周期钩子函数
      // beforeCreate() {
      //   console.log("---beforeCreate--");
      // },
      // created() {
      //   console.log("---created--");
      // },
      // beforeMount() {
      //   console.log("---beforeMount--");
      // },
      // mounted() {
      //   console.log("---mounted--");
      // },
      // beforeUpdate() {
      //   console.log("---beforeUpdata--");
      // },
      // updated() {
      //   console.log("---updated--");
      // },
      // beforeUnmount() {
      //   console.log("---beforeUpdata--");
      // },
      // unmounted() {
      //   console.log("---updated--");
      // },
    };
    </script>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
  • 相关阅读:
    ThreadLocal详解
    从TRPO到PPO(理论分析与数学证明)
    HelloWorld:通过demo,构建黑盒模型
    Spring【注解实现IOC(@Component、@Repository、@Service、@Controller)】(三)-全面详解(学习总结---从入门到深化)
    HTML中华传统文化题材网页《中国民间年画》HTML+CSS+JavaScript
    使用vba调用vb.net封装的dll,出现453错误
    【论文解读】QLORA: Efficient Finetuning of Quantized LLMs
    功能具象化复盘
    Red Hat企业虚拟化(RHEV)监控工具
    17.搜索二维矩阵Ⅱ
  • 原文地址:https://blog.csdn.net/hannah2233/article/details/127833683