VUE自定义组件
现在基于vue的UI组件库有很多,比如vant,element-ui等。但有时候这些组件库满足不了我们的开发需求,这时候我们就需要自己写一个插件。
首先我们来了解一下组件:
- 为什么用组件:因为一个项目里有很多高度相似的区域,或者说功能,每个页面都写一次,甚至一个页面写两次,会造成大量代码重复,并且维护困难,组件就是把这些代码进行封装,把不一样的地方植入插槽,这样需要用到的地方,只需要一行代码,就能实现,并且维护的时候只需要修改组件文件,不需要每个页面修改
- 插槽的含义:用到组件的页面通过向组件传值,达到控制组件展示不同效果,例如组件中有一个控制是否展示一个盒子的插槽,代码是v-if=“isShow”,父组件传值isShow=false;那么这个盒子就不会在父组件中展示
- 组件的使用:
- 首先,创建组件文件,并且完成组件代码,预留可控制插槽
- 其次,在运用组件的页面进行挂载,
- 最后在运用组件的页面,向组件传入控制插槽的参数,并且在页面中引入使用
第一个步骤:创建存放插件的文件夹
- 我们创建一个components文件夹下面创建你要写的插件的文件夹,里面有两个文件,一个VUE组件文件,一个js注册组件文件
第二部,写组件代码,我们这里是一个弹框样式的模板
<template>
<div>
<!-- v-model="show" 这里控制是否展示 @close="changeShow"是否展示 popHeight控制高度-->
<van-popup
v-model="show"
class="model_box"
@close="changeShow"
:style="{ height: popHeight }"
>
<div class="modelHeader">
<!-- 第一个插槽,头部标题 -->
<div class="modelTitle">
{{ title }}
<span></span>
</div>
</div>
<!-- 第二个插槽,内容展示用哪种2方法,通过type值来控制 -->
<div class="model_content" :class="{ resightShow: resightShow }">
<div class="content_info" v-if="type == 1" v-html="content"></div>
<div class="content_info" v-else-if="type == 2">{{ content }}</div>
<div class="content_info" v-else-if="type == 3">
<ul>
<li
v-for="(item, index) in content.orders"
:key="index"
class="order_lists"
>
<span>{{ index + 1 }}</span>
<div>
<p>{{ item.joinMoney }}</p>
<p class="times">{{ getCurrentDateTime(item.createTime) }}</p>
</div>
</li>
</ul>
</div>
</div>
<!-- 这是注册页特有的地步点击确认插槽,通过resightShow控制 -->
<div v-if="resightShow" class="resight_box">
<slot></slot>
</div>
<van-icon name="clear" size="25" @click="changeShow" class="iconClose" />
</van-popup>
</div>
</template>
<script lang="ts">
import Vue from "vue";
import Component from "vue-class-component";
import moment from "moment";
const options = Vue.extend({
// 这里接受父组件的参数,来控制这遍展示的样式
props: ["popHeight", "title", "content", "type", "modelShow", "resightShow"],
});
@Component
export default class Page extends options {
show = true;
changeShow() {
this.show = true;
this.$emit("changeShowNow", false);
}
getCurrentDateTime(date) {
return moment(date).format("MMMM DD YYYY, HH:mm:ss");
}
}
</script>
<style scoped>
.model_box {
width: 90%;
border-radius: 8px;
padding: 20px;
box-sizing: border-box;
overflow: visible;
}
.modelHeader {
width: 200px;
height: 30px;
position: absolute;
top: 0;
left: 50%;
transform: translate(-50%, -50%);
}
.modelTitle {
width: 100%;
height: 100%;
background: #118557;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
font-size: 14px;
position: relative;
border-radius: 3px;
}
.modelTitle span {
position: absolute;
left: 0;
top: 0;
transform: translateY(196%);
width: 0;
height: 0;
border-left: 100px solid transparent;
border-right: 100px solid transparent;
border-top: 15px solid #118557;
}
.model_content {
margin-top: 15px;
height: 90%;
overflow-x: hidden;
overflow-y: scroll;
word-break: normal;
word-wrap: break-word;
font-size: 14px;
}
.resightShow {
height: 70%;
}
.content_info {
word-break: normal;
word-wrap: break-word;
}
.iconClose {
position: absolute;
left: 50%;
bottom: 0;
transform: translate(-50%, 130%);
color: #fff;
}
.order_lists {
border-bottom: 1px solid #f8f8f8;
margin-top: 8px;
display: flex;
flex-direction: row;
}
.order_lists span {
margin-right: 10px;
}
.order_lists p {
line-height: 25px;
font-size: 12px;
}
.order_lists .times {
color: #ccc;
}
.resight_box {
margin-top: 15px;
}
</style>
小结:当你在使用组件那个页面引入这个组件时候,通过向组件传参,获取满足你当前页面需要用到的样式
总结:组件的使用就是,写组件,留插槽,给组件传参,用到页面上,大致用法就和上例一样,如果有不懂的地方可以留言,谢谢大家