侧边栏壁纸
博主头像
神奇的程序员

今天的努力只为未来

  • 累计撰写 167 篇文章
  • 累计创建 25 个标签
  • 累计收到 215 条评论

目 录CONTENT

文章目录

Vue实现文件中的的实例访问

神奇的程序员
2020-03-05 / 0 评论 / 2 点赞 / 431 阅读 / 2,351 字 正在检测是否收录...

前言

在Vue项目中进行工具类封装时,想访问Vue实例,你会怎么做?

本文将跟各位开发者分享一种解决方案,欢迎各位感兴趣的开发者阅读本文。

问题背景

  • main.js中,Vue原型上挂载了$layer方法
import Vue from "vue";
import layer from "vue-layer";
import "vue-layer/lib/vue-layer.css";
import utils from "./utils/index";

Vue.prototype.$layer = layer(Vue);
Vue.prototype.$vb = utils;

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount("#app");
  • layerUtil.js工具类中,对挂载在原型上的$layer方法,封装了几个常用函数
const layerUtil = {
  // 打开组件窗口
  openLayer(componentName, props, layerWidth, layerHeight, title) {
    this.$layer.iframe({
      content: {
        // 子组件
        content: componentName,
        parent: this,
        // 子组件传值
        data: props
      },
      area: [`${layerWidth}px`, `${layerHeight}px`],
      title: title,
      // 关闭事件
      cancel: () => {}
    });
  },
  // 显示消息提示
  showMsg(msg) {
    this.$layer.msg(msg);
  }
};

export default layerUtil;
  • 在工具类中我们使用了this.$layer.xx来访问原型上挂载的方法
  • 在组件中调用工具类中的layerUtil.showMsg()函数

如图所示,控制台会报错: msg未定义,原因是工具类中的this指向的是当前文件,而不是Vue实例

踩坑记录

将Vue实例暴露出去

  • 对main.js进行调整,导出Vue实例
/* 其他内容省略 */
const vue = new Vue({
  router,
  store,
  render: h => h(App)
}).$mount("#app");

export default vue;
  • 对工具类进行修改,在layerUtil.js工具类中,导入main.js,替换this为导入的main.js
import vue from "@/main";

const layerUtil = {
  // 打开组件窗口
  openLayer(componentName, props, layerWidth, layerHeight, title) {
    vue.$layer.iframe({
      content: {
        // 子组件
        content: componentName,
        parent: this,
        // 子组件传值
        data: props
      },
      area: [`${layerWidth}px`, `${layerHeight}px`],
      title: title,
      // 关闭事件
      cancel: () => {}
    });
  },
  // 显示消息提示
  showMsg(msg) {
    vue.$layer.msg(msg);
  }
};

export default layerUtil;

  • 在组件中调用工具类中的layerUtil.showMsg()函数

如图所示,控制台依然报错,msg未定义,原因是:mian.js此时尚未加载,拿不到当前vue实例。

解决方案:可以使用轮询来等main.js加载,得到vue实例

// 其他内容省略
 showMsg(msg) {
    let timer = setInterval(()=>{
     if (vue !== undefined) {
        vue.$layer.msg(msg);
        clearInterval(timer);
      }
    },100);
  }

将实例作为参数传进来

  • 对工具类进行修改,加多一个VueObject参数,调用时穿当前Vue实例过来
const layerUtil = {
  // 打开组件窗口
  openLayer(VueObject, componentName, props, layerWidth, layerHeight, title) {
    VueObject.$layer.iframe({
      content: {
        // 子组件
        content: componentName,
        parent: this,
        // 子组件传值
        data: props
      },
      area: [`${layerWidth}px`, `${layerHeight}px`],
      title: title,
      // 关闭事件
      cancel: () => {}
    });
  },
  // 显示消息提示
  showMsg(VueObject, msg) {
    VueObject.$layer.msg(msg);
  }
};

export default layerUtil;

  • 在组件中进行调用
import layerUtil from "@/utils/layerUtil";

export default {
  name: "index",
  mounted() {
    layerUtil.showMsg(this, "弹层工具类调用测试");
  }
};

如图所示,成功访问到了原型上的方法,当然将实例作为参数这种解决方案,不止能访问原型上的方法,也可以访问其他方法,比如路由。

写在最后

  • 文中如有错误,欢迎在评论区指正,如果这篇文章帮到了你,欢迎点赞和关注😊
  • 本文首发于掘金,未经许可禁止转载💌
2

评论区