1. 程式人生 > 實用技巧 >vue開發中的"騷操作"

vue開發中的"騷操作"

前言

在與同事協作開發的過程中,見識到了不少“騷操作”。因為之前都沒用過,所以我願稱之為“高階技巧”!

Vue.extend

在互動過程中,有個需求就是點選圖示彈出相關資訊的彈窗,並且能夠同時開啟多個。這時就可以用Vue.extend方法手動掛載彈窗元件。

舉例:

// 目錄結構
/registry
    /videoDialog
        videoDialog.vue
        index.js
    /XXXDialog
        ···
    index.js

// videoDialog/index.js
import Vue from 'vue';
import videoDialog from 
'./videoDialog.vue'; const videoDialogConstructor = Vue.extend(videoDialog); function videoDialogInstance (data) { const dialogInstance = new videoDialogConstructor({ el: document.createElement('div'), data () ({ ...data }) }); document.body.appendChild(dialogInstance.$el); } export
default function videoDialogDom () { Vue.prototype.$videoDom = videoDialogInstance } /index.js import videoDialog from './videoDialog'; Vue.use(videoDialog); // 用法 // video.vue export default { method: { click() { this.$video(); } } }

在css中使用相對路徑

在vue專案中,通過在webpack配置檔案中配置alias屬性增加檔案路徑的別名

// webpack.config.js
resolve: {
    alias: {
        '@': resolve('src'),
        '@assets': resolve('src/assets')
    }
}

// 在js檔案中可以使用
import component from '@/component/xxx'

// 但是在css檔案中使用'@assets/images/xxx.png'卻會報錯
background-image: url(@assets/images/xxx.png)

在css檔案使用@assets/images/xxx.png的語法引用相對@assets的目錄會報錯。說明webpack沒有正確識別資源的相對路徑。

這是因為css檔案是被css-loader所處理,url()中的路徑會被css-loader視為絕對路徑。因為並沒有在css-loader中配置alias屬性,所以會找不到@assets

解決方法有兩種:

  • css-loader中配置alias,但是相同的別名卻要配置兩份,會顯得冗餘。
  • 在引用路徑之前新增~符號。background-image: url(~@assets/images/xxx.png);webpack會將以~符號作為字首的路徑視作依賴模組去解析,這樣alias配置就生效了。

同樣的方法也可以用於非JS檔案中。

自動載入模組

有些庫會在專案裡頻繁用到,比如說lodash。而每次使用都得引用一次import _ from 'lodash'麻煩的很!

有一個方法可以自動載入模組:使用ProvidePlugin

new webpack.ProvidePlugin({
  _: 'lodash',
  // ...
})

// 或者只使用單個方法
new webpack.ProvidePlugin({
  _map: ['lodash', 'map']
  // ...
})

任何時候,當_被當作未賦值的變數時,lodash就會自動被載入,並且_會被這個lodash輸出的內容所賦值。

指定vue的時候要注意, 對於ES2015模組的default export,必須指定模組的default屬性。

new webpack.ProvidePlugin({
  Vue: ['vue/dist/vue.esm.js', 'default']
})

公共元件、公共方法與公共指令的注入

在專案的開發中,一般都把重複使用的元件、方法抽象出來放到例如叫common的資料夾中。例如

/common
    /components
        index.js
    /utils
        index.js
    /directives
        index.js
    index.js

在前面這三個index.js檔案中,一般是export出各個型別的函式,例如:

// components/index,js
export { component1 } from './component1.vue'
export { component2 } from './component2.vue'

// utils/index.js
export { method1 } from './method1.js'
export { method2 } from './method2.js'

// directives/index.js
export { directive1 } from './directive1.js'
export { directive2 } from './directive2.js'

然後統一在第四個index.js中,暴露一個install方法,在install裡注入到全域性

import * as Directives from './directives';
import * as Components from './components';
import * as Utils from './utils';

export default {
    install: (Vue) => {
        for (let name of Object.keys(Components)) {
            Vue.component(Components[name]['name'], Components[name]);
        }
        for (let name in Directives) {
            Vue.directive(name, Directives[name]);
        }
        Object.assign(Vue.prototype.$utils ? Vue.prototype.$utils : {}, Utils);
    }
};

只需在main.js檔案中,使用vue.use方法

// main.js
import common from './common';
Vue.use(common);

乾淨利落!

Gzip加速

最後介紹一個外掛:CompressionWebpackPlugin。它可以提供gzip壓縮, 優化http請求, 提高載入速度。

// vue.config.js
const CompressionPlugin = require("compression-webpack-plugin"); 
configureWebpack:config => {
    if (process.env.NODE_ENV === 'production') {
         // 開啟gzip壓縮
        config.plugins.push(new CompressionPlugin({
            algorithm: 'gzip',
            test: /\.js$|\.css$/,
            threshold: 10240, // 對超過10k的資料進行壓縮
            cache: true, // 是否需要快取
            deleteOriginalAssets:false  // 不刪除原始檔
        }))
    }
}

作者: zhangwinwin
連結:vue開發中的"騷操作"
來源:github