组件封装
封装的目的就是为了能够更加便捷、快速的进行业务功能的开发。组件(component)是vue的最强大功能之一,组件可以实现一些类似功能的复用及与其它业务逻辑的解耦。在开发中,我们难免会写很多类似的、重复的代码,有时候两个业务模块有相似的功能,采用复制粘贴已经很省事,但如果涉及的字段或有一些小差别,你也会觉得很烦,毕竟你要从头到尾瞅着去改动。这时候如果把那些相同的功能,抽象出来抽离成组件,通过组件引用方式就会显得格外省事了
效果图
- 先上效果图
代码
1.子组件代码
<template>
<div :class="!plain ? 'box' : 'box_plain'">
<div
class="box_item"
v-for="(item, index) in options"
:key="index"
@click="boxClick(item)"
:class="
valueKey
? boxValue.indexOf(item[valueKey]) === -1
? ''
: 'is-active'
: boxValue.indexOf(item) === -1
? ''
: 'is-active'
"
>
{{ item[labelKey] }}
</div>
</div>
</template>
<script>
export default {
props: {
//多选数据
options: {
type: Array,
default: () => []
},
// 是否是边框模式
plain: {
type: Boolean,
default: false
},
// label绑定的值,默认为label,可以自定义
labelKey: {
type: String,
default: "label"
},
// 值绑定的值,默认为"",可以自定义
valueKey: {
type: String,
default: ""
},
// 选中的值,默认为[],可以自定义
value: {
type: Array,
default: () => []
}
},
data() {
return {
boxValue: this.value
};
},
created() {},
computed: {},
methods: {
// 多选点击事件
boxClick(item) {
if (!this.valueKey) {
if (this.boxValue.indexOf(item) === -1) {
this.boxValue.push(item);
} else {
this.boxValue.splice(this.boxValue.indexOf(item), 1);
}
} else {
if (this.boxValue.indexOf(item[this.valueKey]) === -1) {
this.boxValue.push(item[this.valueKey]);
} else {
this.boxValue.splice(this.boxValue.indexOf(item[this.valueKey]), 1);
}
}
}
},
watch: {
//原生v-model绑定的值
boxValue(val) {
this.$emit("input", val);
},
//原生v-model绑定的值
value(val) {
this.boxValue = val;
}
}
};
</script>
<style lang="scss" scoped>
.box {
display: flex;
flex-wrap: wrap;
align-items: center;
.box_item {
cursor: pointer;
box-sizing: border-box;
width: 100px;
height: 40px;
background: #5271c4;
margin: 2px 10px 2px 0;
color: #fff;
border-radius: 5px;
text-align: center;
line-height: 40px;
overflow: hidden;
}
.box_item:hover {
opacity: 0.8;
}
.is-active {
position: relative;
border: 1px solid #5271c4;
}
.is-active::after {
content: "\2714";
color: #5271c4;
line-height: 20px;
padding: 3px 0 0 5px;
box-sizing: border-box;
position: absolute;
overflow: hidden;
bottom: 0;
right: 0;
width: 20px;
height: 20px;
background: linear-gradient(
-45deg,
#fff,
#fff 50%,
transparent 50%,
transparent 100%
);
}
}
.box_plain {
display: flex;
flex-wrap: wrap;
align-items: center;
.box_item {
cursor: pointer;
box-sizing: border-box;
width: 100px;
height: 40px;
border: 1px solid $leftColor;
margin: 2px 10px 2px 0;
font-weight: 700;
color: #5271c4;
border-radius: 5px;
text-align: center;
line-height: 40px;
// box-shadow: 5px 5px 15px $leftColor;
overflow: hidden;
}
.box_item:hover {
opacity: 0.8;
}
.is-active {
position: relative;
}
.is-active::after {
content: "\2714";
color: #fff;
font-weight: normal;
line-height: 20px;
padding: 3px 0 0 5px;
box-sizing: border-box;
position: absolute;
overflow: hidden;
bottom: 0;
right: 0;
width: 20px;
height: 20px;
background: linear-gradient(
-45deg,
#5271c4,
#5271c4 50%,
transparent 50%,
transparent 100%
);
}
}
</style>
2.父组件中使用
//设置:value-key、label-key可指定绑定数据,和显示内容\不设置value-key默认绑定全部属性;plain属性为边框模式
//填充模式:
<boxselect v-model="value3" :value-key="'value'" :label-key="'label'" :options="options" />
//边框模式:
<boxselect v-model="value4" :options="options" plain />
//数据
data() {
return {
options: [
{
value: "选项1",
label: "黄金糕"
},
{
value: "选项2",
label: "双皮奶"
},
{
value: "选项3",
label: "蚵仔煎"
},
{
value: "选项4",
label: "龙须面"
},
{
value: "选项5",
label: "北京烤鸭"
}
],
value3: [],
value4: [],
}
},
//注册组件
components: {
boxselect: () => import("./components/boxselect.vue")
},
有疑惑可以私聊我哦🤞🤞🤞