javascript - 在 Vuejs 3 中实现插件系统
问题描述
我正在尝试为我的 Vue3/Laravel 应用程序实现一个(简单的)插件系统。为了快速获得工作版本,我决定定义一个全局变量 ( window.$plugins
),它引用我的应用程序app
和添加新插件的函数register(data)
。
插件需要一个主 js 文件main.js
和一个应显示为插件的 vue 组件(例如Counter.vue
)。(本文末尾是一个示例组件和插件)
服务器上的设置也很基本。如果服务器 ( ./plugins/Counter
) 上存在文件夹,则该文件./plugins/Counter/counter.js
将添加到我的主 HTML 并在应用程序本身之后加载。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Styles -->
<link href="css/app.css" rel="stylesheet">
</head>
<body>
<div id="app" class="d-flex flex-column"></div>
<!-- Scripts -->
<script src="js/app.js"></script>
<script src="js/file.js"></script>
</body>
</html>
当我现在加载我的应用程序时,插件也被加载了,但是有几个问题:
- 反应性不起作用。反应性变量发生变化(例如,如果我登录
console.log(state.count)
),但 HTML 部分未更新 - 模板中没有包含在自己的标签中的部分根本不显示
<template>
<div>
<!-- displayed; but stays at Count: 0 -->
<span>Count: {{ state.count }}</span>
<!-- not displayed -->
Count: {{ state.count }}
<!-- not displayed as well -->
Hello Vue!
</div>
</template>
有什么我想念的吗?我读了几篇文章,反应性的问题是import {reactive} from 'vue'
我的插件中的 引用了另一个 vue 实例,而不是我的主应用程序中的导入。但我也读到这不是问题。我还尝试将reactive
其作为全局window.$plugins
变量的一部分公开。这解决了反应性问题,但 HTML 中未包装的行仍未呈现?
结果看起来应该可以正常工作,但是我缺少一部分来使它正确。因此,如果有人有提示或解决方案,我会非常高兴:)
主应用程序(使用 Laravel Mix 构建(Webpack)
// webpack.mix.js
mix.js('resources/js/app.js', 'public/js').vue();
// babel.config.js
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}
// app.js
const app = createApp(App);
window.$plugins = {
app: app,
register: data => {
// simple add plugin as global component
window.$plugins.app.component(data.component.name, data.component);
},
}
app.mount('#app');
插件(使用 vue-cli 构建)
// vue.config.js
module.exports = {
productionSourceMap: false,
chainWebpack: config => {
config.optimization.delete('splitChunks')
},
filenameHashing: false,
}
// babel.config.js
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}
// main.js
import Counter from './components/Counter.vue';
window.addEventListener('load', _ => {
window.$plugins.register({
// some data...
component: Counter,
});
});
<template>
<div>
Count: {{ state.count }}
<button type="button" @click="inc()">Click</button>
</div>
</template>
<script>
import {reactive} from 'vue';
export default {
name: 'Counter',
setup() {
const state = reactive({
count: 0,
});
const inc = _ => {
state.count++;
}
return {
state,
inc,
};
}
}
</script>
解决方案
推荐阅读
- nginx - 我将我的 jekyll _site 文件夹推送到服务器的子文件夹 /blog 中,如何修复所有资产和链接?
- javascript - 演示图像 CSS - javascript
- python - 非停止正则表达式(python re 模块)
- rspec - 如何模拟dry-rb(使用inf改革合约)验证配置方法
- javascript - Django/React - 你可能需要一个合适的加载器来处理这个文件类型
- javascript - 用javascript中的值替换函数中的变量
- django - 以与注解类似的方式链接 Django QuerySet
- xamarin.forms - 在依赖服务中获取导航栏高度 - Xamarin Forms
- javascript - 如何在 JavaScript 函数中使用来自 ajax 请求的 json 响应作为 Javascript 数组
- google-chrome-extension - 扩展 Chrome.Proxy,仅代理某些网站