Vue中的9种组件的实现方式你用过几种?
本篇文章结合了Vue2.0与Vue3.0两个角度去叙述的,对于刚学习vue的小白来说前两种用的还是比较多,如果你要想进阶或者自己有需求封装高可用的组件的话那就有必要去熟悉后面的几种组件写法,当然我这解释每种组件的写法,怎样去封装还得要靠自己去实现,好了废话不多说,看看今天的菜系,首先先给大家来两道简单的小菜!
一. 全局组件
首先创建一个组件btnComp/button.vue,内容随便来就行
- 然后创建btnComp/button.js文件
export const btnInstall = funciton(component){
const comp = component
comp.install = (app) => {
app.component(comp.name || comp.displayName, compone nt);
}
return component
};
- main.js下引入
import { btnInstall } from '@/components/btnComp'
import { createApp } from 'vue';
import App from './App.vue';
const app = createApp(App);
// 了解vue2.0源码的朋友应该都了解当use的时候,内部会触发install,恰好触发button.js下的install
app.use(btnInstall);
二.局部组件
components:{ //局部组件
'my-world':{
template:'<h3>aaa</h3>'
}
}
以上两种组件不过多叙述,相信大家都很熟悉,那小菜都上完了,那就换个口味
三.缓存组件
vue3.0举例
- keep-alive实现缓存组件,缓存非活动的组件,可以保留组件的状态,避免重新渲染,包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们
- keep-alive属性
- include:只有名称匹配的组件会被缓存,这里的名称不是路由里的name而是组件、页面中的name
- exclude:任何名称匹配的组件都不会被缓存
- max:最多可以缓存多少组件实例
- Vue3 中的缓存写法
代码如下:
<template>
<router-view v-slot="{ Component }">
<keep-alive>
<component :is="Component" />
</keep-alive>
</router-view>
</template>
四.函数式组件
vue3.0举例
函数式组件的特性:
- 无状态
- 无实例化
- 只接受props
- 渲染性能高,适合只依赖于外部数据传递
- 函数式组件没有this
- 其实无脑的来说就是给组件打上 "functional" 标记,即得函数式组件
<template functional>
</template>
- 具体他怎么用,一起来看一下
vue单文件写法,创建FunctionComp.vue
<template functional>
<div>
<button >{{ props.title }}</button>
</div>
</template>
<script>
export default {
props: {
title: [String],
},
edit(val) {
return 'tcl' + val
}
}
</script>
在父组件使用,因为手头实在没有vue2的dome,所以这里我用的是vue3.0的写法
<template>
<div id="app">
<FunctionComp title="asd"/>
</div>
</template>
// 这里使用vue3的语法糖setup这样我们引入的组件以及方法和变量就不用return,非常的方便
<script setup lang="ts">
import { defineAsyncComponent } from "vue";
const FunctionComp = defineAsyncComponent(() => import('./FunctionComp.vue'))
</script>
五.构造器组件
由于Vue3.0没有办法使用extends所以这里只好使用vue2.0的列子,此案例是本人参考的Element-ui的Massage源码,vue3.0举例
1.首先创建组件文件
创建的Massage.vue
<template>
<p class="Message">{{value}}</p>
</template>
<script>
export default {
data() {
return { value: "我是一个弹框" };
}
};
再创建Massage.js 核心文件
import Vue from 'vue';import Message from './Message.vue';
// 这里只实现了一个弹窗展示与取消,其实这里应该存放一个队列,就可以达到多个Message出现的效果了
const MessageConstructor = Vue.extend(Message);
const removeDom = (target) => {
target.parentNode.removeChild(target);
};
//清除Message
MessageConstructor.prototype.close = function() {
removeDom(this.$el);
};
const MessageDiv = (options) => {
const instance = new MessageConstructor({
el: document.createElement('div'),
data: options,
});
// instaance.$el 就是我们要创建的实例
document.body.appendChild(instaance.$el);
Vue.nextTick(()={
// 组件被创建3s后被清除
instance.timer = setTimeout(()=>{
instance.close();
},3000)
})
export default MessageDiv
- 在main.js种注册的
import Message from '@/components/Message.js'
Vue.prototype.$message = Message;
- 在组件中使用
<template>
<div id="app">
<button @click="showmsg">弹窗</button>
</div>
</template>
<script>
export default {
name: "app",
methods: {
showmsg() {
this.$message({value:'我是构造组件'});
}
}
};
</script>
六.高阶组件(HOC)
高阶组件这个概念在 React 中一度非常流行,因为现在是vue专栏,所以就不说React了,比较适合:操作属性,代码重用,操作数据和数据抽象
- 讲高阶组件之前,先讲一下高阶函数,
- 什么是高阶函数
- 接受一个函数作为参数
- 函数被当做返回值返回
- 什么是高阶函数
- 其实高阶组件与高阶函数的形成条件是类似的,高阶组件也可以理解为高阶函数,高阶组件只是接受一个组件作为参数,返回一个包装后的组件
- 首先创建HocComponent.js文件
vue3.0举例
在vue3.0种h函数是手动引入的,vue2.0中h函数是作为render函数的参数,所以大家要分清
import { h } from 'vue'
//在这里可以对参数进行一些处理包装啥的
export const HoComponent = function(component){
const comp = component;
return {
mounted() {
console.log(' 高阶组件传参',this.title)
},
props: comp.props,
render() {
return h(comp,{title:this.title})
},
}
}
- 创建组件HocComponent.vue请注意尾缀
<template>
<div @click="onClick">{{ title }}</div>
</template>
<script>
import { defineComponent } from 'vue';
export default defineComponent({
name:'HocCompt',
props:{
title:String
},
emits:{
handleClick:null
},
setup(_,{emit}){
const onClick = ()=>{
emit('handleClick','Hoc1')
}
return {
onClick
}
}
})
</script>
- 最后使用
<template>
<div>
<Function1 @handleClick="handleClicks" title="小熊泰迪"/>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import HocCompt from './comp.vue'
import { HoComponent } from './functionComp'
const Function1 = HoComponent(HocCompt)
export default defineComponent({
name:'functionComp',
components:{
Function1
},
setup(){
const handleClicks = (e)=>{
console.log(e)
}
return {
handleClicks
}
}
})
七.递归组件
递归组件可能不太熟悉的人不理解,其实就类似于递归函数,那给大家说一个简单的案例,树形目录大家应该都不陌生,树形目录使用递归组件实现非常适合不过了,给大家简单的展示以下递归组件的实现方法:
//数据
const list=[{
title: '菜单1',
children: [{
title: '菜单1-1',
children: [{
title: '菜单1-1-1'
}]
}, {
title: '菜单1-2'
}]
}, {
title: '菜单2'
}, {
title: '菜单3'
}, {
title: '菜单4'
}]
//子组件定义
<ul>
<li v-for="(item,index) in list" :key="index">
<a href="#">{{ item.title }}</a>
// 注意这里是自己调用自己,类似于递归函数
<Vlist :list="item.children"></Vlist>
</li>
</ul>
//父组件使用
<div>
<Vlist :list="list"></Vlist>
</div>
八. 动态组件
官方原话:在一个多标签的界面中使用 is attribute 来切换不同的组件,对于动态组件这里就不写例子了,比较适合做选项卡
ComponentName 可以引入组件的名称或者是HTML标签
<component v-bind:is="ComponentName"></component>
九.Vue3.0新特性 Suspense异步组件
- vue2.0也存在异步组件,既然新东西何不尝试一下
- Suspense是vue3.0内置标签主要解决异步请求的困境
- 子组件写法
<template>
<h1>{{ result }}</h1>
</template>
<script>
import { defineComponent } from "vue";
export default defineComponent({
setup() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({
result: 'result'
})
}, 2000)
})
}
});
</script>
- 父组件使用
<template>
<div id="app">
<Suspense>
<template #default>
<AsyncComp></AsyncComp >
</template>
<template #fallback>
<h1>Loading...</h1>
</template>
</Suspense>
</div>
</template>
<script setup lang="ts">
import { defineAsyncComponent } from "vue";
const AsyncComp = defineAsyncComponent(() => import('./comp.vue'))
</script>
文章到这里就结束了,小伙子,当你完全看到这里的时候,说明你是一个非常有毅力的人,本篇文章除了封面没有任何插图,全是满满的干货,希望你通过此文章能Get到你想要的内容。最后补充一点其实在Vue中不单单存在这九种组件的写法,还存在其他,比如Vue3.0的tsx,jsx等等一些组件的写法后期会作者会将其补充。如果文章内容存在那些不足或者是问题,还请留言反馈,感谢!
不破不立的骑士!在这里恭喜EDG夺冠🎉🎉🎉
每个人都不能回到过去,但都能从现在开始。你好,我是小熊泰迪,咱们下篇文章再见!