Vue 2.x折腾记 - (18) 用Vue的Inject Provide结合Event Bus来实现局部的状态维护

简介: 原型有个东西,看着是几个功能组件的组合体;想拆分成对应的组件(全部写在一起是贼恐怖的事情),又不想用Vuex这类来实现。那最终的方案就是Vue的eventbus了, 这只是一种方案的实现。具体业务请具体分析是否可以用这个来维护多组件数据的


前言


原型有个东西,看着是几个功能组件的组合体;


想拆分成对应的组件(全部写在一起是贼恐怖的事情),又不想用Vuex这类来实现。


那最终的方案就是Vueeventbus了, 这只是一种方案的实现。


具体业务请具体分析是否可以用这个来维护多组件数据的通讯!


效果图


只展示部分功能,实际原型要复杂的多;



原型大体是这样的



实现原理


其实就是各个组件独立维护自己的状态,组件的默认值从外部传入;


而内部通过watchimmediate立即触发复制一份到data,

watch data回调$emit,而对于聚拢所有数据,我们就用event bus来实现;


如何局部状态化,就用到了inject provide了,在当前组件下provide,该分支的所有子组件都能inject;


ng有这个概念,reactcontext也是差不多的玩意


代码参考


依旧如前两篇文章,基于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>
目录
相关文章
|
2月前
|
API
vue3知识点:provide 与 inject
vue3知识点:provide 与 inject
34 4
vue3知识点:provide 与 inject
|
3月前
|
API UED
如何实现Vue2项目升级Vue3?
如何实现Vue2项目升级Vue3?
299 59
|
2月前
Vue3 中使用 Event Bus
【10月更文挑战第16天】Event Bus 是 Vue3 中一种简单而实用的通信方式,在一些简单的场景中可以发挥重要作用。但在实际应用中,要根据项目的具体需求和复杂度,选择合适的通信方式,以实现最佳的性能和可维护性。同时,要遵循最佳实践,合理使用 Event Bus,避免出现问题。
115 5
|
3月前
|
缓存 JavaScript 前端开发
「offer来了」从基础到进阶原理,从vue2到vue3,48个知识点保姆级带你巩固vuejs知识体系
该文章全面覆盖了Vue.js从基础知识到进阶原理的48个核心知识点,包括Vue CLI项目结构、组件生命周期、响应式原理、Composition API的使用等内容,并针对Vue 2与Vue 3的不同特性进行了详细对比与讲解。
「offer来了」从基础到进阶原理,从vue2到vue3,48个知识点保姆级带你巩固vuejs知识体系
|
2月前
|
JavaScript 前端开发 算法
对比一下Vue2 和 Vue3?—— 8个方面给你答案
本文介绍了 Vue 和 React 的起源、核心思想、表现形式、API 差异、社区差异、升级方向、响应式原理、Diff 算法、事件机制,并进行了总结。Vue 以其渐进式框架设计和简洁性著称,而 React 则强调单向数据流和灵活性。两者均支持组件化开发和虚拟 DOM,适用于不同的开发场景。
25 0
对比一下Vue2 和 Vue3?—— 8个方面给你答案
|
2月前
|
JavaScript 前端开发
VUE学习三:双向绑定指令(v-mode)、组件化开发(全局组件/局部组卷/组件通信)、组件化高级(slot插槽使用)
这篇文章是关于Vue.js框架中的v-model指令和组件化开发的详细教程,涵盖了从基础使用到高级功能的多个方面。
31 1
|
2月前
|
缓存 JavaScript 前端开发
对比一下Vue2和Vue3?
本文首发于微信公众号“前端徐徐”,详细对比了 Vue 2 和 Vue 3 在原理、生命周期、性能、编码方式、API、Diff 算法、打包构建、TS 支持等八个方面的差异,帮助读者全面了解两者的不同之处。
198 0
对比一下Vue2和Vue3?
|
2月前
|
JavaScript API
|
2月前
|
JSON JavaScript 前端开发
vue尚品汇商城项目-day00【项目介绍:此项目是基于vue2的前台电商项目和后台管理系统】
vue尚品汇商城项目-day00【项目介绍:此项目是基于vue2的前台电商项目和后台管理系统】
45 1
|
2月前
|
JavaScript 前端开发 Java
vue2知识点:Vue封装的过度与动画
vue2知识点:Vue封装的过度与动画
15 0