mixin 內容
這裡是以前的習慣養成的,其實不一定是個好作法,我會將某些 .vue 裡面,可以共用的 method 或是某些比較獨立的 method 抽出來另外做成 mixin 然後在 import 來用,雖然立意良好,但實際執行上,有時會變成把一個很大的 .vue 檔抽出部分 method 放去 mixin 來使用。
pages 內容
這裡才是放我主要網站頁面架構的 vue 元件,目前分成四個目錄以及一個 Home.vue 與 App.vue 檔
App.vue
這是原本專案建立時產生的 vue 檔,基本上所有內容都在從這裡面產生,底下的範例雖然會透過判斷 getLoading
來切換 loading 與顯示畫面,不過我後來實際開發時,把每個頁面或是每個區塊 loading 又另外做處理,所以最外層這個 loading 就沒再用了
<template> <div v-if="getLoading" class="ui active inverted dimmer"> <div class="ui text loader">Loading</div> </div> <router-view class="body" /> </template>
<script> import { mapGetters } from 'vuex'
export default { name: 'App', data () { return { } }, computed: { ...mapGetters([ 'getLoading' ]) }, created () { console.log('App created') }, mounted () { } } </script>
<style lang="sass"> .body margin: 0 padding: 0 width: 100% height: 100% </style>
|
整個 App.vue 裡面主要就放一個 <router-view />
,讓 vue-router 來處理要渲染的內容,一開始的頁面是根目錄 /
,所以會依據 routes 裡設定 path 為 /
來載入頁面,而這頁就是 Home.vue,所以簡單來說 App.vue 就是包住整個 route 要渲染的內容,而一開始渲染 /
這個路徑的檔案
router 內容
這部分才是重點之一,畢竟過去開發 vue.js 的經驗都是某個頁面內需要複雜操作的時候,才將該區塊改寫成 vue.js,然後載入頁面的時候一起把 build 好的 js 載入使用,而這次真的要靠 vue.js 來架構整個網站的路徑,所以也是第一次學習怎麼寫前端 route
使用 vue-router Vue.js 官方的路由管理器,底下例子會用到
- HTML5 History Mode
- Nested Routes 嵌套路由
- Route Meta Fields(路由元信息) 用來判斷是否需要驗證用戶登入狀態
- Navigation Guards 的 Global Guards,用來作用戶登入檢查
import Vue from 'vue' import Router from 'vue-router'
import store from '../store/index'
import Home from '@/pages/Home' // Auth: Login, ResetPassword import Login from '@/pages/auth/login' // Product Page import Products from '@/pages/products/products-root' import ProductsWeekly from '@/pages/products/products-weekly' import ProductsMonthly from '@/pages/products/products-monthly' Vue.use(Router) const router = new Router({ mode: 'history', routes: [ { path: '/', name: 'Home', component: Home, meta: { requiresAuth: true }, children: [ { path: 'products', name: 'Products', component: Products, meta: { requiresAuth: true }, children: [ { path: 'weekly', name: 'ProductsWeekly', component: ProductsWeekly, meta: { requiresAuth: true } }, { path: 'monthly', name: 'ProductsMonthly', component: ProductsMonthly, meta: { requiresAuth: true } } ] } ] }, { path: '/login', name: 'Login', component: Login, meta: { requiresAuth: false } },
// 當 url path 不符合 router 表的時候,預設轉址到 // 順序一定要最後面 { path: '/*', redirect: '/login' } ] })
const isLogged = function () { let storeLoggedIn = store.getters.getLoggedIn let sessionLoggedIn = sessionStorage.getItem('LoggedIn') return storeLoggedIn || sessionLoggedIn }
router.beforeEach((to, from, next) => { console.log('to=', to.fullPath, '| from=', from.fullPath) if (to.matched.some(record => record.meta.requiresAuth) && !isLogged()) { // 如果 router 轉跳的頁面需要驗證 requiresAuth: true // 尚未登入時,導向 login 頁面, 網址帶入 redirect,以便登入後重新導向 next({ path: '/login', query: { redirect: to.fullPath } }) } else { next() // 往下繼續執行 } })
export default router
|
store 內容
這也是主要重點之一,Vue.js 的狀態管理模式 vuex 相關的檔案都放在這邊了,開發過程中需要搭配 devtools extension 的 Chrome 插件來使用,包保事半功倍
目錄結構
目前的目錄結構如下,為了功能細分,所以有拆出 modules,以及 root.js 來放切換語系等功能
src/store ├── index.js ├── modules │ ├── auth.js │ ├── notify.js │ ├── orders.js │ ├── products.js │ ├── resources.js │ └── token.js └── root.js
|
index.js
index.js 的內容大致如下:
import Vue from 'vue' import Vuex from 'vuex' // root import { state, actions, mutations, getters } from './root.js' // modules import auth from './modules/auth' import products from './modules/products' Vue.use(Vuex) const debug = process.env.NODE_ENV !== 'production' export default new Vuex.Store({ // root state, actions, mutations, getters, // 整理過的 modules modules: { auth, products, }, strict: debug })
|
root.js
而 root.js 放了些 global 使用的 state 與比較重要的語系切換設定,這裡只列出切換語言的相關程式碼
// 為了設定語系引入 Vue import i18n from '@/i18n' export const types = { SET_LANGUAGE: 'SET_LANGUAGE', } export const state = { lang: localStorage.getItem('LANGUAGE') || 'zh-TW' } export const getters = { getLanguage: state => state.lang, } export const actions = { setLanguage ({ commit }, lang) { commit(types.SET_LANGUAGE, lang) }, } export const mutations = { [types.SET_LANGUAGE] (state, setlang) { state.lang = setlang localStorage.setItem('LANGUAGE', setlang) // 改變全域語系設定 i18n.locale = state.lang } }
|
所以在 vue component 切換語系時,只要呼叫 setLanguage
就好
changeLanguage (value) { this.$store.dispatch('setLanguage', value) }
|
modules
而其他 store 模組,大致上如下:
const state = { payload: null } const getters = { getPayload: state => state.payload } const actions = { acitonName ({ commit }, payload) { commit(mutationFunc, payload) } } const mutations = { mutationFunc (state, payload) { state.payload = payload }, } export default { state, getters, actions, mutations }
|
雖然看起來都只是把寫過的 code 貼上來,畢竟也是當初花了不少時間寫的,雖然有資料可以參考,參考的資料都是比較精簡的,真的要應用到專案裡,還是有很多需要自己調整的部分,做這個紀錄也只是為了之後有跡可循可以自己參考用
未完…待續….