关于javascript:Vue3-CompositionAPI

55次阅读

共计 3067 个字符,预计需要花费 8 分钟才能阅读完成。

Vue3 Composition-API

本文将简要介绍一下以后 Vue3 组合式 API 的应用形式及意义。

当然,该调侃的时候还是要调侃一下的,嘿嘿

1. 组件状态

以 2.x 的应用习惯为例,咱们最关怀的就是双向数据绑定的应用模式:

<template>
<button @click="increment">
    以后是: {{state.count}}, 双倍是: {{state.double}}
</button>
</template>

<script>
import {
    computed,
    reactive
} from 'vue'
export default {setup() {
        const state = reactive({
            count: 1,
            double: computed(() => state.count * 2)
        })

        function increment() {state.count++;}
        return {
            state,
            increment
        }
    }
}
</script>

reactive, 接管一个一般对象而后返回该对象的响应式代理,等同于 2.x 中的Vue.observable()

响应式转换是“深层的”:会影响对象外部所有嵌套属性。基于 Proxy 的实现,返回的代理对象 不等于 原始对象。在应用时应尽量应用代理对象而防止依赖原始对象。

Vue响应式零碎的精华:当在组件中从 data()返回一个对象,,外部本质上是通过调用 reactive() 使其变为响应式的。

computed, 传入一个 getter 函数,返回一个不可手动批改的 ref 对象;

computed 的另一种应用形式是,传入一个带有 get 和 set 的函数对象,创立一个能够手动批改的计算状态;

const double = computed({get: () => count.value,
    set: (val) => {count.value = val * 2}
})

watchEffect对执行过程中用到的 响应式状态 作为 依赖 进行跟踪(与 2.x 中的 watch 选项相似,然而它不须要把被依赖的数据源和副作用回调离开),并在依赖变更时从新运行该函数。当组件的 setup() 或者 生命周期钩子 被调用时,watchEffect 会被链接到该组件的生命周期,并在组件 卸载 主动进行

新的ref, 承受一个参数值并返回一个响应式且可扭转的 ref 对象。ref 对象领有一个指向外部值的繁多属性,即.value

<template>
<button @click="increment">
    数字减少
</button>
<p>{{num}}</p>
</template>
<script>
import {ref} from 'vue'
export default {setup() {const num = ref(0);
        function increment() {num.value ++;}
        return {
            increment,
            num
        }
    }
}
</script>

如果传入 ref 的是一个对象,将调用 reactive 办法进行深层响应转换。

readonly, 传入一个对象或者 ref,返回一个原始对象的只读代理。即便是深层对象,外部的任何属性也都是只读的。

const original = reactive({count: 0});
const only = readonly(original);
watchEffect(() => {    // 依赖追踪
    console.log(only.count);
})
original.count ++;    // 这里的批改会触发 only 的监测
only.count ++;        // 无奈批改并收回正告

至此简介曾经笼罩了组件的纯状态层面:响应式状态、计算状态和用户输出时的状态变更。接下来将介绍生命周期及组合式 API。

2. 生命周期钩子

import {onMounted, onUpdated, onUnmounted} from 'vue'
setup() {
        //...
        onMounted(() => {console.log('组件曾经被挂载了!')
        })
        onUpdated(() => {console.log('组件曾经更新了!')
        })
        onUnmounted(() => {console.log('组件曾经被卸载了!')
        })
        //...
}

如上例所示,生命周期钩子函数只能注册在 setup 函数中,因为它们依赖于外部的全局状态来定位以后组件实例(即正在调用 setup()的组件实例),不在以后组件下调用会抛出谬误。

组件实例上下文都是在生命周期钩子同步执行期间设置的,所以在卸载组件时同步创立的侦听器和计算状态也会被删除。

除上例所示外,还有钩子:onBeforeMount、onBeforeUpdate、onBeforeUnmount、onErrorCaptured 以及新增的钩子 onRenderTracked、onRenderTriggered。

3. 组合式 API VS 选项式 API

有组织的代码最终让代码更可读,更易于了解。在组件中看到的是“如何解决这个 X、Y 和 Z”,而不再是“这个组件有这些 data、这些 property、这些 methods”,即更加关怀“这个组件是要干什么的”。基于选项的 API 写进去的代码天然不能很好地表述出组件的性能。

以下图为例,当以 选项式 API进行开发时,通过浏览选项中的代码梳理出各个逻辑是十分艰难的,因为与逻辑相干的代码都扩散在各处。这种碎片化开发使得前期浏览和保护变得相当艰难,选项的强行拆散为逻辑的了解贬低了门槛,咱们不得不在各个代码块之间来回跳转,以找到相干代码。

相同,如果能把雷同的逻辑点代码放在一起的话,那将是再好不过的事件了。这正是 组合式 API要做的事件。这种模式让该组件的逻辑点最终成为了良好的解耦函数:每个逻辑点代码块都被组合进一个函数中,大大减少了来回跳转的状况。你还能够把这些组合函数折叠起来,更加易于浏览:

除了提取逻辑外,另一个变动就是 this 的援用。

setup()中的 this 与 2.x 中的 this 齐全不同,同时在 setup()和 2.x 中应用 this 将会造成凌乱。这里就须要再介绍一下 setup 函数了:

  • 创立组件实例时,先初始化 props,紧跟着就要调用 setup 函数,并且将在 beforeCreate 之前被调用;
  • setup 返回一个对象,对象的属性将会被合并到组件模板的上下文中;
  • setup 的第一个参数,就是 props;
  • setup 的第二个参数,提供了上下文对象,并且从 2.x 中选择性裸露了一些属性。
export default {
    props: {
        name: string,
        age: number
    },
    setup(prop,context) {watchEffect(() => {console.log(`My name is ${props.name},I'm ${props.age} years old.`)
        });
        context.attrs
        context.slots
        context.emit
    }
}

当提取逻辑点时,逻辑办法也可接管参数 props 和 context:

const checkUsername = (props, context) => {onMounted(() => {console.log(props)
    context.emit('event', 'payload')
  })
}
export default {setup (props, context) {checkUsername(props, context)
  }
}

4. 最初

心愿本文能帮忙更好地理解 Composition API 将如何扭转咱们的编码方式,在后续的开发流动中,进步代码的浏览性,进步内聚耦合度,毕竟这才是成熟的程序员要做的。

正文完
 0