龙空技术网

vue3进阶-组合式API

左道前端 99

前言:

当前你们对“vuejsapi”大体比较珍视,各位老铁们都想要知道一些“vuejsapi”的相关文章。那么小编也在网上汇集了一些对于“vuejsapi””的相关文章,希望你们能喜欢,姐妹们快快来学习一下吧!

前言:

最近刚弄明白什么是组合式API,什么是选项式API,使用vue2.x这么多年,居然不知道一直在使用的居然是选项式API,以此文对这两个知识点做个总结,纪念自己的无知。

选项式API VS 组合式API1.vue2中的选项式 API (options API)

页面使用methods、watch、computed等来处理页面逻辑,vue2中的常规格式,不做过多说明。

export default{    data(){            },    //方法    methods:{            },    //观察属性    watch:{            },    //计算属性    computed:{            }}

为什么使用组合式API

选项式 API,看起来结构很清晰,当随着业务功能不断增加,代码不断迭代,methods、watch、computed中的代码会不断增加,可能一个vue中包含几个功能,这些功能在methods等内是零散的,当进行bug修复或者添加新功能时带来的工作量会很大,基于这些问题,vue3的组合式API应运而生。

2. vue3中的组合式API

引入vue官方示例,setup内的部分为组合式API

export default {  props: {    user: { type: String }  },  setup(props) {    console.log(props) // { user: '' }    return {} // 这里返回的任何内容都可以用于组件的其余部分  }  // 组件的“其余部分”}
setup参数

setup接收2个参数

1.props

父组件传入的props

示例:export default {  props: {    title: String  },  setup(props) {    console.log(props.title) //父组件传入的title值  }}

2.context

context包含3个参数,attrsslotsemit

示例:export default {  setup(props, context) {    // Attribute (非响应式对象)    console.log(context.attrs) //包含除props以外的参数,与vue2中的this.$attrs功能一致    // 插槽 (非响应式对象)    console.log(context.slots)//包含插槽,与this.$slots功能一致    // 触发事件 (方法)    console.log(context.emit)//触发事件,与this.$emit方法一致  }}

前置知识点:

vue3支持tree-shaking(死代码消除),因此vue2中挂载在vue上的全局方法现在必须单独引入才能使用。

vue 2.xthis.$nextTich(()=>{    });vue 3import { nextTick } from 'vue'nextTick(()=>{    })
setup什么时候触发

在组件创建之前执行,props被解析,然后执行setup并将props传入方法,由于执行setup时组件实例尚未创建,所以setup内无法使用this,并且无法访问methodswatchcomputed内的方法及属性。

setup使用1. 响应式变量

setup内使用ref函数实现变量的响应式,并使用return返回变量,供给模板内使用。

未使用ref

示例:<template>  <div>name:{{name}}</div>  <button @click="updateName">修改姓名</button></template><script>export default {  name: "test",  setup(){    let name = '';    let updateName = ()=>{      name = 'xiaoming';      console.log("修改名字",name)    }    return {name,updateName}  }}</script><style scoped></style>

由于变量是未响应的,所以点击修改触发方法,修改后的值并没有更新到dom中。

使用ref

示例:<template>  <div>name:{{name}}</div>  <button @click="updateName">修改姓名</button></template><script>import {ref} from 'vue'export default {  name: "test",  setup(){    let name = ref('')    console.log(name); //{value:''}    let updateName = ()=>{      name.value = 'xiaoming';      console.log("修改名字",name)    }    return {name,updateName}  }}</script><style scoped></style>

使用ref方法定义变量后,返回的是一个对象,如果需要修改变量的值需要使用变量.value修改变量的值。

2. setup内使用watch

示例:<template>  <div>name:{{name}}</div>  <button @click="updateName">修改姓名</button></template><script>import {ref,watch} from 'vue'export default {  name: "test",  setup(){    let name = ref('')    console.log(name);    let updateName = ()=>{      name.value = 'xiaoming';      console.log("修改名字",name)    }    //计算属性观察name变化    watch(name,(newVal,oldVal)=>{      console.log("newVal",newVal) //xiaoming      console.log("oldVal",oldVal) // ''    })    return {name,updateName}  }}</script><style scoped></style>
3. setup内使用computed
示例:<template>  <div>name:{{name}}</div>  <div>{{nowName}}</div>  <button @click="updateName">修改姓名</button></template><script>import {ref,computed} from 'vue'export default {  name: "test",  setup(){    let name = ref('')    console.log(name);    let updateName = ()=>{      name.value = 'xiaoming';      console.log("修改名字",name)    }    //使用计算属性返回    let nowName = computed(()=>{      return `现在的名字是:${name.value}`    })    return {name,updateName,nowName}  }}</script><style scoped></style>
4. setup内触发生命周期函数

选项式API与对应的组合式API生命周期

选项式 API Hook inside setup beforeCreate Not needed* created Not needed* beforeMount onBeforeMount mounted onMounted beforeUpdate onBeforeUpdate updated onUpdated beforeUnmount onBeforeUnmount unmounted onUnmounted errorCaptured onErrorCaptured renderTracked onRenderTracked renderTriggered onRenderTriggered

选项式API的生命周期钩子函数与组合式API的触发时机一致,书写方法有区别,下面列了几个常用的生命周期钩子函数的定义方式。

示例:<template>  <div>name:{{name}}</div>  <div>{{nowName}}</div>  <button @click="updateName">修改姓名</button></template><script><!--引入所需内置函数-->import {onBeforeMount,onMounted,onBeforeUpdate,onUpdated,ref} from 'vue'export default {  name: "test",  setup(){    //挂载前    onBeforeMount(()=>{      console.log("onBeforeMount")    })    //挂载后    onMounted(()=>{      console.log("onMounted")    })    //修改前    onBeforeUpdate(()=>{      console.log("onBeforeUpdate")    })    //修改后    onUpdated(()=>{      console.log("onUpdated")    })    let name = ref('')    console.log(name);    let updateName = ()=>{      name.value = 'xiaoming';      console.log("修改名字",name)    }    return {name,updateName}  }}</script><style scoped></style>
5. 依赖注入( Provide / Inject)

父组件将参数注入provide,子、孙组件使用inject,这里使用官方示例

父组件:<template>  <MyMarker /></template><script>import { provide } from 'vue'import MyMarker from './MyMarker.vueexport default {  components: {    MyMarker  },  setup() {    //向子组件及孙子组件注入两个参数,分别是地址及坐标,一个变量,一个对象    provide('location', 'North Pole')    provide('geolocation', {      longitude: 90,      latitude: 135    })  }}</script>子组件:<script>import { inject } from 'vue'export default {  setup() {    //引入父组件注入的变量    const userLocation = inject('location', 'The Universe')    const userGeolocation = inject('geolocation')        return {      userLocation,      userGeolocation    }  }}</script>
6. 依赖注入响应式

上面注入的参数如果发生变动,子组件内引入的参数并不会变化,接下来将参数动态化。

子组件<template>  <MyMarker /></template><script>import { provide, reactive, ref } from 'vue'import MyMarker from './MyMarker.vueexport default {  components: {    MyMarker  },  setup() {    <!--ref上面已经介绍过-->    const location = ref('North Pole')    <!--reactive用法与ref相同,不过ref针对的是基本数据类型,而reactive针对的是引用数据类型-->    const geolocation = reactive({      longitude: 90,      latitude: 135    })    provide('location', location)    provide('geolocation', geolocation)  }}</script>

如果要确保注入的参数不被子组件修改,可以在注入时使用readonly避免子组件修改参数

父组件<template>  <MyMarker /></template><script>import { provide, reactive, readonly, ref } from 'vue'import MyMarker from './MyMarker.vueexport default {  components: {    MyMarker  },  setup() {    const location = ref('North Pole')    const geolocation = reactive({      longitude: 90,      latitude: 135    })    <!--readonly使子组件无法修改父组件注入的参数-->    provide('location', readonly(location))    provide('geolocation', readonly(geolocation))  }}</script>
结语:

至此组合式API基本介绍完毕,在开发过程中还是需要自己选择是使用选项式API还是使用组合式API来开发,需要结合自己的使用场景做出选择。

标签: #vuejsapi