前言:
当前你们对“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个参数,attrs、slots,emit
示例: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,并且无法访问methods、watch、computed内的方法及属性。
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