【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); 
 }

在这里插入图片描述

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>
      <!-- <template v-slot="test2">
        <div>
          <h2>剧名插槽2</h2>
        </div>
      </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>

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>

在这里插入图片描述

三、计算属性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]
                }
            })
        }
    }
    

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. 情况一:监视ref所定义的多个响应式数据
    watch(
      [sum, msg],
      (newValue, oldValue) => {
        console.log("sum变了", newValue, oldValue);
      },
      { immediate: true }
    );

在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述

3-2-3 watch时value的问题

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

3-3 watchEffect

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

    在这里插入图片描述

    • 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值