• Vue3 -- computed 生命周期钩子 Provide函数 侦听数据的变化 watch script setup语法


    computed

    在前面我们讲解过计算属性computed:当我们的某些属性是依赖其他状态时,我们可以使用计算属性来处理
    在前面的Options API中,我们是使用computed选项来完成的;
    在Composition API中,我们可以在 setup 函数中使用 computed 方法来编写一个计算属性;
    如何使用computed呢?
    方式一:接收一个getter函数,并为 getter 函数返回的值,返回一个不变的 ref 对象;
    方式二:接收一个具有 get 和 set 的对象,返回一个可变的(可读写)ref 对象;

      export default {
        setup() {
          // 1.定义数据
          const names = reactive({
            firstName: 'kobe',
            lastName: 'bryant',
          });
          const fullname = computed({
            set: function (newValue) {
              const tempNames = newValue.split(' ');
              names.firstName = tempNames[0];
              names.lastName = tempNames[1];
            },
            get: function () {
              return names.firstName + ' ' + names.lastName;
            },
          });
          console.log(fullname);
          function setFullname() {
            fullname.value = 'coder why';
            console.log(names);
          }
          // 2.定义score
          const score = ref(89);
          const scoreLevel = computed(() => {
            return score.value >= 60 ? '及格' : '不及格';
          });
          return {
            names,
            fullname,
            setFullname,
            scoreLevel,
          };
        },
      };
    
    • 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

    再setup中使用ref获取元素或者组件
    只需要定义一个ref对象 绑定到元素或者组件的ref属性上即可

    <template>
      
      <h2 ref="titleRef">我是标题h2>
      <button ref="btnRef">按钮button>
    
      
      <show-info ref="showInfoRef">show-info>
      <button @click="getElements">获取元素button>
    template>
    
    <script>
      import { ref, onMounted } from 'vue'
      import ShowInfo from './ShowInfo.vue'
    
      export default {
        components: {
          ShowInfo
        },
        setup() {
          const titleRef = ref()
          const btnRef = ref()
          const showInfoRef = ref()
    
          // mounted的生命周期函数
          onMounted(() => {
            console.log(titleRef.value)
            console.log(btnRef.value)
            console.log(showInfoRef.value)
    
            showInfoRef.value.showInfoFoo()
          })
    
          function getElements() {
            console.log(titleRef.value)
          }
    
          return {
            titleRef,
            btnRef,
            showInfoRef,
            getElements
          }
        }
      }
    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

    生命周期钩子

    setup可以用来替代data methods computed等等这些选项 也可以替代生命周期钩子

    可以直接再setup中使用onX函数注册生命周期钩子

    在这里插入图片描述

        setup() {
          // 在执行setup函数的过程中, 你需要注册别的生命周期函数
          onMounted(() => {
            console.log('onmounted');
          });
          onUpdated(() => {
            console.log('onUpdated');
          });
          onUnmounted(() => {
            console.log('onUnmounted');
          });
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    Provide函数

    Composition API也可以替代之前的Provide和Inject的选项
    我们可以通过 provide来提供数据:
    可以通过 provide 方法来定义每个 Property;
    provide可以传入两个参数:
    name:提供的属性名称;
    value:提供的属性值;

    为了增加 provide 值和 inject 值之间的响应性,我们可以在 provide 值时使用 ref 和 reactive。

        setup() {
          const name = ref("why")
    
          provide("name", name)
          provide("age", 18)
    
          return {
            name
          }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    Inject函数

    在 后代组件 中可以通过 inject 来注入需要的属性和对应的值:
    可以通过 inject 来注入需要的内容;
    inject可以传入两个参数:
    要 inject 的 property 的 name;
    默认值;

        setup() {
          const name = inject("name")
          const age = inject("age")
          const height = inject("height", 1.88)
          return {
            name,
            age,
            height
          }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    侦听数据的变化

    在前面的Options API中,我们可以通过watch选项来侦听data或者props的数据变化,当数据变化时执行某一些操作。
    在Composition API中,我们可以使用watchEffect和watch来完成响应式数据的侦听;
    watchEffect:用于自动收集响应式数据的依赖;
    watch:需要手动指定侦听的数据源;

    watch的使用

    watch的API完全等同于组件watch选项的Property:
    watch需要侦听特定的数据源,并且执行其回调函数;
    默认情况下它是惰性的,只有当被侦听的源发生变化时才会执行回调;

    const name = ref('kobe')
    
    watch(name, (newValue, oldValue) => {
    	console.log(newValue, oldValue);
    })
    
    const changeName = () => {
    	name.value = 'james'
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    侦听器可以使用数组同时侦听多个源

    const name = ref('kobe')
    const age = ref(18)
    
    const changeName = () => {
    	name.value = 'james'
    }
    
    watch([name,age], (newValue, oldValue) => {
    	console.log(newValue, oldValue)
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    如果我们希望侦听一个深层的侦听,那么依然需要设置 deep 为true:
    也可以传入 immediate 立即执行;

    监听reactive数据变化后, 获取普通对象

    		 const info = reactive({
    			name = 'kobe',
    			age = 18,
    		 })
          watch(() => ({ ...info }), (newValue, oldValue) => {
            console.log(newValue, oldValue)
          }, {
            immediate: true,
            deep: true
          })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    watchEffect

    当侦听到某些响应式数据变化时,我们希望执行某些操作,这个时候可以使用 watchEffect。
    我们来看一个案例:
    首先,watchEffect传入的函数会被立即执行一次,并且在执行的过程中会收集依赖;
    其次,只有收集的依赖发生变化时,watchEffect传入的函数才会再次执行;

    const name  = ref('kobe')
    const age = ref(18)
    
    watchEffect(() => {
    	console.log('watchEffect执行', name.vlaue, age.value)
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    如果在发生某些情况下,我们希望停止侦听,这个时候我们可以获取watchEffect的返回值函数,调用该函数即可。

          const counter = ref(0)
          const name = ref("why")
          const stopWatch = watchEffect(() => {
            console.log("-------", counter.value, name.value)
            if (counter.value >= 10) {
              stopWatch()
            }
          })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    script setup语法

    < script setup> 是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖,当同时使用 SFC 与组合式 API 时则推荐该语法。
    更少的样板内容,更简洁的代码;
    能够使用纯 Typescript 声明 prop 和抛出事件;
    更好的运行时性能 ;
    更好的 IDE 类型推断性能 ;

    这个语法需要将setup attribute添加到

    <script setup>
    	console.log('hello world')
    script >
    
    • 1
    • 2
    • 3

    里面的代码会被编译成组件 setup() 函数的内容:
    这意味着与普通的

    当使用 < script setup> 的时候,任何在

    在这里插入图片描述

    响应式数据需要通过ref、reactive来创建。
    < script setup> 范围里的值也能被直接作为自定义组件的标签名使用:

    在这里插入图片描述

    defineProps() 和 defineEmits()

    为了在声明 props 和 emits 选项时获得完整的类型推断支持,我们可以使用 defineProps 和 defineEmits API,它们将自动
    地在 < script setup> 中可用:

    <template>
      <div>ShowInfo: {{ name }}-{{ age }}div>
      <button @click="showInfoBtnClick">showInfoButtonbutton>
    template>
    
    <script setup>
    
    // 定义props
    const props = defineProps({
      name: {
        type: String,
        default: "默认值"
      },
      age: {
        type: Number,
        default: 0
      }
    })
    
    // 绑定函数, 并且发出事件
    const emits = defineEmits(["infoBtnClick"])
    function showInfoBtnClick() {
      emits("infoBtnClick", "showInfo内部发生了点击")
    }
    
    // 定义foo的函数
    function foo() {
      console.log("foo function")
    }
    defineExpose({
      foo
    })
    
    script>
    
    <style scoped>
    style>
    
    • 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

    defineExpose()

    使用 < script setup> 的组件是默认关闭的:
    通过模板 ref 或者 $parent 链获取到的组件的公开实例,不会暴露任何在 < script setup> 中声明的绑定;
    通过 defineExpose 编译器宏来显式指定在

    <template>
      <div>AppContent: {{ message }}div>
      <button @click="changeMessage">修改messagebutton>
      <show-info name="kobe" 
                 :age="18"
                 @info-btn-click="infoBtnClick"
                 ref="showInfoRef">
      show-info>
      <show-info>show-info>
      <show-info>show-info>
    template>
    
    <script setup>
      // 1.所有编写在顶层中的代码, 都是默认暴露给template可以使用
      import { ref, onMounted } from 'vue'
      import ShowInfo from './ShowInfo.vue'
    
      // 2.定义响应式数据
      const message = ref("Hello World")
      console.log(message.value)
    
      // 3.定义绑定的函数
      function changeMessage() {
        message.value = "你好啊"
      }
    
      function infoBtnClick(payload) {
        console.log("监听到showInfo内部的点击:", payload)
      }
    
      // 4.获取组件实例
      const showInfoRef = ref()
      onMounted(() => {
        showInfoRef.value.foo()
      })
    
    script>
    
    <style scoped>
    style>
    
    
    
    • 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
  • 相关阅读:
    SLAM第11讲
    29.5.4 恢复数据
    STM32项目分享---MQTT智能门禁系统(含APP控制)
    【MacOS】常用快捷键
    Python究竟属不属于嵌入式语言?
    【pandas小技巧】--字符串转数值
    大数据必学Java基础(四十四):接口讲解
    第五章 Android应用核心Intent
    LeetCode 75 - 01 : 最小面积矩形
    大模型应用开发:为产品创建一个AI客服/智能助手
  • 原文地址:https://blog.csdn.net/weixin_65402230/article/details/127591755