Vue3中怎么使用CompositionAPI解决问题(CompositionAPI,vue3,编程语言)

时间:2024-04-28 03:23:55 作者 : 石家庄SEO 分类 : 编程语言
  • TAG :

接下来,请跟着小编一起来学习吧!

一、为什么选择CompositionAPI

Vue2的局限性

  • 组件逻辑膨胀导致的可读性变差

  • 无法跨组件重用代码

  • Vue2对TS的支持有限

在传统的OptionsAPI中我们需要将逻辑分散到以下六个部分。

OptionsAPI

  • components

  • props

  • data

  • computed

  • methods

  • lifecycle methods

如何使用CompositionAPI解决问题

最佳的解决方法是将逻辑聚合就可以很好的代码可读性。

这就是我们的CompositionAPI语法能够实现的功能。CompositionAPI是一个完全可选的语法与原来的OptionAPI并没有冲突之处。他可以让我们将相同功能的代码组织在一起,而不需要散落到optionsAPI的各个角落

代码重用方法PK

Vue2中的跨组件重用代码,我们大概会有四个选择

1、Mixin - 混入

Vue3中怎么使用CompositionAPI解决问题

  • 代码混入其实就是设计模式中的混合模式,缺点也非常明显。

  • 可以理解为多重继承,简单的说就是一个人如何有两个父亲

缺点

  • 无法避免属性名冲突

  • 继承关系不清晰

2、Mixin Factory - 混入工厂

返回一个

Vue3中怎么使用CompositionAPI解决问题

✅代码重用方便

✅继承关系清洗

3、ScopeSlots - 作用域插槽

❌可读性不高

❌配置复杂 - 需要再模板中进行配置

❌性能低 - 每个插槽相当于一个实例

4、CompositionApi - 复合API

Vue3中怎么使用CompositionAPI解决问题

✅代码量少

✅没有引入新的语法,只是单纯函数

✅异常灵活

✅工具语法提示友好 - 因为是单纯函数所以 很容易实现语法提示、自动补偿

二、setup & ref

使用CompositionAPI理由

✅更好的Typescript支持

✅在复杂功能组件中可以实现根据特性组织代码 - 代码内聚性, 比如:
排序和搜索逻辑内聚

✅组件间代码复用

setup是什么

  • 在以下方法前执行:

    • Components

    • Props

    • Data

    • Methods

    • Computed Properties

    • Lifecycle methods

  • 可以不在使用难于理解的this

  • 有两个可选参数

    • props - 属性 (响应式对象 且 可以监听(watch))

import{watch}from"vue"
exportdefalut{
props:{
name:String
},
setup(props){
watch(()=>{
console.log(props.name)
})
}
}
  • context 上下文对象 - 用于代替以前的this方法可以访问的属性

setup(props,context){
const{attrs,slots,parent,root,emit}=context
}

ref是什么

对基本数据类型数据进行装箱操作使得成为一个响应式对象,可以跟踪数据变化。

总结

Vue3中怎么使用CompositionAPI解决问题

可维护性明显提高

  • 可以控制哪些变量暴露

  • 可以跟中哪些属性被定义 (属性继承与引用透明)

三、Methods

基础用法

Vue3中怎么使用CompositionAPI解决问题

自动拆装箱总结

Vue3中怎么使用CompositionAPI解决问题

  • JS :需要通过.value访问包装对象

  • 模板: 自动拆箱

四、 Computed - 计算属性

这个地方实在没什么好讲的,和Vue2没变化

<template>
<div>
<div>Capacity:{{capacity}}</div>
<p>SpasesLeft:{{sapcesLeft}}outof{{capacity}}</p>
<button@click="increaseCapacity()">IncreaseCapacity</button>
</div>
</template>

<script>

import{ref,computed,watch}from"vue";
exportdefault{
setup(props,context){
constcapacity=ref(3);
constattending=ref(["Tim","Bob","Joe"]);
functionincreaseCapacity(){
capacity.value++;
}
constsapcesLeft=computed(()=>{
returncapacity.value-attending.value.length;
});
return{capacity,increaseCapacity,attending,sapcesLeft};
},
};
</script>

五、Reactive - 响应式语法

之前reactive 的 Ref 去声明所有的响应式属性

import{ref,computed}from'vue'
exportdefault{
setup(){
constcapacity=ref(4);
constattending=ref(["Tim","Bob","Joe"]);
constspacesLeft=computed(()=>{
returncapacity.value-attending.value.length
})
functionincreaseCapacity(){capacity.value++;}
return{capacity,increaseCapacity,attending,spacesLeft}
}
}

但是有另一个等效的方法用它去代替 reactive 的Ref

import{reactive,computed}from'vue'
exportdefault{
setup(){
constevent=reactive({
capacity:4,
attending:["Tim","Bob","Joe"],
spacesLeft:computed(()=>{
returnevent.capacity-event.attending.length;
})
})
}
}

过去我们用vue2.0的data来声明响应式对象,但是现在在这里每一个属性都是响应式的包括computed 计算属性

这2种方式相比于第一种没有使用.

接下来 我们再声明method 这2种语法都ok,取决于你选择哪一种

setup(){
constevent=reactive(){
capacity:4,
attending:["Tim","Bob","Joe"],
spacesLeft:computed(()=>{
returnevent.capacity-event.attending.length;
})
functionincreaseCapacity(){event.capacity++}
//return整个对象
return{event,increaseCapacity}
}
}
<p>SpacesLeft:{{event.spacesLeft}}outof{{event.capacity}}</p>
<h3>Attending</h3>
<ul>>
<liv-for="(name,index)inevent.attending":key="index">
{{name}}
</li>
</ul>
<button@click="increaseCapacity()">IncreaseCapacity</button>

在这里我们使用对象都是.属性的方式,但是如果 这个结构变化了,event分开了编程了一个个片段,这个时候就不能用.属性的方式了

//在这里可以使用toRefs
import{reactive,computed,toRefs}from'vue'
exportdefault{
setup(){
constevent=reactive({
capacity:4,
attending:["Tim","Bob","Joe"],
spacesLeft:computed(()=>{
returnevent.capacity-event.attending.length;

})
})
functionincreaseCapacity(){event.capacity++}
return{...toRefs(event),increaseCapacity}
}
}

如果没有 increaseCapacity() 这个方法 直接可以简化为

returntoRefs(event)

完整代码

<div>
<p>SpaceLeft:{{event.spacesLeft}}outof{{event.capacity}}</p>
<h3>Attending</h3>
<ul>
<liv-for="(name,index)"inevent.attending:key="index">{{name}}
</li>

</ul>
<button@click="increaseCapacity">IncreaseCapacity</button>
</div>
</template>

<script>
//第一种
import{ref,computed}from'vue'
exportdefault{
setup(){
constcapacity=ref(4)
constattending=ref(["Tim","Bob","Joe"])
constspaceLeft=computed(()=>{
returncapacity.value-attending.value.length;
});
functionincreaseCapacity(){capacity.value++;}
return{capacity,increaseCapacity,attending,spaceLeft}

}
}

//返回一个响应式函数第二种
import{reactive,computed}from'vue'
exportdefault{
setup(){
constevent=reactive({
capacity:4,
attending:["Tim","Bob","Joe"],
spaceLeft:computed(()=>{
returnevent.capacity-event.attending.length;
})
})
//我们不再使用.value
functionincreaseCapacity(){event.capacity++;}
//把这个event放入到template中
return{event,increaseCapacity}
}
}

</script>

六、 Modularizing

使用CompositionAPI的两个理由

1、可以按照功能组织代码

Vue3中怎么使用CompositionAPI解决问题

2、组件间功能代码复用

Vue3中怎么使用CompositionAPI解决问题

Vue3中怎么使用CompositionAPI解决问题

七、 LifecycleHooks - 生命周期钩子

Vue2Vue3beforeCreate❌setup(替代)created❌setup(替代)beforeMountonBeforeMountmountedonMountedbeforeUpdateonBeforeUpdateupdatedonUpdatedbeforeDestroyonBeforeUnmountdestroyedonUnmountederrorCapturedonErrorCaptured-?onRenderTracked-?onRenderTriggered

setup中调用生命周期钩子

import{onBeforeMount,onMounted}from"vue";
exportdefault{
setup(){
onBeforeMount(()=>{
console.log('BeforeMount!')
})
onMounted(()=>{
console.log('BeforeMount!')
})
},
};

八、Watch - 监听器

//所有依赖响应式对象监听
watchEffect(()=>{
results.value=getEventCount(searchInput.value);
});

//特定响应式对象监听
watch(
searchInput,
()=>{
console.log("watchsearchInput:");
}
);

//特定响应式对象监听可以获取新旧值
watch(
searchInput,
(newVal,oldVal)=>{
console.log("watchsearchInput:",newVal,oldVal);
},
);

//多响应式对象监听
watch(
[firstName,lastName],
([newFirst,newLast],[oldFirst,oldlast])=>{
//.....
},

);

//非懒加载方式监听可以设置初始值
watch(
searchInput,
(newVal,oldVal)=>{
console.log("watchsearchInput:",newVal,oldVal);
},
{
immediate:true,
}
);

九、Sharing State - 共享状态

Vue3中怎么使用CompositionAPI解决问题

编写一个公共函数usePromise函数需求如下:

  • results : 返回Promise执行结果

  • loading: 返回Promise运行状态

    • PENDING :true

    • REJECTED : false

    • RESOLVED: false

  • error : 返回执行错误

Vue3中怎么使用CompositionAPI解决问题

import{ref}from"vue";

exportdefaultfunctionusePromise(fn){
constresults=ref(null);
//isPENDING
constloading=ref(false);
consterror=ref(null);

constcreatePromise=async(...args)=>{
loading.value=true;
error.value=null;
results.value=null;
try{
results.value=awaitfn(...args);
}catch(err){
error.value=err;
}finally{
loading.value=false;
}
};
return{results,loading,error,createPromise};
}

应用

import{ref,watch}from"vue";
importusePromisefrom"./usePromise";
exportdefault{
setup(){
constsearchInput=ref("");
functiongetEventCount(){
returnnewPromise((resolve)=>{
setTimeout(()=>resolve(3),1000);
});
}

constgetEvents=usePromise((searchInput)=>getEventCount());

watch(searchInput,()=>{
if(searchInput.value!==""){
getEvents.createPromise(searchInput);
}else{
getEvents.results.value=null;
}
});

return{searchInput,...getEvents};
},
};

十、Suspense - 悬念

复杂的Loading实现

我们考虑一下当你加载一个远程数据时,如何显示loading状态

通常我们可以在模板中使用v-if

Vue3中怎么使用CompositionAPI解决问题

但是在一个组件树中,其中几个子组件需要远程加载数据,当加载完成前父组件希望处于Loading状态时我们就必须借助全局状态管理来管理这个Loading状态

Vue3中怎么使用CompositionAPI解决问题

Suspense基础语法

这个问题在Vue3中有一个全新的解决方法。

这就是Suspense Component,悬念组件。

Vue3中怎么使用CompositionAPI解决问题

<template>
<div>
<divv-if="error">Uhoh..{{error}}</div>
<Suspense>
<template#default>
<div>
<Event/>
<AsyncEvent/>
</div>
</template>
<template#fallback>Loading....</template>
</Suspense>
</div>
</template>

<script>
import{ref,onErrorCaptured,defineAsyncComponent}from"vue";

importEventfrom"./Event.vue";

constAsyncEvent=defineAsyncComponent(()=>import("./Event.vue"));
exportdefault{
components:{
Event,
AsyncEvent,
},

setup(){
consterror=ref(null);
onErrorCaptured((e)=>{
error.value=e;
//阻止错误继续冒泡
returntrue;
});
return{error};
},
};
</script>

骨架屏实现

Vue3中怎么使用CompositionAPI解决问题

Vue3中怎么使用CompositionAPI解决问题

十一、Teleport - 传送门

功能

类似React中的Portal, 可以将特定的html模板传送到Dom的任何位置

Vue3中怎么使用CompositionAPI解决问题

基础语法

通过选择器QuerySelector配置

Vue3中怎么使用CompositionAPI解决问题

示例代码

<template>
<div>
<teleportto="#end-of-body":disabled="!showText">
<!--【Teleport:Thisshouldbeattheend】-->
<div>
<videosrc="../assets/flower.webm"mutedcontrols="controls"autoplay="autoplay"loop="loop">

</video>
</div>
</teleport>
<div>【Teleport:Thisshouldbeatthetop】</div>
<button@click="showText=!showText">ToggleshowText</button>
</div>
</template>
<script>
import{ref}from"vue";
exportdefault{
setup(){
constshowText=ref(false);
setInterval(()=>{
showText.value=!showText.value;
},1000);
return{showText};
},
};
</script>

若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!

本文:Vue3中怎么使用CompositionAPI解决问题的详细内容,希望对您有所帮助,信息来源于网络。
上一篇:daisyUI怎么解决TailwindCSS堆砌class问题下一篇:

91 人围观 / 0 条评论 ↓快速评论↓

(必须)

(必须,保密)

阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18