首頁>技術>

上文中說到了利用Element-ui優化了導航欄,本節介紹抽離公共的less變數與利用Element-Ui實現登入註冊頁面。本專案git地址:

https://gitee.com/vuejslearn/news-list.git
抽離less,引入公共less變數

我們的樣式程式碼採用了less語法,因此很多地方可以封裝出一些共性的程式碼。比如佈局上,本專案的佈局採用了flex佈局。截止目前,我們發現頁面中的樣式程式碼有很多相同的flex佈局程式碼:

.flex-display (@dir: column, @content: center, @align: center) { display: flex; flex-direction: @dir; justify-content: @content; align-items: @align;}

如果把這些程式碼抽離出一個公共的檔案,那麼對於我們開發速度就會提高很多。那麼如何抽離呢?

很簡單,首先我們需要安裝style-resources-loader外掛:

npm install style-resources-loader --save

這個外掛是用來幫助我們注入公共的樣式檔案,匯入css / sass / scss / less / stylus這些內容,這樣可以避免我們在每個檔案裡使用import匯入。安裝完後,我們在vue.config.js中新增對樣式檔案的匯入。

首先在最上面引入path:

// 配置全域性less變數 chainWebpack: config => { const types = ['vue-modules', 'vue', 'normal-modules', 'normal'] types.forEach(type => addStyleResource(config.module.rule('less').oneOf(type))) }, css: { loaderOptions: { less: { javascriptEnabled: true } } }

在module.exports裡我們加入:

// 配置全域性less變數 chainWebpack: config => { const types = ['vue-modules', 'vue', 'normal-modules', 'normal'] types.forEach(type => addStyleResource(config.module.rule('less').oneOf(type))) }, css: { loaderOptions: { less: { javascriptEnabled: true } } }

然後在module.exports後面,我們加入方法:

function addStyleResource (rule) { rule.use('style-resource') .loader('style-resources-loader') .options({ patterns: [ // 需要全域性匯入的less路徑,自己修改 path.resolve(__dirname, './src/assets/styles/global.less') ] })}

ok,配置檔案寫好後,我們在上面配置的路徑裡(src/assets/styles),新增配置檔案global.less,檔案內容就是開頭的公共方法:

至此,公共的less抽離完成。我們在一般的頁面的使用方法和以前一樣,沒有任何變化,無需單獨引入這個樣式檔案即可使用。

Vuex持久化

vuex很好用,可以幫助我們記錄元件狀態,並且是響應式的。但是有個問題,就是它的狀態是儲存在記憶體裡的,當我們的瀏覽器重新整理後,狀態就重新初始化了。比如目前我們的程式碼中對登入狀態的記錄,就是。登陸後,我們再重新整理瀏覽器,發現有標記為未登入,這顯然不對。有沒有一種可能,將我們的狀態記錄到本地,然後重新整理後重新獲取呢?這樣就不怕重新整理了。答案是有的。很簡單,我們利用sessionStorage即可實現,那為什麼不用localStorage呢?因為前者是會話儲存,後者是本地儲存,前者當頁面關閉後會自動清除,後者不會。

因此我們保持登入狀態最好用前者。瀏覽器退出,或者關閉頁面,自動退出登入,比較好。

那具體怎麼做呢?很簡單我們只要在元件建立後,監聽重新整理事件,當重新整理前,我們持久化狀態到本地,然後重新整理完,元件重新建立,再把值從本地合併到vuex裡。

但是我們想讓全域性的元件都會這樣,那怎麼辦呢?很簡單,我們只需要在app中執行上面的步驟就可以了。

編輯App.vue,新增程式碼:

created () { // 在頁面載入時讀取sessionStorage裡的狀態資訊 if (sessionStorage.getItem('store')) { this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem('store')))) } // 在頁面重新整理時將vuex裡的資訊儲存到sessionStorage裡 window.addEventListener('beforeunload', () => { sessionStorage.setItem('store', JSON.stringify(this.$store.state)) }) }

這樣,在重新整理時,就可以自動的同步資料了。

Vuex多模組構建

目前的vuex是一個模組的,如果我們的應用比較大,把所有的狀態都寫在這個檔案裡,那樣會越來越臃腫。我們可以按照頁面、元件來分模組進行管理。然後都整合到vuex中即可。目前我們只有一個登入頁,因此我們建立一個登陸模組,來儲存登陸的狀態。

在store中,新建modules資料夾,進入後再建立login資料夾,進入後建立index.js。這個檔案用來管理登陸頁的狀態,把之前store/index.js的登入狀態移動到這裡:

login/index.js

匯出這些:

然後,我們去掉store/index.js中原有的登入狀態的程式碼,精簡後:

import Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)export default new Vuex.Store({ modules: {  })

ok,我們引入之前login的模組,並加入到modules中:

import Vue from 'vue'import Vuex from 'vuex'import login from './modules/login'Vue.use(Vuex)export default new Vuex.Store({ modules: { login }})

這樣,我們就成功地分了模組管理了。但是,我們仔細看,在login/index.js中,我們加了一句話:

namespaced: true,

這是什麼意思呢?這意思是,我們在每個模組裡,使用了名稱空間,使用了名稱空間,我們的模組就擁有了自己的action、mutation 和 getter 。如果沒有,那麼我們每建立一個模組,它的mutation等會註冊到全域性名稱空間,這樣其他模組,都能隨便的對這個mutation做操作。有了名稱空間,模組會更加的封閉,同時避免了衝突。

改變了vuex的多模組模式後,我們對登入狀態的操作就發生了變化。比如,我們用getters讀取login的狀態時,語句變成了:

this.$store.getters['login/login']

同時,我們也可以用mapGetters來簡化我們的操作:

import { mapGetters } from 'vuex'....computed: { ...mapGetters({ logined: 'login/login' }) },

這樣兩種方法,我們獲取到了某個模組下的狀態。同理,更改狀態的語句變成:

this.$store.dispatch('login/login')

以上的路徑,均是名稱空間+對應的getters或者mulation。

以上就是vuex的模組化管理,下篇文章我們將繼續在此基礎上,實現我們的登入註冊頁面,同時優化登入與非登陸狀態下路由的跳轉。先看一看登入、註冊完成後的樣子吧!

朋友們也可以直接下載程式碼執行,可以看到上面的頁面。


原創不容易,鑑於本人水平有限,文中如有錯誤之處歡迎大家指正。以後我會持續釋出vue實戰系列的文章,喜歡的朋友歡迎關注。

  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • Vue中路由導航 && 重定向 && 預設樣式