开个系列的文章记录一下自己封装vue组件的经历,就以弹窗组件为例:
1.局部封装(基础组件):
新建一个vue的基础组件,把公用的数据和方法提取出来,弹窗要注意阴影遮罩层
//html结构
<template>
<div class="dialog">
<div class="dialog-cover back" v-show="show"></div>
<div class="modal-container" v-show="show">
<div class="modal-header">{{ title }}</div>
<div class="modal-main">
<!-- 预留一个插槽位置 -->
<slot></slot>
</div>
<div class="modal-footer">
<button @click="cancelClick">取消</button>
<button @click="confirmClick">确认</button>
</div>
</div>
</div>
</template>
如上图所示html部分,遮罩层必须必须有v-show属性,组件根div和modal-container两者选其一控制隐藏就可以了,视具体情况和业务逻辑而定,modal-heade就是抽出来的公共部分,仅做个示例,具体情况可能会有许多公用的部分,<slot></slot>是插槽,组件的封装调用最灵活的就是插槽的使用
//js部分
export default {
name: "dialoga",
props: {
show: {
type: Boolean,
default: false
},
title: {
type: String,
default: ""
}
},
methods: {
cancelClick() {
this.$emit("hideModal");
},
confirmClick() {
this.$emit("submit");
}
}
父子组件通信的点击事件,需要在子组件中通过$emit派发一个方法出去,这个方法在父组件中监听回,可以写回调的逻辑,然后我们在页面中调用该子组件,那么此页面就是父组件了,子组件接收来自父组件的值,需要用props接收,这是单向流数据传递,要注意的是,自组件porp是定义的是变量的类型
<template>
<div>
<button @click="showD">点击展示弹窗</button>
<Dialog :show="show" :title="title" @hideModal="cancel" @submit="confirm">
<span>使用插槽</span>
</Dialog>
</div>
</template>
<script>
import Dialog from "../components/DialogA.vue";
export default {
data() {
return {
title: "弹窗标题",
show: false
};
},
components: { Dialog },
methods: {
showD() {
this.show = true;
},
cancel() {
// 取消弹窗回调
this.show = false;
},
confirm() {
// 确认弹窗回调
this.show = false;
}
}
};
</script>
<style scoped>
</style>
上述代码中:在vue中是v-bind的语法糖写法,我们在自组件中抽出来的公用部分,需要在父组件中绑定,回调的事件需要在父组件绑定,用v-on绑定,语法糖写法是@,给绑定的事件一个方法,就可以在父组件的方法中写当前逻辑了。
奉上该组件的css部分:
<style lang="stylus" scoped>
.dialog {
position: relative;
color: #2e2c2d;
font-size: 16px;
}
.dialog-cover {
background: rgba(0, 0, 0, 0.8);
position: fixed;
z-index: 200;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.modal-container {
position: fixed;
top: 35%;
left: 30%;
z-index: 300;
background-color: #ffffff;
}
</style>
2.全局组件封装
全局组件封装我们从简单的例子开始入手,以全局封装一个button按钮为例,第一步也是需要一个基础的组件
<template>
<button class="btn">
<slot/> <!-- 插槽 -->
</button>
</template>
<script>
export default {
// 传入子组件的参数写到props
props: {
}
}
</script>
<style scoped>
.btn {
width: 100px;
height: 50px;
color:red;
border: none;
font-size: 14px;
}
</style>
全局组件要让全局都能调用他,就需要注册一个js文件,让基础组件在js中注册,然后导出:
import xxxxxxx from 'xxxxxxx' //引入刚才的基础vue组件
// 添加install方法
const Button = {
install: function (Vue) {
Vue.component("Button", ButtonComponent);//注册组件
}
}
// 导出
export default Button
最后,需要在vue的入口js文件,也就是main.js文件中来引入注册的js文件,然后使用vue.use方法使封装的组件成为vue的一个实例,能在全局中使用:
import Button from 'xxxxxx'//引用全局组件Button
Vue.use(Button);//使用全局组件Button
想要在页面中使用该全局组件,如下:
<template>
<div id="app">
<!-- 使用Button组件 -->
<Button>全局按钮</Button>
</div>
</template>
这一期就先到这里,全局组件的封装不局限与这一种方法,而且全局组件的公用部分的抽取封和使用稍复杂一下,我们放到下期再讲