Composition API

setup

执行时机

  1. - `setup``beforeCreate`钩子前执行**一次**,此时并**没有组件**也就没有指向组件本身的`this`

返回值

  1. - setup是一个函数,如果这个函数返回了对象,则对象中的属性或方法,**可以在模版中直接使用**
  2. - setup返回的对象中的**方法**和**属性**,会和组件options中定义的datamethods中返回的对象和方法**合并**,

注意:虽然setup返回的对象可以和options中的合并,但是,setup中并不能访问当前组件实例的this,也就是说,setup函数中,不能访问
options中的datamethods。所以请不要混合使用setup和methods

  1. - setup不能是一个async函数,因为如果是async函数,其返回的是promise对象,而不是一个普通对象。

参数

  1. - 两个参数 `props``context`,[说明](https://v3.cn.vuejs.org/guide/composition-api-setup.html#props)

props

  1. - props是响应式的,包括了所有组件上定义的props中包含的属性
  2. - 由于props是响应式的,所以不能直接使用解构赋值,因为会消除他的响应性
  3. - 如果想使用解构赋值,使用`toRefs`为源目标对象[创建响应式链接](https://v3.cn.vuejs.org/api/refs-api.html#torefs),然后可以使用解构赋值。
  1. //child.vue
  2. import { toRefs } from 'vue'
  3. ...
  4. setup() {
  5. const { age } = toRefs(props.person)
  6. }

注意:props中存在可选props,这时候需要单独为这个props创建toRef的单独的响应式链接。

  1. //childe.vue
  2. import { toRef } 'vue'
  3. ...
  4. setup() {
  5. const career = toRef(props.person, 'career')
  6. }

context

context是一个普通的对象所以可以使用解构赋值,这里要注意的是,attrsslots是有状态的对象,这里不应该使用解构,而通过.点记法引用属性,attrs.xxxslots.xxx

attrsslots 是有状态的对象,它们总是会随组件本身的更新而更新。这意味着你应该避免对它们进行解构,并始终以 attrs.xslots.x 的方式引用 property。请注意,与 props 不同,attrsslots响应式的。如果你打算根据 attrsslots 更改应用副作用,那么应该在 onUpdated 生命周期钩子中执行此操作。

attrs
任何不在props对象上定义的属性,都会放在attrs对象上,注意这里和vue2.x有明显的区别,vue2.x中attrs中不包含事件回调,也就是on,vue3.0中,如果子组件没有显示的定义emits数组或对象,则会抛出警告。正确的做法是,添加emits属性在实例上,并使用
slots
emit
相当于vue2.x中的this.$emit,不同的是,在setup中使用,需显式的定义emits,这样可以将emits分发的事件,从attrs上移除。
新增的emitsOption,这里我们建议定义所有的分发事件,并且对分发事件进行适当的校验

Tips

Vue3支持多个标签Vue2不支持

moutipleTemplate.png


Vue3通过createApp函数初始化,Vue2通过对象new Vue({template:'',render(){}})初始化

createApp.png


使用ts时.vue文件报错解决,根目录添加shims-vue.ts

shims-vue.png


router初始化

route.png


配置vite alias路径别名,在vite.config.js中加入(vite2+)

alias.png


script文件中当lang=ts时引入没有script的组件会报错如下

截屏2021-02-19 上午10.45.22.png
解决方式:为给没有script的组件加上sciprt结构,如果继续报错,将引入组件的代码删掉再粘贴,也可修复


ref相当于一个响应式的盒子,盒子里的value属性才是我们需要的值


当 ref 作为渲染上下文 (从 setup() 中返回的对象) 上的 property 返回并可以在模板中被访问时,它将自动展开为内部值。不需要在模板中追加 .value ref用法


在setup函数中使用router

route.png

  • 单独建立router文件
  • 在需要使用的sfc中引入router
  • 在setup函数中使用(注意在setup中使用的是ref中的value属性),ref相当于一个礼品盒,你需要的是盒子中的礼物value

截屏2021-02-20 下午2.24.57.png


setup中第二个参数为context,可以解构出 attrs,slots,emit,


父组件可以通过$event直接拿到事件携带的参数

截屏2021-02-20 下午5.08.09.png


自定义组件使用v-modal的方式,注意3.x和2.x有明显的不同,已经习惯2.x开发的同学需要格外注意

  • 2.X用法 相当于绑定valueinput事件

截屏2021-02-20 下午5.31.44.png

  • 3.x用法 给v-modal绑定propertyName同时监听emit(update:propertyName,someargs)事件,这里要格外注意,触发事件用的是属性名update:propertyName


截屏2021-02-20 下午5.33.20.png


v-bind.sync的使用方式,参见第12条,v-modal某种意义上可以替代.sync方案,其形式几乎相同

  • 父组件

截屏2021-02-20 下午5.12.28.png

  • 子组件

截屏2021-02-20 下午5.12.58.png

v-on监听事件名称会全部转为小写,所以任何时候,事件推荐使用短横线连接的方式

截屏2021-02-20 下午5.27.21.png


2.x版本中的$listener在3.X中移除,事件监听是$attrs中的一部分

截屏2021-02-20 下午8.03.09.png

由于上一条,所有的非声明的组件的属性和事件,将会默认绑定到子组件的根元素上,则可能造成事件和样式不是我们想要的,此时,使用inheritAttrs:false来更改默认的行为非Props的Attribute。这种情况经常发生在有外部包裹结构的组件上。此时

  • 可以一次性绑定所有的$attrs到指定的元素上

截屏2021-02-20 下午8.13.39.png

  • 也可以分为置之,将事件和属性分别指定到我们想要的元素上,这里注意在使用attrsslots时候,不要使用解构,使用attrs.xxx slots.xxx
    • 父组

image.png

  • 子组件
    image.png
    上面这个例子,将由子组件的button来触发事件,而不是外层的div元素。这里注意,如果是多个标签的组件,会报警告

继续上一条,总结一波props vs attrs

  • props不声明就没有,不声明的情况下快速查看console.log({...props})为空
    attrs除了props里声明的全都有
  • props不包含事件
    attrs包含事件
  • props可以声明类型
    attrs除了string其他不认识