import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state = {
topics: [],
count: 0
}
const getters = {
getCount(state) {
return state.count
}
}
const actions = {
increment({
commit,
state
}) {
setTimeout(() => {
commit('INCREMENT', 1)
}, 1000)
},
decrement({
commit,
state
}) {
setTimeout(() => {
commit('DECREMENT', 1)
}, 1000)
}
}
const mutations = {
TOPICS_LIST: (state, topics) => {
state.topics = topics
},
INCREMENT: (state) => {
state.count++
},
DECREMENT: (state) => {
state.count--
}
}
export default new Vuex.Store({
state,
getters,
actions,
mutations
})
import Vue from 'vue'
import App from './App'
import store from './store'
import {
createRouter
} from './router'
import {
sync
} from 'vuex-router-sync' // 取得route状态
export function createApp() {
// 创建 router 实例
const router = createRouter()
sync(store, router)
const app = new Vue({
// 注入 router 到根 Vue 实例
router,
store,
render: h => h(App)
})
// 返回 app 和 router
return {
app,
router,
store
}
}
<template>
<div>
<button @click='increment'>Increment +1</button>
<button @click='decrement'>Decrement -1</button>
<h3>Count is </h3>
<router-link to="/">Home</router-link>
</div>
</template>
<script>
import { mapGetters, mapActions } from 'vuex'
export default {
data() {
return {
res: [1, 2, 3, 4]
}
},
methods: {
...mapActions(['increment', 'decrement']),
asy: function() {
return new Promise((resolve, reject) => {
setTimeout(n => {
console.log(new Date())
resolve()
}, 5000)
})
},
fasdf: async function() {
await this.asy()
}
},
computed: {
...mapGetters(['getCount'])
},
created() {
this.fasdf()
if (this.res.includes(1)) {
console.log(123)
}
}
}
</script>
<style>
body {
}
</style>
import {
createApp
} from './main'
const {
app,
router,
store
} = createApp()
// 统一客户端与服务器端的store
if (window.__INITIAL_STATE__) {
store.replaceState(window.__INITIAL_STATE__)
}
// 因为可能存在异步组件,所以等待router将所有异步组件加载完毕,服务器端配置也需要此操作
router.onReady(() => {
router.beforeResolve((to, from, next) => {
const matched = router.getMatchedComponents(to)
const prevMatched = router.getMatchedComponents(from)
let diffed = false
const activated = matched.filter((c, i) => {
return diffed || (diffed = (prevMatched[i] !== c))
})
if (!activated.length) {
return next()
}
// start loading indicator
Promise.all(activated.map(c => {
if (c.asyncData) {
return c.asyncData({
store,
route: to
})
}
})).then(() => {
// stop loading indicator
next()
}).catch(next)
})
app.$mount('#app')
})
// entry-server.js
import { createApp } from './main'
export default context => {
// 因为有可能会是异步路由钩子函数或组件,所以我们将返回一个 Promise,
// 以便服务器能够等待所有的内容在渲染前,
// 就已经准备就绪。
return new Promise((resolve, reject) => {
const { app, router, store } = createApp()
// 设置服务器端 router 的位置
router.push(context.url)
// 等到 router 将可能的异步组件和钩子函数解析完
router.onReady(() => {
const matchedComponents = router.getMatchedComponents()
// 匹配不到的路由,执行 reject 函数,并返回 404
if (!matchedComponents.length) {
// eslint-disable-next-line
return reject({ code: 404 })
}
// Promise 应该 resolve 应用程序实例,以便它可以渲染
Promise.all(matchedComponents.map(Component => {
if (Component.asyncData) {
return Component.asyncData({
store,
route: router.currentRoute
})
}
})).then(() => {
context.state = store.state
resolve(app)
}).catch(reject)
}, reject)
})
}