Heim > Artikel > Web-Frontend > Komponentenfreigabe, die Vue-Remote-Code lädt
In unserem Vue-Projekt (insbesondere im Backend-System) wird es immer einige Szenarien geben, in denen mehrere Geschäftsbereiche gemeinsam dasselbe Projekt entwickeln müssen. Wenn jedes Geschäftsteam dem Framework einige private Anzeigekomponenten bereitstellt, diese Komponenten jedoch nicht Es kann nicht zusammen mit dem Framework gepackt werden, da das Framework aufgrund häufiger Änderungen in einem privaten Modul nicht wiederholt erstellt und veröffentlicht werden kann. In diesem Szenario benötigen wir eine Komponente, die asynchronen Remotecode lädt, um das Laden dieser Komponenten in das Framework abzuschließen.
vue-cli ist das offiziell empfohlene Projektbaugerüst für Vue. Es bietet Funktionen, die häufig im Entwicklungsprozess verwendet werden, wie z. B. Hot-Reloading, Erstellen, Debuggen, Unit-Tests, Codeerkennung und andere Funktionen. Unsere asynchrone Remote-Komponente wird dieses Mal auf Basis von vue-cli entwickelt.
Anforderungsanalyse
Wie lade ich Remote-Code?
Wie registriere ich den geladenen Code im Framework?
Wie die übergeordnete Komponente mit der remote importierten Komponente kommuniziert.
Wie der Remote-Code die im Framework eingeführten Bibliotheken wiederverwendet.
Vermeiden Sie unnötige Anfragen, die durch mehrmaliges Aufrufen von Remote-Code wie v-for verursacht werden.
Remote-Code laden
Der Remote-Code sollte auf einer zugänglichen URL gespeichert sein, damit wir diesen Link über einen HTTP-Client wie Axios anfordern können Quellcode.
import Axios from 'axios'; export default { name: 'SyncComponent', props: { // 父组件提供请求地址 url: { type: String, default: '' } }, data() { return { resData: '' }; }, async mounted() { if (!this.url) return; const res = await Axios.get(this.url); // 我们在组件挂载完成时,请求远端代码并存储结果。 this.resData = res.data; } };
Das Obige ist der Basiscode. Der Einfachheit halber werde ich die wiederholten Codeteile in den folgenden Beispielen weglassen.
Code im Framework registrieren
Dieser Teil ist etwas umständlich und beinhaltet mehrere Probleme:
Der Browser unterstützt keine .vue-Vorlagen oder ES.next-Syntax und -Module require Es kann nach der Kompilierung verwendet werden.
Es ist relativ einfach, mit diesem Teil umzugehen. Wir definieren selbst eine Webpack-Konfigurationsdatei, um diese Vorlagen zu packen.
// 在 build 目录下新建 webpack.sync-components.prod.conf.js 文件 const webpack = require('webpack'); const path = require('path'); const utils = require('./utils'); const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') function resolve(dir) { return path.join(__dirname, '..', dir) } module.exports = { // 此处引入要打包的组件 entry: { componentA: resolve('/src/views/component-a.vue') }, // 输出到静态目录下 output: { path: resolve('/static/'), filename: '[name].js', }, resolve: { extensions: ['.js', '.vue', '.json'], alias: { 'vue$': 'vue/dist/vue.esm.js', '@': resolve('src'), } }, module: { rules: [ { test: /\.vue$/, loader: 'vue-loader', options: { esModule: false, // ****** vue-loader v13 更新 默认值为 true v12及之前版本为 false, 此项配置影响 vue 自身异步组件写法以及 webpack 打包结果 loaders: utils.cssLoaders({ sourceMap: true, extract: false // css 不做提取 }), transformToRequire: { video: 'src', source: 'src', img: 'src', image: 'xlink:href' } } }, { test: /\.js$/, loader: 'babel-loader', include: [resolve('src'), resolve('test')] }, { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: utils.assetsPath('img/[name].[hash:7].[ext]') } }, { test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: utils.assetsPath('media/[name].[hash:7].[ext]') } }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: utils.assetsPath('fonts/[name].[hash:7].[ext]') } } ] }, plugins: [ new webpack.DefinePlugin({ 'process.env.NODE_ENV': '"production"' }), // 压缩JS new webpack.optimize.UglifyJsPlugin({ compress: false, sourceMap: true }), // 压缩CSS 注意不做提取 new OptimizeCSSPlugin({ cssProcessorOptions: { safe: true } }) ] };
Zu diesem Zeitpunkt wurde unser Modul in eine Datei kompiliert, die das Framework erkennen kann.
1. So konvertieren Sie einen String in ein JS-Objekt.
new Function。 async mounted() { if (!this.url) return; const res = await Axios.get(this.url); let Fn = Function; this.mode = new Fn(`return ${res.data}`)(); }
1. Das konvertierte js-Objekt kann von vue nicht erkannt werden.
Es gibt zwei Möglichkeiten, die dieses Problem verursachen können:
// vue-loader v13 esModule 更新 默认值为 true, v12及之前版本为 false, 此项配置影响 vue 自身异步组件写法以及 webpack 打包结果 { test: /\.vue$/, loader: 'vue-loader', options: { esModule: false ... 以下省略千军万码 } } // UglifyJs 需要取消变量名替换配置,此配置并不会极大影响压缩率 new webpack.optimize.UglifyJsPlugin({ compress: false, sourceMap: true })
Zu diesem Zeitpunkt wurde die Remote-Komponente in das Framework eingeführt.
Wie kommuniziert die übergeordnete Komponente mit der remote eingeführten Komponente?
Hier gibt es drei Kommunikationsebenen von der Ansichtskomponente zur entfernten asynchronen Ladekomponente die eigentliche Geschäftskomponente Die mittlere Schicht Da es sich um eine öffentliche Komponente handelt, kann die entfernte asynchrone Komponente nicht geändert werden und erfordert, dass die Ansichtskomponente direkt mit der eigentlichen Geschäftskomponente kommuniziert. Sowohl Vuex- als auch EventBus-Lösungen sind zu umständlich. Hier verwenden wir $attrs und $listeners (vue v2.4+), um einen „Fallthrough“ (ebenenübergreifende Kommunikation von Vue-Komponenten) zu erreichen.
// 修改 sync-component.vue 组件 // 新增 v-bind="$attrs" v-on="$listeners" <component :is="mode" v-bind="$attrs" v-on="$listeners"> </component> // inheritAttrs: true export default { name: 'SyncComponent', props: { // 父组件提供请求地址 url: { type: String, default: '' } }, inheritAttrs: true ... 以下省略千军万码 }
Wie Remote-Code Bibliotheken wiederverwendet, die im Framework eingeführt wurden
Wir möchten nicht, dass größere Bibliotheken oder Plug-Ins in Remote-Komponenten und Frameworks wiederholt eingeführt werden. Dieser Teil des Inhalts befindet sich noch in der praktischen Phase. Die Hauptidee besteht darin, die öffentliche Bibliothek in die Vue-Prototypenkette einzubinden, um die öffentliche Wiederverwendung der Komponenten Vue.prototype.$xxx zu realisieren.
// 全局添加 axios 对象 import axios from 'axios'; Vue.prototype.$http = axios;
Die eingeführte Remote-Komponente kann auf das öffentliche Paket im Framework zugreifen. Zu diesem Zeitpunkt muss Webpack so konfiguriert werden, dass der Code des öffentlichen Pakets beim Packen der Remote-Komponente nicht enthalten ist.
// webpack.sync-components.prod.conf.js 添加 externals: { vue: 'vue', 'element-ui': 'element-ui', axios: 'axios' }
Vermeiden Sie unnötige Anfragen, die durch mehrmaliges Aufrufen von Remote-Code wie v-for verursacht werden.
In diesem Teil verwenden wir direkt eine globale Variable als Wörterbuch, um ein Array mit Request Address: Data als Unterelementen zu speichern.
async mounted() { if (!this.url) return; // Cache 缓存 根据 url 参数 if (!window.SyncComponentCache) { window.SyncComponentCache = {}; } let res; if (!window.SyncComponentCache[this.url]) { window.SyncComponentCache[this.url] = Axios.get(this.url); res = await window.SyncComponentCache[this.url]; } else { res = await window.SyncComponentCache[this.url]; } let Fn = Function; this.mode = new Fn(`return ${res.data}`)(); console.log(this.mode); }
An diesem Punkt kann die asynchrone Remote-Komponente geladen und mit dem Framework kommuniziert werden.
Bitte besuchen Sie Github, um den Quellcode in diesem Artikel zu erhalten. Die Komponenten wurden für NPM freigegeben und können direkt installiert werden.
Verwandte Empfehlungen:
Detaillierte Erklärung zum Lesen oder Abrufen von Remote-Codeinstanzen in PHP
Ajax um eine Remote-Implementierung zu erreichen Kommunikation
Beispielfreigabe von PHP zur Beurteilung der Existenz von Remote-Dateien
Das obige ist der detaillierte Inhalt vonKomponentenfreigabe, die Vue-Remote-Code lädt. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!