vue如何把组件方法暴露到window对象中
场景:使用Vue开发电子地图功能,供客户端使用qtWebEngineView嵌入页面,客户端需要调用页面里定义的js方法实现相应功能。
问题:Vue组件内的方法,在外部调用不到。
原因:每个 Vue 组件都有自己的作用域,组件内定义的方法只能在该组件内部调用,以保持内部状态的封装和组件的复用性,避免命名冲突和不必要的耦合。
解决:把vue组件内的方法暴露到window对象中。
实现:
方法1:在vue组件内直接把方法挂到window上
Home.vue
mounted(){
window.markPoint = ()=>{
this.markPointFn()
}
},
methods:{
markPointFn(){
xxx
}
}
优点:实现方式简单,适合暴露方法不太多的系统.
缺点:
1、变量名易冲突:如果需要暴露的方法越来越多,那window对象中的全局变量也会越来越多,容易变量名冲突;
2、位置分散:随着业务的复杂化,暴露的方法可能分散在各个.vue文件中,不容易管理。
方法2:把需要暴露出去的方法挂载到Vue原型上,再把Vue对象暴露给window
1.在main.js中把Vue对象暴露给 window
const qtMapVm = new Vue({
router,
store,
render: (h) => h(App),
}).$mount("#app")
window.qtMapVm = qtMapVm
2.新建js文件,该文件用来存放需要暴露出去的方法
@/utils/exportVmFunction.js
exports.install = function (Vue) {
// 把需要暴露出去的方法挂载到Vue原型上,避免了全局变量过多的问题
// 全局方法都在这里,方便管理
Vue.prototype.markPoint = function (point) {
const component = findComponentDownward(this, "home")
component.markPoint(point)
}
Vue.prototype.drawRoutes = function (target) {
const component = findComponentDownward(this, "home")
component.drawRoutes(target)
}
Vue.prototype.drawMonitorRange = function (target) {
const component = findComponentDownward(this, "home")
component.drawMonitorRange(target)
}
Vue.prototype.removeRoutes = function (target) {
const component = findComponentDownward(this, "home")
component.removeRoutes(target)
}
}
/**
* 由一个组件,向下找到最近的指定组件
* @param {*} context 当前上下文,比如你要基于哪个组件来向上寻找,一般都是基于当前的组件,也就是传入 this
* @param {*} componentName 要找的组件的 name
*/
function findComponentDownward(context, componentName) {
const childrens = context.$children
let children = null
if (childrens.length) {
for (const child of childrens) {
const name = child.$options.name
if (name === componentName) {
children = child
break
} else {
children = findComponentDownward(child, componentName)
if (children) break
}
}
}
return children
}
- 在main.js中,导入刚刚声明好的js文件
import vmFunction from "@/utils/exportVmFunction"
Vue.use(vmFunction)
经过上述三步操作后,就可以在外部使用qtMapVm.markPoint(‘xxxx’)
来调用组件内的方法了。
优点:
1、方便管理:所有方法都在一个js文件中;
2、全局变量少:只有qtMapVm一个变量。