还是来看ComponstionAPI中都有什么
ref 和 reactivecomputed 和watch新的生命周期函数- 自定义函数–hooks函数
- Teleport - 瞬移组件的位置
- Suspense - 异步加载组件
上次简单梳理过前三个,现在接着梳理
3.自定义函数–hooks函数
vue2.0的mixins的缺点上次已经讲过了,这次主要梳理一下3.0是怎么解决这个问题的
- 1.代码提取
Composition API的第一个明显优势是很容易提取逻辑。举例:在useCounter.js文件中书写我们需要开发的内容
//useCounter.js
import { ref, computed } from "vue";
export default function () {
const count = ref(0);
const double = computed(() => count * 2)
function increment() {
count.value++;
}
return {
count,
double,
increment
}
}
- 2.代码重用
要在组件中使用该功能,我们只需将模块导入到组件文件中,然后调用它(注意,导入是一个函数)。这将返回我们定义的变量,随后我们可以从setup函数中返回这些变量
// MyComponent.js
import useCounter from "./useCounter.js";
export default {
setup() {
const { count, double, increment } = useCounter();
return {
count,
double,
increment
}
}
}
首先我们来看命名冲突的解决,命名碰撞的解决方法将与其他任何JavaScript变量的命名方式一样,因为是引入的js文件暴漏的属性及方法,所以我们如同js原本引入逻辑一致来自己解决命名冲突
export default {
setup () {
const { someVar1, someMethod1 } = useCompFunction1();
const { someVar2, someMethod2 } = useCompFunction2();
return {
someVar1,
someMethod1,
someVar2,
someMethod2
}
}
}
隐式依赖关系也解决了,我们之前也看到了一个组合函数可能会使用消耗组件上定义的数据属性,这可能会使代码变得很脆弱,而且很难推理。 而组合函数也可以调用消耗组件中定义的本地变量。但不同的是,这个变量现在必须显式传递给组成函数。
import useCompFunction from "./useCompFunction";
export default {
setup () {
// 自己定义的变量
const myLocalVal = ref(0);
// 必须以显式明白的方式传递给接收到的函数
const { ... } = useCompFunction(myLocalVal);
}
}
在大部分人看起来,好像没有什么区别,反而变得更加的原生,其实是这样的,更原始也就意味着我们更好去解决问题,当然了vue3.0还是支持原本我们常见的mixins混入的,而且还支持自定义的合并逻辑
- 常见的mixins混入的使用,自定也合并策略,合并策略方法中接受两个参数,第一个参数为 mixin 自定义属性值,第二个参数为 app 组件自定义属性值,用户可以通过方法判断来返回哪个值,来定义自定义属性的优先级。
缺陷依旧存在
app.config.optionMergeStrategies.message = (mixinVal, appVal) => {
return mixinVal || appVal;
};
我看到的一个比较合理的分析两者的文字是这样的:
mixin模式表面上看起来很安全。然而,通过合并对象来共享代码,由于它给代码增加了脆弱性,并且掩盖了推理功能的能力,因此成为一种反模式。 Composition API 最聪明的地方在于,它允许 Vue 依靠原生 JavaScript 内置的保障措施来共享代码,比如将变量传递给函数,以及模块系统。 这是否意味着Composition API在各方面都比Vue的经典API优越?不是的,在大多数情况下,你可以坚持使用经典的API。但是,如果你打算重用代码,Composition API无疑是优越的。
4.Teleport
Teleport能够直接帮助我们将组件渲染后页面中的任意地方,这真的是一个极其神奇的功能,解决掉一部分我们头疼的东西
- 解决掉的问题所在
我是有遇到过这样的问题的,就是我的组件所需要的逻辑及数据,和我想要展示的地方,很不对劲,我看好多的帖子都是以模态框举例,大致确实是这样的,如果我的整个逻辑都在一个文件内,那其实没什么,都可以拿到,但是如果我展示的东西,是需要在极深层次的组件内拿到,但是我想要相对来说展示在外部,那我展示的东西,对于父级,祖父级各个上层的定位,该如何定位,当然,可以直接写在外部,然后值传出去,但是这个太low了,代码也很不友好
<teleport to="body" class="modal" v-if="show">
<div class="modal-mask" @click="close"></div>
</teleport>
看代码,我们这几行代码,其实就实现了我们的组件现在是传送到body的元素下,那我们的定位以及布局都是相对于body来说的,但是我们使用的逻辑以及数据,还是在当前的文件中就可以拿到的.可能只是看感受不是那么的深,但是实际遇到问题,就一定逃不过真香定律了
5.Suspense
“Suspense是Vue3推出的一个内置的特殊组件,有两个template slot,刚开始会渲染一个fallback内容,直到达到某个条件以后才会渲染正式的内容”
- 描述十分离奇,解决异步渲染的问题,有的人肯定会疑惑,我ifelse来控制组件的是否渲染,来控制loading的展示不是挺好的,但是要知道,ifelse我们需要定义变量,需要自己手动的去处理逻辑,现在有了Suspense 我们就不需要关注这个了,我们只需要知道,异步组件,返回结果就可以
//父组件
<suspense>
<template #default>
<new-model></new-model>
</template>
<template #fallback>
<err-model></err-model>
</template>
</suspense>
//异步子组件
export default {
name: "NewModel",
setup(){
return new Promise((resolve)=>{
setTimeout(()=>{
return resolve({result:"OK"})
},3000)
})
}
}
需要注意的是:使用Suspense,在setup( )中需要返回一个promise,而不是直接返回一个对象