options-api

首先咱们来看看 option-api。

default export {        data() {        return {            state:0        }    },    methods:{        myFun() {            console.log(this.state)        }    }}

下面代码的形式就是 option-api, 也是 vue2.x 中最罕用的形式。

composition-api

在vue3.x中,能够应用上面的 composition-api 形式。

default export {        setup(){    const state = ref(0)    function myFunOne() {      console.log(state.value)    }    function myFunTwo() {      console.log(state.value + 1)    }    return {      state,      myFunOne    }    }}

解决痛点

看上面的图片(起源:https://composition-api.vuejs.org/#code-organization),雷同业务的代码色彩雷同,能够看见 Options API 的雷同业务代码扩散在各处,这样前期保护起来就会十分麻烦,而Composition-Api 解决了这个痛点。

知识点梳理

对于 composition-api 所蕴含的函数有以上这么多,上面依据相干例子一个个来学习。

setup

setup性能是新的组件选项。它是组件外部应用Composition-API的入口。

可选参数

它有两个可选参数 props 和 context。
这两个参数能够解构应用。

  • props 和 vue2.x props是一样的,外面的属性是 父组件传给自组子或 vue-router 传给 页面的参数。
  • context具备与vue2.x 中 this.$attrs,this.$slots,this.$emit,this.$parent,this.$root对应的属性。

示例代码

  props: {    msg: String  },  // 须要在 emits 中申明 不然会报错 上面会有解释  emits: {    sayhi: payload => {      // validate payload by returning a boolean      return payload    }  },    // 1. 个别应用    // setup(props, context) {    //  console.log('====>', props)    //  context.emit('sayhi', 'hi')    //}    // 2. 可解构应用    setup({ msg }, { emit }) {       console.log('====>', msg)       emit('sayhi', 'hi')    }

留神点⚠️

在 setup 中应用 emit , 须要在emits 中申明它,否则会报以下谬误。

Extraneous non-emits event listeners (此处是函数名) were passed to component but could not be automatically inherited because component renders fragment or text root nodes. If the listener is intended to be a component custom event listener only, declare it using the "emits" option.

ref

<template>  <div>    <div>{{ state }}</div>    <button @click="addOne">新增1</button>  </div></template><script lang="ts">import { defineComponent, ref, onMounted } from "vue"export default defineComponent({  setup(){    // 通过 ref 初始化一个响应式的对象    const state = ref(0)        // 在生命周期 onMounted  中打印 state    onMounted(() => {      console.log(state)    })        function addOne() {        state.value += 1    }        return {        state,        addOne    }    }})</script>

咱们再来看看这段代码。
在 dom挂载结束的生命周期 onMounted  中打印 state , 发现它是一个对象。

因为 state 是通过ref 传参,而后返回的一个对象( ref 是一个函数,它承受一个参数,返回的一个响应式对象 )。咱们初始化的这个 0 作为参数包裹到这个对象中去,在将来能够检测到扭转并作出对应的相应。
addOne  函数中, 若要扭转 这个 state 响应式对象的值, 则须要通过 赋值 state.value  来实现。
在 template 模板中 ,vue 曾经帮咱们主动获取了其 value属性,所以咱们只须要传{{ state }}  即可。

reactive

reactive 和 ref 十分类似, 也是一个函数, 然而其接管一个对象。咱们革新下面学习 ref 的 例子来理解 reactive。

<template>  <div>    <div>{{ state }}</div>    <button @click="addOne">新增1</button>  </div></template><script lang="ts">import { defineComponent, onMounted, reactive, toRefs } from "vue"export default defineComponent({  setup(){    // 通过 reactive 初始化数据    const data = reactive({      state: 0,    })    // const state = ref(0)    // 在生命周期 onMounted  中打印 state    onMounted(() => {      console.log('无 toRefs', data)      console.log('通过 toRefs 解决', toRefs(data))    })        function addOne() {        data.state += 1    }        return {        // ...data, // 这样导出会使数据失去响应式        ...toRefs(data), // 通过 toRefs 使得 data 中数据取得响应式        addOne    }    }})</script>


与 ref 相比:

  • reactive 能够将 零散的 变量汇集在一个对象中。
  • reactive 中的变量 的取值和赋值不须要 取其 value 属性。


留神点:
应用 reactive 时要记得应用 toRefs 保障 reactive  对象属性放弃响应性。

watch 和 watchEffect

代码示例

// 通过 reactive 初始化数据const data = reactive({  state: 0,  num: 2,  arr: [1, 2, 3]})// 简略监听watch(data, () => {  console.log(data.state)})// 上面间接监听data.state会报错。watch 监听的指标只能是getter/effect函数、ref、reactive对象或数组。// watch(data.state, (newValue, oldValue) => {//   console.log('newValue', newValue)//   console.log('oldValue', oldValue)// })// 监听 新的值和旧值watch(() => data.state, (newValue, oldValue) => {  console.log('newValue', newValue)  console.log('oldValue', oldValue)})// watch 监听多个属性,返回的也是多个值的数组watch([() => data.num, () => data.state], (newValue, oldValue) => {  console.log('old', oldValue)  console.log('new', newValue)})// watchEffect 不须要指定监听的属性 watchEffect(()=>{  console.log('watchEffect ===>', data.state);});

watch

A watch source can only be a getter/effect function, a ref, a reactive object, or an array of these types. 

watch 监听源只能是getter/effect函数、ref、reactive对象或数组。
具体用法如上述代码所见

  1. 简略监听值的扭转。
  2. 能够获取到新值与旧值。
  3. watch 只能监听指定的属性而做出变更,vue3.x能够同时监听多个属性。

watchEffect

watchEffect 和 watch 相似,能够监听属性的变动。具体应用形式如上述代码。

不同点

  1. watchEffect 不须要指定监听的属性,它会主动的收集依赖,只有咱们回调中援用到了 响应式的属性, 那么当这些属性变更的时候,这个回调都会执行,而 watch 只能监听指定的一个或多个属性而做出变更。
  2.  watch  能够获取到新值与旧值,而 watchEffect是拿不到的 oldValue 
  3. watchEffect 在组件初始化的时候就会默认执行一次,而 watch 不须要。



computed

计算属性和vue2.x 中一样,代码示例如下。

<template>  <div>    <div>{{ state }}</div>    <div>{{ double }}</div>    <button @click="addOne">新增1</button>  </div></template><script lang="ts">import { computed, defineComponent, reactive, toRefs } from "vue"export default defineComponent({  setup(){    // 通过 reactive 初始化数据    const data = reactive({      state: 0,    })    // 通过计算属性取得的新的值    const double = computed(() => data.state * 2)        function addOne() {        data.state += 1    }        return {        ...toRefs(data), // 通过 toRefs 使得 data 中数据取得响应式        addOne,        double    }    }})</script>

参考文献
composition-api 官网文档