让独立 JavaScript 文件与当前 Vue 实例无缝交互的实践

背景

在大型和复杂的业务中,如何让独立的 JavaScript 文件能够轻松地与当前 Vue 实例进行交互是一个关键问题。本文将介绍一种简单而有效的解决方案,以实现 JavaScript 文件与 Vue 实例的无缝交互。我们将以一个示例演示该方案,并展示如何在业务逻辑中灵活应用。

1. 定义 ctx 对象

  • view
    • AxiosView.vue
    • ctx
      • config.js
      • controller.js
      • service.js
      • ctx.js
      • enums.js

首先,我们需要定义一个 ctx 对象,在其中引入各种服务。

javascript 复制代码
// ctx.js
import config from "./config";
import controller from "./controller";
import enums from "./enums";
import service from "./service";

// eslint-disable-next-line no-unused-vars
// let vm = null;

const ctx = {
  init(vmInstance) {
    // vm = vmInstance;
    controller.init(vmInstance);
    service.init(vmInstance);
    enums.init(vmInstance);

    return this;
  },

  controller,
  service,
  config,
  enums,
};

export default ctx;

controller 使用service.js,config.js 中的函数或数据demo(其他js文件与controller.js类似写法)

ini 复制代码
// controller.js

let vm = null;

export default {
  init(vmInstance) {
    vm = vmInstance;
  },

  getMessage() {
    console.log(vm.$data.message); // 组件的实例有一个名为 message 的属性
  },

  setMessage(newMessage) {
    let res = vm.ctx.service.updateMessage();
    vm.$data.message =
      newMessage + " " + res.data + " " + vm.ctx.config.TIME_OUT;
  },

  async getCat() {
    vm.$data.imageUrl = "";

    let params = {
      limit: vm.$data.limit,
    };
    // 使用其他服务
    let res = await vm.ctx.service.getCat(params);
    vm.$data.imageUrl = res[0].url;
  },

  async getDog() {
    vm.$data.imageUrl = "";

    let res = await vm.ctx.service.getDog();
    vm.$data.imageUrl = res.message;
  },
};

2. 在 Vue 实例中引入 ctx 文件

在 Vue 实例中引入 ctx.js 文件,并在 created 钩子中将当前实例传入 ctx.init() 方法。

xml 复制代码
// AxiosView.vue

<template>
  <div>
    <!-- Vue 实例模板内容 -->
  </div>
</template>

<script>
import ctx from "./ctx/ctx";

export default {
  data(){
     return {
        ctx: null
     }
  },
  created() {
    // 在初始化时将当前 Vue 实例传递给 ctx
    this.ctx = Object.freeze(ctx.init(this));
  }
};
</script>

3. 在 Vue 模板中使用 ctx 的服务

现在,我们可以在 Vue 模板中使用 ctx 对象中的服务了。

xml 复制代码
// AxiosView.vue

<template>
  <div>
    <p>{{ message }}</p>
    <select name="" id="">
      <option value="">--Please choose an option--</option>
      <option
        v-for="item in ctx.enums.accountList()"
        :key="item.label"
        :value="item.value"
      >
        {{ item.value }}
      </option>
    </select>

    <div>
      <button @click="ctx.controller.getCat">getCat</button>
      <button @click="ctx.controller.getDog">getDog</button>
    </div>

    <div style="width: 200px; height: 200px; margin: auto">
      <div style="width: 100%; height: 100%; background: #ccc" v-if="!imageUrl">
        loading
      </div>
      <img v-else :src="imageUrl" alt="" style="width: 100%; height: 100%" />
    </div>
  </div>
</template>

<script>
import ctx from "./ctx/ctx";

export default {
  data() {
    return {
      ctx: null,

      message: "Hello, World!",
      limit: 1,
      imageUrl: "",
    };
  },
  created() {
    // 在初始化时将实例传递给 ctx
    this.ctx = Object.freeze(ctx.init(this));
    // ctx.controller.getMessage();
    // ctx.controller.setMessage("Hello, Vue!");
    // ctx.controller.getMessage();
    // console.log(this.ctx.enums.accountList());
  },
};
</script>

结论

通过上述示例,我们展示了如何在 Vue 单文件组件中让独立的 JavaScript 文件能够轻松地与当前 Vue 实例进行交互。这种方案简单易行,同时保持了代码的清晰和可维护性。您可以根据自己的业务需求,灵活地组织和使用 ctx 对象中的各种服务,以实现复杂业务逻辑的开发。

仓库地址:github.com/shouheyuan/...


(TODO)项目案例:

在我的项目中 「项目背景」 「服务拆分」

  • preview-table.vue
    • allocation.js // 收集所有模块数据,使用分配算法得到分配数据,传回实例中渲染
    • batch-edit.js // 批量编辑预览广告数据,编辑后调用分配函数,传回实例中渲染
    • ad-submit.js // 基于实例数据,按接口格式提交
相关推荐
kyriewen1 小时前
Skills 榜前 10 我全装了:只有 3 个能直接用
前端·javascript·程序员
工控丫丫2 小时前
帆软看板中经常使用的公式函数及经常搭的组合
前端·javascript·数据库
Dream-Y.ocean4 小时前
鸿蒙PC平台星图遥感适配实战:基于 Electron 壳方案的纯 JavaScript 遥感图像处理引擎开发
javascript·electron·harmonyos
螺丝钉tina5 小时前
[Playwright ][16]Playwright + TypeScript API 自动化测试实战:API测试
前端·javascript·typescript
Highcharts.js7 小时前
React 中原生支持使用 JSX 组件配置自定义表格 Highcharts Grid
前端·javascript·react.js·前端框架·jsx·highcharts·自定义表格
Java后端的Ai之路7 小时前
【AIAgent开发】-Agent工具封装成CLI(纯干货!!!)
java·javascript·人工智能·agent·cli
薛定谔的猫-菜鸟程序员7 小时前
Electron开发超详细教程(从入门到放弃)
前端·javascript·electron
小郎君6588 小时前
Vue 多标签页的加载态设计:为什么我没有用 Suspense 实现 PageLoading
vue.js·算法
htzyl2069 小时前
前端阶梯——第四十三章、实战二:待办清单To-Do
前端·javascript·html