前言
原型有个东西,看着是几个功能组件的组合体;
想拆分成对应的组件(全部写在一起是贼恐怖的事情),又不想用Vuex
这类来实现。
那最终的方案就是Vue
的eventbus
了, 这只是一种方案的实现。
具体业务请具体分析是否可以用这个来维护多组件数据的通讯!
效果图
只展示部分功能,实际原型要复杂的多;
原型大体是这样的
实现原理
其实就是各个组件独立维护自己的状态,组件的默认值从外部传入;
而内部通过watch
在immediate
立即触发复制一份到data
,
再watch data
回调$emit
,而对于聚拢所有数据,我们就用event bus
来实现;
如何局部状态化,就用到了inject provide
了,在当前组件下provide
,该分支的所有子组件都能inject
;
ng
有这个概念,react
的context
也是差不多的玩意
代码参考
依旧如前两篇文章,基于antd design vue
来实现的,当然还有部分自定义组件是自己封装的
所以呢,看看用法就好,一般来说你们跑步起来
eventbus.js
import Vue from 'vue';
export const eventBus = new Vue();
复制代码
BasicSetting.vue
(父组件)
记得在组件生命周期销毁!!这是个好习惯!!!
<template>
<a-card :bodyStyle="{ position: 'relative' }">
<template #extra>
<btn-popconfirm
size="default"
:text="isEdit ? '关闭编辑' : '开启编辑'"
:message="`确定要${isEdit ? '关闭编辑' : '开启编辑'}续期配置?`"
@change="onEdit"
/>
<btn-popconfirm
size="default"
type="primary"
text="确定配置"
:disabled="!isEdit"
:message="`确定要更新配置?操作需谨慎!`"
@change="onUpdate"
/>
template>
<div class="basic-setting">
<a-col v-bind="{ xs: 24, sm: 24, md: 24, lg: 24, xxl: 6 }">
<pivot-card :defaultValue="pivotData" :bordered="false" />
a-col>
<a-col v-bind="{ xs: 24, sm: 24, md: 24, lg: 24, xxl: 18 }">
<product-item />
a-col>
div>
<div class="overlay" v-if="!isEdit" />
a-card>
template>
<script>
import PivotCard from './PivotCard';
import ProductItem from './ProductItem';
import { eventBus } from '@/utils/eventBus';
export default {
name: 'BasicSetting',
provide: function() {
return {
bus: eventBus
};
},
components: {
PivotCard,
ProductItem
},
created() {
eventBus.$on('pivot', this.getPivotData);
eventBus.$on('productItem', this.getProductItemData);
},
beforeDestroy() {
eventBus.$off('pivot');
},
data() {
return {
isEdit: false, // 是否开启编辑
pivotData: {
// 基准信息
minMoney: 200, // 最低金额
maxMoney: 4000, // 最高金额
defaultAmount: 2000 // 默认额度
}
};
},
methods: {
onEdit(e) {
// 开启关闭编辑
if (e) {
this.isEdit = !this.isEdit;
}
},
onUpdate(e) {
// 更新提交
},
getPivotData(e) {
console.log('我是基准表单的值回调: ', JSON.stringify(e));
// 获取基准信息的回调
},
getProductItemData(e) {
console.log('我是产品项的值回调: ', JSON.stringify(e));
}
}
};
script>
<style lang="scss" scoped>
.overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(230, 229, 229, 0.24);
z-index: 999;
}
style>
复制代码
PivotCard.vue
子组件
<template>
<a-card>
<template #title>
最低金额、最高金额、默认额度
template>
<a-row type="flex" justify="start" align="middle" style="margin:10px 0;">
<a-col :sm="24" :md="10">
<span style="padding:5px 0">最低金额span>
a-col>
<a-col :sm="24" :md="14">
<a-input-number
:min="0"
v-model="fields.minMoney"
:formatter="value => `¥ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')"
:parser="value => value.replace(/\¥\s?|(,*)/g, '')"
/>
a-col>
a-row>
<a-row type="flex" justify="start" align="middle" style="margin:10px 0;">
<a-col :sm="24" :md="10"> <span style="padding:5px 0">最高金额span>a-col>
<a-col :sm="24" :md="14">
<a-input-number
:min="0"
:formatter="value => `¥ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')"
:parser="value => value.replace(/\¥\s?|(,*)/g, '')"
v-model="fields.maxMoney"
/>
a-col>
a-row>
<a-row type="flex" justify="start" align="middle" style="margin:10px 0;">
<a-col :sm="24" :md="10"> <span style="padding:5px 0">默认额度span>a-col>
<a-col :sm="24" :md="14">
<a-input-number
:min="0"
:max="100"
v-model="fields.defaultAmount"
:formatter="value => `¥ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')"
:parser="value => value.replace(/\¥\s?|(,*)/g, '')"
/>
a-col>
a-row>
a-card>
template>
<script>
export default {
inject: ['bus'],
data() {
return {
fields: {}
};
},
props: {
defaultValue: {
// 默认值
type: Object,
default: function() {
return {
minMoney: 200,
maxMoney: 4000,
defaultAmount: 2000
};
}
}
},
watch: {
defaultValue: {
// 把默认值初始化了
immediate: true,
deep: true,
handler(newValue, oldValue) {
if (newValue) {
this.fields = newValue;
}
}
},
fields: {
// 监听变动回调给父
immediate: true,
deep: true,
handler(newValue, oldValue) {
console.log('newValue, oldValue: ', newValue, oldValue);
if (newValue) {
this.bus.$emit('pivot', newValue);
}
}
}
}
};
script>
<style lang="scss" scoped>
.ant-input-number {
min-width: 150px;
}
style>
复制代码
总结
到这里,我们结合Vue
提供的一些特性实现了,可能某些特性有些小伙伴用的少;
这里有用到新的slot
语法,还有比较冷门的provide | inject
;
有不对之处请留言,会及时修正,谢谢阅读