最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue動態(tài)加載異步組件的方法

 更新時間:2018年11月21日 15:09:41   作者:DanielDemi  
這篇文章主要介紹了Vue動態(tài)加載異步組件的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

背景:

目前我們項目都是按組件劃分的,然后各個組件之間封裝成產(chǎn)品。目前都是采用iframe直接嵌套頁面。項目中我們還是會碰到一些通用的組件跟業(yè)務之間有通信,這種情況下iframe并不是最好的選擇,iframe存在跨域的問題,當然是postMessage還是可以通信的,但也并非是最好的。目前有這么一個場景:門戶需要制作通用的首頁和數(shù)據(jù)概覽頁面,首頁和數(shù)據(jù)概覽頁面通過小部件來自由拼接。業(yè)務組件在制作的時候只需要提供各個模塊小部件的url就可以了,可是如果小部件之間還存在聯(lián)系呢?那么iframe是不好的。目前采用Vue動態(tài)加載異步組件的方式來實現(xiàn)小組件之間的通信。當然門戶也要提供一個通信的基線:Vue事件總線(空的Vue實例對象)。

內容:

使用過vue的都應該知道vue的動態(tài)加載組件components:

Vue通過is來綁定需要加載的組件。那么我們現(xiàn)在需要的就是如何打包組件,如果通過復制業(yè)務組件內部的代碼,那么這種就需要把依賴全部找齊,并復制過去(很多情況下會漏下某個圖片或css等),這種方式是比較low的,不方便維護。因此我們需要通過webpack來打包單個vue文件成js,這邊一個vue打包成一個js,不需壓代碼分割,css分離。因為component加載時只需要加載一個文件即可。打包文件配置如下:

首先在package.json加入打包命令:

"scripts": {
  ...
  "build-outCMP": "node build/build-out-components.js"
 },

Build-out-components.js文件:

'use strict'
require('./check-versions')()

process.env.NODE_ENV = 'production'

const ora = require('ora')
const path = require('path')
const chalk = require('chalk')
const webpack = require('webpack')
const webpackConfig = require('./webpack.out-components.prod.conf')

const spinner = ora('building for sync-components...')
spinner.start()

webpack(webpackConfig, function (err, stats) {
 spinner.stop()
 if (err) throw err
 process.stdout.write(stats.toString({
  colors: true,
  modules: false,
  children: false,
  chunks: false,
  chunkModules: false
 }) + '\n\n')

 if (stats.hasErrors()) {
  console.log(chalk.red(' Build failed with errors.\n'))
  process.exit(1)
 }

 console.log(chalk.cyan(' Build complete.\n'))
 console.log(chalk.yellow(
  ' Tip: built files are meant to be served over an HTTP server.\n' +
  ' Opening index.html over file:// won\'t work.\n'
 ))
})

webpack.out-components.prod.conf.js文件配置如下

const webpack = require('webpack');
const path = require('path');
const utils = require('./utils');
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
const {entry, mkdirsSync} = require('./out-components-tools')

function resolve(dir) {
 return path.join(__dirname, '..', dir)
}

mkdirsSync(resolve('/static/outComponents'))

module.exports = {
 entry: entry,
 output: {
  path: resolve('/static/outComponents'),
  filename: '[name].js',
 },
 resolve: {
  extensions: ['.js', '.vue', '.json'],
  alias: {
   'vue$': 'vue/dist/vue.esm.js',
   '@': resolve('src'),
  }
 },
 externals: {
  vue: 'vue',
  axios: 'axios'
 },
 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"'
  }),
  // UglifyJs do not support ES6+, you can also use babel-minify for better treeshaking: https://github.com/babel/minify
  new webpack.optimize.UglifyJsPlugin({
   compress: false,
   sourceMap: true
  }),
  // Compress extracted CSS. We are using this plugin so that possible
  // duplicated CSS from different components can be deduped.
  new OptimizeCSSPlugin({
   cssProcessorOptions: {
    safe: true
   }
  })
 ]
};

out-components-tools.js文件配置如下:

const glob = require('glob')
const fs = require('fs');
const path = require('path');
// 遍歷要打包的組件
let entry = {}
var moduleSrcArray = glob.sync('./src/out-components/*')
for(var x in moduleSrcArray){
 let fileName = (moduleSrcArray[x].split('/')[3]).slice(0, -4)
 entry[fileName] = moduleSrcArray[x]
}

// 清理文件
function mkdirsSync(dirname) {
 if (fs.existsSync(dirname)) {
  deleteall(dirname)
  return true;
 } else {
  if (mkdirsSync(path.dirname(dirname))) {
   fs.mkdirSync(dirname);
   return true;
  }
 }
}
// 刪除文件下的文件
function deleteall(path) {
 var files = [];
 if(fs.existsSync(path)) {
  files = fs.readdirSync(path);
  files.forEach(function(file, index) {
   var curPath = path + "/" + file;
   if(fs.statSync(curPath).isDirectory()) { // recurse
    deleteall(curPath);
   } else { // delete file
    fs.unlinkSync(curPath);
   }
  });
 }
};

exports.entry = entry
exports.mkdirsSync = mkdirsSync

build-out-components是打包的入口文件,webpack.out-components.prod.conf.js是webpack打包的配置文件,out-components-tools.js是工具庫,這邊是打包的entry自動獲?。J為src/out-components),還有自動刪除之前打包的文件。

目前的文件目錄為

通過打包生產(chǎn)文件:

在static下outComponents文件夾內的js文件。(最終打包需要打包到dist下面,這邊做測試先打包在static文件下,方便后續(xù)動態(tài)組件ajax獲取組件使用)

門戶的小部件是通過配置url,和調整布局來生產(chǎn)的。因此業(yè)務組件至此已經(jīng)完成了。只需要提供對門戶暴露的url即可。
接下來就是門戶這邊加載動態(tài)組件的實現(xiàn)了。門戶這邊就相對簡單了。看如下圖配置:

門戶通過component的動態(tài)組件來實現(xiàn)加載異步組件,通過ajax請求剛才打包的url,然后實例化函數(shù)new Function來賦值給mode(new Function之所以分成2部,是因此效驗規(guī)則的問題,可忽略)。這樣就實現(xiàn)了動態(tài)加載異步組件了。門戶和業(yè)務組件可以各個開發(fā),任何業(yè)務開發(fā)數(shù)據(jù)概覽,門戶都不需要改代碼,只需要界面上配置url即可。這個異步加載組件已經(jīng)結束了。這邊門戶需要封裝一封實現(xiàn)異步組件。父級只需要傳入url即可。這邊還有個可以優(yōu)化的是,可以把mode優(yōu)先緩存,那么不需要每次都去加載請求。如下:

我們可以看到在門戶的一個數(shù)據(jù)概覽頁面上加載了多個異步組件,那么異步組件之間也是可能存在通信的,這樣該如何做呢?因為現(xiàn)在已經(jīng)不是iframe嵌套了,可以通過監(jiān)聽一個組件,然調用另一個組件的方法,這樣確實可以實現(xiàn)平級組件間的通信,但這樣勢必不可取的,因為一旦這樣做了門戶必須要根據(jù)業(yè)務來輔助,修改代碼來實現(xiàn)功能。因此這邊借用門戶來生成vue事件總線(空的vue實例)來實現(xiàn)。

門戶代碼如下: 在this.$root上掛在一個事件總線:

 created () {
    if (!this.$root.eventBus) {
     this.$root.eventBus = new Vue()
    }
   }

然后業(yè)務組件之間就可以根據(jù)自己的業(yè)務實現(xiàn)通信:

組件一和組件二代碼如下:

 <template>
   <div class="test1">
    這是一個外部組件a1
    <hello-word></hello-word>
   </div>
    </template>
  
  <script>
  import helloWord from '../components/HelloWorld'
  export default {
   data () {
    return {
     i: 0
    }
   },
   components: {
    helloWord
   },
   mounted () {
    setInterval(() => {
     this.i++
     if (this.i < 10) {
      this.test()
     }
    }, 1000)
   },
   methods: {
    test () {
     this.$root.eventBus.$emit('childEvent', this.i)
    }
   }
  }
  </script>
 <template>
   <div class="test1">
    這也是外部組件哦
    <div >
     這是a1傳來的{{a1}}
    </div>
   </div>
  </template>
  
  <script>
  export default {
   data () {
    return {
     a1: 0
    }
   },
   created () {
    this.$root.eventBus.$on('childEvent', this.change)
   },
   methods: {
    change (i) {
     this.a1 = i
    }
   }
  }
  </script>

業(yè)務組件就可以根據(jù)this.$root.eventBus和vue上的事件傳遞($emit, $on)來實現(xiàn)相互的通信。

總結:本篇主要借助vue的動態(tài)組件和webpack打包單文件來實現(xiàn)動態(tài)加載異步組件,通過vue的事件總線掛載在this.$root上來實現(xiàn)平級組件之間的通信。

拓展方向:這個方式不僅僅可以應用在門戶單個頁面上的小部件上,同樣如果某個項目中的頁面文件需要復用時,不想通過代碼的復制,同樣可以再那個文件配置打包單文件配置,打包出的文件在領一個項目中動態(tài)加載出來即可。這種模式與通用組件的install模式是有點類似的,只是這個單文件vue不是通用的,但同樣可以達到打包復用頁面。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • 講解vue-router之什么是編程式路由

    講解vue-router之什么是編程式路由

    編程式路由在我們的項目使用過程中最常用的的方法了。這篇文章主要介紹了講解vue-router之什么是編程式路由,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • vue2中的keep-alive使用總結及注意事項

    vue2中的keep-alive使用總結及注意事項

    vue2.0提供了一個keep-alive組件用來緩存組件,避免多次加載相應的組件,減少性能消耗。本文給大家介紹vue2中的keep-alive使用總結及注意事項,需要的朋友參考下吧
    2017-12-12
  • vue使用html2canvas和jspdf將html轉成pdf

    vue使用html2canvas和jspdf將html轉成pdf

    在前端開發(fā)中, html轉pdf是最常見的需求,下面這篇文章主要給大家介紹了關于vue如何使用html2canvas和jspdf將html轉成pdf的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-03-03
  • vue 2.0 購物車小球拋物線的示例代碼

    vue 2.0 購物車小球拋物線的示例代碼

    本篇文章主要介紹了vue 2.0 購物車小球拋物線的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-02-02
  • VUE識別訪問設備是pc端還是移動端的實現(xiàn)步驟

    VUE識別訪問設備是pc端還是移動端的實現(xiàn)步驟

    經(jīng)常在項目中會有支持pc與手機端需求,并且pc與手機端是兩個不一樣的頁面,這時就要求判斷設置,下面這篇文章主要給大家介紹了關于VUE識別訪問設備是pc端還是移動端的相關資料,需要的朋友可以參考下
    2023-05-05
  • 基于vue實現(xiàn)分頁組件的示例代碼

    基于vue實現(xiàn)分頁組件的示例代碼

    分頁組件是一種用戶界面元素,用于在長列表或數(shù)據(jù)集中分割內容,分頁組件是每個開發(fā)人員必須掌握的一個組件,廣泛應用在各個場所,用以用戶方便閱讀等,本文就給大家介紹一下如何基于vue寫出的分頁組件,需要的朋友可以參考下
    2023-08-08
  • vue如何自定義按鈕單選和多選

    vue如何自定義按鈕單選和多選

    這篇文章主要介紹了vue如何自定義按鈕單選和多選問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Vue v2.4中新增的$attrs及$listeners屬性使用教程

    Vue v2.4中新增的$attrs及$listeners屬性使用教程

    這篇文章主要給大家介紹了關于Vue v2.4中新增的$attrs及$listeners屬性的使用方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。
    2018-01-01
  • Vue.js實現(xiàn)表格渲染的方法

    Vue.js實現(xiàn)表格渲染的方法

    今天小編就為大家分享一篇對Vue.js實現(xiàn)表格渲染的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • 圖文詳解如何在vue3+vite項目中使用svg

    圖文詳解如何在vue3+vite項目中使用svg

    SVG指可伸縮矢量圖形,用來定義用于網(wǎng)絡的基于矢量的圖形,下面這篇文章主要給大家介紹了關于如何在vue3+vite項目中使用svg的相關資料,需要的朋友可以參考下
    2021-11-11

最新評論

南丹县| 得荣县| 安多县| 宁武县| 福海县| 广东省| 湘潭县| 伊春市| 衡南县| 措美县| 甘孜县| 陈巴尔虎旗| 临海市| 托里县| 汉阴县| 溧水县| 永德县| 商河县| 定日县| 茂名市| 松潘县| 疏勒县| 安平县| 沂源县| 米易县| 德格县| 通化市| 杭州市| 临沂市| 淮阳县| 图们市| 大安市| 镇远县| 沅江市| 昌图县| 遂溪县| 新竹县| 通渭县| 南澳县| 沽源县| 竹溪县|