在uni-app的H5项目中,在全局所有页面中挂载公用组件

在uni-app的H5大型项目中,当部署后无法大规模改动的情况下,如何在不修改任何页面结构的前提下,在所有页面中挂载一个公用组件?

根据需求,不能修改 App.vue 的 ,也不能修改其他页面的代码。因此,可以通过动态创建组件实例并挂载到 DOM 上的方式,在全局中添加组件(如toolQuickBack.vue),并让它在所有页面即时生效。

✅ 实现思路

1.不修改模板:利用 Vue 的 $mount() 方法手动创建组件实例。
2.动态插入 DOM:将组件挂载后的 DOM 插入到页面顶部或底部。
3.控制显示逻辑:通过 vuex 或全局变量控制组件是否显示。

🧩 示例实现

1. 创建全局入口文件(如 globalToolQuickBack.js)

import Vue from 'vue';
// import store from './store'; // 引入你的 Vuex store 实例
import toolQuickBack from '@/components/toolQuickBack.vue';

let instance = null;

export function mountToolQuickBack(VueApp,store) {
  if (instance) return;

  // 创建组件构造器
  // const ToolQuickBackComponent = Vue.extend(toolQuickBack);
  
  // 手动挂载组件时,该组件实例是脱离 Vue 实例树的,没有将组件挂载到当前 Vue 应用实例(即 new Vue(...))的上下文中,导致组件内部无法访问 this.$store
  // 因此无法直接访问 $store、$router 等全局属性
  // 将 store 实例注入到组件实例中
  const ToolQuickBackComponent = Vue.extend({
    ...toolQuickBack,
    store, // 将 store 注入到组件实例中
  });
  // 这样组件就能通过 this.$store 访问到 Vuex 的状态。

  /* 解决手动挂载组件脱离Vue实例树的问题,还可以使用以下方案:

  方案二:通过 props 传递 store 数据(适用于简单数据) ---- 不推荐
  1、组件中定义props (showQuickBack);
  2、挂载时传入props:
    const ToolQuickBackComponent = Vue.extend(toolQuickBack);
	const instance = new ToolQuickBackComponent({
	  propsData: {
	    showQuickBack: store.state.quickBackVisible
	  }
	}).$mount();

  方案三:使用全局变量替代 $store
  如果项目较小或仅用于临时过渡,可以在 main.js 或 App.vue 中设置一个全局变量:
  // App.vue
  import store from './store';
  Vue.prototype.$globalStore = store; // 全局访问 store

  然后在 toolQuickBack.vue 中:
    computed: {
	  myState() {
	    return this.$globalStore.state.myKey;
	  }
	}

  ⚠️ 虽然有效,但不推荐长期使用这种方式,建议优先使用方案一。

  */

  // 创建组件实例并挂载
  instance = new ToolQuickBackComponent().$mount();

  // 将组件的 DOM 插入到 body 最前面
  document.body.insertBefore(instance.$el, document.body.firstChild);
}

export function unmountToolQuickBack() {
  if (!instance) return;
  instance.$destroy(); // 销毁组件
  instance.$el.remove(); // 移除 DOM
  instance = null;
}

2. 在 App.vue 中调用挂载函数

// App.vue
import store from './store'; // 引入你的 Vuex store 实例
import { mountToolQuickBack } from './utils/globalToolQuickBack'; // 根据实际路径引入

export default {
  store, // 确保 App.vue 使用了 store
  onLaunch() {
    // 初始化全局组件
    mountToolQuickBack(this,store);

    // 其他初始化逻辑...
  },
};

3. 确保 toolQuickBack.vue 支持独立使用
确保该组件不需要依赖任何父组件传递的 props,因为它将以独立方式挂载。

4. 可选:通过 Vuex 控制显示隐藏

// store.js
state: {
  showToolQuickBack: true,
},
mutations: {
  setShowToolQuickBack(state, flag) {
    state.showToolQuickBack = flag;
  }
}

然后在 toolQuickBack.vue 中监听:

computed: {
  show() {
    return this.$store.state.showToolQuickBack;
  }
},
watch: {
  show(nv) {
    this.$el.style.display = nv ? 'block' : 'none';
  }
}

✅ 效果说明

所有页面都会自动显示 toolQuickBack.vue。
不需要修改任何页面模板或代码。
即时生效,无需刷新页面。
支持动态控制显示/隐藏。

⚠️ 注意事项

由于是手动插入 DOM,需注意样式层级(如 z-index)。
若组件涉及事件绑定,确保其生命周期正确。
如果项目是 uni-app 多端项目,H5 端可以这样操作,小程序可能受限。

🔚 总结

你可以在不修改任何页面结构的前提下,通过手动挂载组件的方式,将 toolQuickBack.vue 添加到所有页面中。此方法适用于 H5 大型项目,且部署后无法大规模改动的情况。

解决手动挂载组件脱离Vue实例树的解决方案:
解决手动挂载组件脱离Vue实例树的解决方案

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值