上一章作了node以及vue-cli3的配置,今天就來作vuex的部分。
先打開官方文檔-數據預取和狀態html
看完以後,發現大體的邏輯就是
利用mixin,攔截頁面渲染完成以前,查看當前實例是否含有'asyncData'函數(由你建立以及任意名稱),
若是含有就進行調用,而且傳入你須要的對象好比(store,route)vue
例子node
// pages/vuex/index.js export default { name: "vuex", asyncData({ store, route }) { // 觸發 action 後,會返回 Promise return store.dispatch('fetchItem', route.path) }, computed: { // 從 store 的 state 對象中的獲取 item。 item() { return this.$store.state.items[this.$route.path] } } } //mixin import Vue from 'vue'; Vue.mixin({ beforeMount() { const { asyncData } = this.$options if (asyncData) { this.dataPromise = asyncData({ store: this.$store, route: this.$route }) } } })
上面只是個大概的示例,下面開始正式來作吧。ios
先建立一些文件 src/store.config.js 跟router.config.js 同樣,在服務端運行避免狀態單例 src/pages/store/all.js 全局公共模塊
// src/pages/store/all.js const all = { //開啓命名空間 namespaced: true, //ssr注意事項 state 必須爲函數 state: () => ({ count:0 }), mutations: { inc: state => state.count++ }, actions: { inc: ({ commit }) => commit('inc') } } export default all;
all 單獨一個全局模塊
若是home有本身的數據,那麼就在home下 惰性註冊模塊
可是記得頁面銷燬時,也必定要銷燬模塊!!!
由於當屢次訪問路由時,能夠避免在客戶端重複註冊模塊。
若是想只有個別幾個路由共用一個模塊,
能夠在all裏面進行模塊嵌套,或者將這個幾個頁面概括到一個父級路由下 ,在父級實例進行模塊惰性註冊。git
// home/index.js import all from '../store/all.js'; export default { name: 'home', computed:{ count(){ return this.$store.state.all.count } }, asyncData({ store}){ store.registerModule('all',all); return store.dispatch('all/inc') }, data() { return { activeIndex2: '1', show:false, nav:[ { path:'/home/vue', name:'vue' }, { path:'/home/vuex', name:'vue-vuex' }, { path:'/home/vueCli3', name:'vue-cli3' }, { path:'/home/vueSSR', name:'vue ssr' } ] }; }, watch:{ $route:function(){ if(this.show){ this.show = false; } //切換路由時,進行自增 this.$store.dispatch('all/inc'); } }, mounted() { //作額外請求時,在mounted下進行 }, methods: { user_info(){ this.http.post('/cms/i1/user_info').then(res=> { console.log(res.data); }).catch( error => { console.log(error) }) } }, destroyed(){ this.$store.unregisterModule('all') } }
// store.config.js //store總配置 import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); //預請求數據 function fetchApi(id){ //該函數是運行在node環境 因此須要加上域名 return axios.post('http://localhost:8080/cms/i1/user_info'); } //返回 Vuex實例 避免在服務端運行時的單利狀態 export function createStore() { return new Vuex.Store({ state:{ items:{} }, actions: { fetchItem ({commit}, id) { return fetchApi(id).then(item => { commit('setItem',{id, item}) }) } }, mutations: { setItem(state, {id, item}){ Vue.set(state.items, id, item.data) } } }) }
在src下新建個methods 文件夾,這裏存放寫vue的全局代碼以及配置
獲取當前實例github
// src/methods/index.js import './mixin'; import Vue from 'vue'; import axios from 'axios'; Vue.prototype.http = axios; // src/methods/mixin/index.js import Vue from 'vue'; Vue.mixin({ beforeMount() { const { asyncData } = this.$options;//這裏 本身打印下就知道了。就不過多解釋了 //當前實例是否有該函數 if (asyncData) { // 有就執行,並傳入相應的參數。 asyncData({ store: this.$store, route: this.$route }) } } })
main.js 新增代碼vue-router
import Vue from 'vue'; Vue.config.productionTip = false; import VueRouter from 'vue-router'; import App from './App.vue'; + import './methods'; //同步路由狀態 + import { sync } from 'vuex-router-sync'; import { createRouter } from './router.config.js'; + import { createStore } from './store.config.js'; export function createApp() { const router = createRouter() const store = createStore() //同步路由狀態(route state)到 store sync(store, router) const app = new Vue({ router, + store, render: h => h(App) }) return { app, router, + store }; }
下面更新,開發環境部署相關vuex
項目github地址
項目公網地址vue-cli
1) vueSSR: 從0到1構建vueSSR項目 --- 初始化
2) vueSSR: 從0到1構建vueSSR項目 --- 路由的構建
3) vueSSR: 從0到1構建vueSSR項目 --- node以及vue-cli3的配置
4) vueSSR: 從0到1構建vueSSR項目 --- vuex的配置(數據預取)
5) vueSSR: 從0到1構建vueSSR項目 --- 開發環境的部署
6) vueSSR: 從0到1構建vueSSR項目 --- 僞熱更新axios