美文网首页
vue-全局通讯层

vue-全局通讯层

作者: KIKIWS | 来源:发表于2019-08-07 16:37 被阅读0次

今天分享的主题是复杂组件中的事件通讯,内容包括建立通讯层的出发点,建立过程中的方案确定,以及最终实现。

建立通讯层的出发点

我们来思考下复杂组件的业务场景,比如商品组件的商品卡片,组件拆分需要细致到商品图片,商品服务标签、氛围标签,商品价格,按钮等,很多触发事件都是指向跳转商祥页面,但是这些小组件的层级不是相同的而是存在嵌套关系,那就需要一个全局的通讯层,来接收共用的事件消息通知。

通讯层方案

装载/卸载全局消息处理器

专题实例创建时装载全局消息处理器,实例销毁时卸载全局消息处理器

 beforeMount() {
   // 装载全局消息处理器
   installHandler.call(this)
 }
deactivated() {
    // 卸载全局消息处理器
    unistallFunHandler.call(this)
 }

监听与发送触达

在vue1.0中,我们可以使用

$dispatch() // 派发事件,沿着父链冒泡
$broadcast() // 广播事件, 向下传递给所有的后代

这可以满足使用与全局广播的功能,但是在vue2.0中已经删除了这两个方法,我们需要换一种方式。
根据vue1.0 $dispatch的写法,Element 实现了dispatch,如下:

dispatch(componentName, eventName, params) {
  var parent = this.$parent || this.$root;
  var name = parent.$options.componentName;
  //寻找父级,如果父级不是符合的组件名,则循环向上查找
  while (parent && (!name || name !== componentName)) {
    parent = parent.$parent;
    if (parent) {
      name = parent.$options.componentName;
    }
  }
  //找到符合组件名称的父级后,触发其事件。整体流程类似jQuery的closest方法
  if (parent) {
    parent.$emit.apply(parent, [eventName].concat(params));
  }
 }

通过源码我们可以看到实现的方案是层层查找,对于此方案我们并不满意,在查找的过程中也发现了$root的使用,也就是我们现在所使用的层级传递解决方案:

/**
 * 装载全局消息处理器
 */
export function installHandler() {
  this.$root.$on('msgHandler', (messageName, param = {}) => {
    const { reportPoints } = param
    this.clickEventReport(reportPoints)
    methodHandle.call(this, messageName, param)
  })
}
/**
 * 卸载全局消息处理器
 */
export function unistallFunHandler() {
  this.$root.$off('msgHandler')
}     
/**
 * 发送消息示例
 */
this.$root.$emit('msgHandler', 'commonEvent', params)

消息处理

在此步骤中已经明确,需要将共用的方法抽取独立文件。
一开始我是在页面初始化阶段,将共用的方法通过setMethods设置在实例中,触发时调用。考虑后续拓展及更优的使用方式,最后使用mixin的方式将共用的方法插入实例中。下图的示例是setMethods的实现

/**
 *  设置公共方法在vue实例
 */
function setMethods () {
  function polyfillBind (fn, ctx) {
    function boundFn (a) {
      const l = arguments.length
      return l
        ? l > 1
          ? fn.apply(ctx, arguments)
          : fn.call(ctx, a)
        : fn.call(ctx)
    }
    boundFn._length = fn.length
    return boundFn
  }
  function nativeBind (fn, ctx) {
    return fn.bind(ctx)
  }
  const bind = Function.prototype.bind ? nativeBind : polyfillBind
  Object.keys(methods).forEach((key) => {
    this[key] = methods[key] == null ? noop : bind(methods[key], this)
  })
}

到此我们就只剩下最后的步骤,将接收到的消息转化为方法调用。

/**
 * 消息处理
 * @param messageName 消息名称
 * @param param       消息参数
 */
function methodHandle(messageName, param) {
  try {
    if (typeof (this[messageName]) !== 'function') return false
    this[messageName](param)
  } catch (e) {
    return false
  }
}

相关文章

  • vue-全局通讯层

    今天分享的主题是复杂组件中的事件通讯,内容包括建立通讯层的出发点,建立过程中的方案确定,以及最终实现。 建立通讯层...

  • vue-全局 API

    Vue.extend( options ) 参数: {Object} options 用法: 使用基础 Vue 构...

  • vue-全局配置

    Vue.config是一个对象,包含 Vue 的全局配置。可以在启动应用之前修改下列属性: silent 类型:b...

  • 使用 vue-cli 脚手架一键搭建工程

    五部走: 全局安装vue-­cli 进入目录–初始化项目 进入项目 安装依赖 启动项目 目录结构的分析 一、├──...

  • 网络

    网络模型:应用层,表示层,会话层,传输层,网络层,数据链路层,物理层。网络的通讯其实就是socket间的通讯(通讯...

  • 使用vue-cli脚手架工具来搭建项目

    首先电脑上要安装最新版的nodeJS.官网下载,安装完之后安装淘宝npm镜像 五部走:1、全局安装vue-­cli...

  • HAP Cloud功能手册

    HAP Cloud功能分四个层:全局层、组织层、项目层、用户层 I 全局层 选中顶部导航栏的【管理】选项,即可进入...

  • Electron主进程与渲染进程之间的通信

    通过设置全局变量进行通讯 Electron-vue

  • vue-封装axios(不带token)

    vue-封装axios(不带token)

  • DLMS通讯过程

    DLMS通讯过程共有三层,包括以下 物理层,链路层,应用层。每层通讯都是CS模式,数据请求端为C,数据提供端...

网友评论

      本文标题:vue-全局通讯层

      本文链接:https://www.haomeiwen.com/subject/qyfadctx.html