上一章作了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