zoukankan      html  css  js  c++  java
  • Vue3的新特性(三):setup()、computed()和watch()

    前言

    本文主要介绍 vue3 新增 Composition API 的一些特性 setup()、computed()和 watch(),Composition API 可以把复杂组件的逻辑变得更为紧凑,使代码有更高复用性和灵活性。

    1. setup()

    setup()vue3 中新增特性,在组件 created()生命周期之前执行。
    因为 setup() 是在组件 created()之前执行的,所以在 setup()内部无法获取 this

    setup(props,context)接收两个参数:props,context

    参数一:props

    组件接收的 props 数据可以在 setup()函数内访问到。

    export default {
      props: {
        title: String
      },
      setup(props) {
        console.log(props.title)
      }
    }
    

    props 具有响应性,不能使用 ES6 解构它,这会使其失去响应性。如果需要解构,可以使用 toRefs()

    const { title } = toRefs(props)
    console.log(title.value)
    

    如果 title 是一个可选的属性,需使用 toRef(),如下:

    import { toRef } from 'vue'
    setup(props) {
    	const title = toRef(props, 'title')
    	console.log(title.value)
    }
    
    参数二:context:
    `context` 是一个上下文对象,可以通过 context 来访问 Vue 的实力 this。
    `context` 内部包括三个属性:`attrs`、`slots`、`emit`
    
    export default {
      setup(props, { attrs, slots, emit }) {
        // ...
      }
    }
    

    context 是一个常规的 js 对象,它不具有响应性可以直接对它解构。但 attrsslots 是有状态的对象,当组件本身更新时它们也会随之更新,这意味着我们应该避免解构它们。

    2. computed()

    computed()创建只读计算属性
    const count = ref(1)
    // 创建一个只读性计算属性,依赖于count值
    const plusOne = computed(() => count.value + 1)
    console.log(plusOne.value) // 2
    plusOne.value++ // error 该计算属性为只读属性,不可写
    
    computed()创建可读写计算属性
    const count = ref(1)
    // 创建一个可读写计算属性
    const plusOne = computed({
      get: () => count.value + 1,
      set: (val) => {
        count.value = val - 1
      }
    })
    plusOne.value = 1
    console.log(count.value) // 0
    

    3. watch()

    watch()监听单个数据源
    // 监听 a getter
    const state = reactive({ count: 0 })
    watch(
      () => state.count,
      (count, prevCount) => {
        /* ... */
      }
    )
    
    // 直接监听 a ref
    const count = ref(0)
    watch(count, (count, prevCount) => {
      /* ... */
    })
    
    watch()监听多个数据源

    第一个参数中,要监听的数据源以数组的形式传入。

    const firstName = ref('')
    const lastName = ref('')
    
    watch([firstName, lastName], (newValues, prevValues) => {
      console.log(newValues, prevValues)
    })
    
    firstName.value = 'John' // logs: ["John",""] ["", ""]
    lastName.value = 'Smith' // logs: ["John", "Smith"] ["John", ""]
    

    另,当监听一个响应性对象时,

    const numbers = reactive([1, 2, 3, 4])
    watch(
      () => [...numbers],
      (numbers, prevNumbers) => {
        console.log(numbers, prevNumbers)
      }
    )
    numbers.push(5) // logs: [1,2,3,4,5] [1,2,3,4]
    

    当监听一个复杂对象的属性或者数组时需要传入第三个参数{deep:true},如下:

    const state = reactive({
      id: 1,
      attributes: {
        name: ''
      }
    })
    watch(
      () => state,
      (state, prevState) => {
        console.log('not deep ', state.attributes.name, prevState.attributes.name)
      }
    )
    watch(
      () => state,
      (state, prevState) => {
        console.log('deep ', state.attributes.name, prevState.attributes.name)
      },
      { deep: true }
    )
    
    state.attributes.name = 'Alex' // Logs: "deep " "Alex" "Alex"
    

    监听一个响应式对象或者数组时总是返回当前数据变化前后的引用,为了真正的监听复杂对象或数组,需要进行一次深拷贝。
    官方推荐方案:lodash.cloneDeep

    import _ from 'lodash'
    const state = reactive({
      id: 1,
      attributes: {
        name: 'lemon'
      }
    })
    watch(
      () => _.cloneDeep(state),
      (state, prevState) => {
        console.log(state.attributes.name, prevState.attributes.name)
      }
    )
    state.attributes.name = 'Alex' // Logs: "Alex" "lemon"
    

    更多详细用法请参考Composition API——watch

    日益努力,而后风生水起。众生皆苦,你也不能认输O(∩_∩)O
  • 相关阅读:
    Python机器学习(六十九)Matplotlib 其他类型图形
    Python机器学习(六十八)Matplotlib 多个图形
    Python机器学习(六十七)Matplotlib 图形绘制
    Python机器学习(六十六)Matplotlib 基本概念
    Python机器学习(六十五)Matplotlib 入门
    Python机器学习(六十四)SciPy 统计
    Python机器学习(六十三)SciPy 信号处理
    Python机器学习(六十二)SciPy 优化
    Python机器学习(六十一)SciPy 图像处理
    Python机器学习(六十)SciPy 线性代数
  • 原文地址:https://www.cnblogs.com/yingliyu/p/14271931.html
Copyright © 2011-2022 走看看