原型有個東西,看着是幾個功能組件的組合體;javascript
想拆分紅對應的組件(所有寫在一塊兒是賊恐怖的事情),又不想用Vuex
這類來實現。css
那最終的方案就是Vue
的eventbus
了, 這只是一種方案的實現。html
具體業務請具體分析是否能夠用這個來維護多組件數據的通信!vue
只展現部分功能,實際原型要複雜的多;java
原型大致是這樣的react
其實就是各個組件獨立維護本身的狀態,組件的默認值從外部傳入;antd
而內部經過watch
在immediate
當即觸發複製一份到data
,ide
再watch data
回調$emit
,而對於聚攏全部數據,咱們就用event bus
來實現;flex
如何局部狀態化,就用到了inject provide
了,在當前組件下provide
,該分支的全部子組件都能inject
;ui
ng
有這個概念,react
的context
也是差很少的玩意
依舊如前兩篇文章,基於antd design vue
來實現的,固然還有部分自定義組件是本身封裝的
因此呢,看看用法就好,通常來講大家跑步起來
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
;
有不對之處請留言,會及時修正,謝謝閱讀