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"],});@Componentexport 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>
小结:当你在使用组件那个页面引入这个组件时候,通过向组件传参,获取满足你当前页面需要用到的样式
总结:组件的使用就是,写组件,留插槽,给组件传参,用到页面上,大致用法就和上例一样,如果有不懂的地方可以留言,谢谢大家