vue.js+vue-router创建单页运用
一、安装
npm install vue-router
二、router的运用
1. 在子组件中监听路由变化
export default {
name: 'app',
computed:mapGetters(['loading','shownav']),
//监听路由的变化
watch:{
$route(to,from){
console.log(to);
console.log(from);
}
},
components:{
}
}
路由信息对象:$route(只读不可变的,可通过watch检测其变化)
表示当前激活的路由的状态信息,包含了当前url解析得到的信息以及url匹配到的路由记录
路由信息对象出现在多个地方:
路由信息对象的属性
三、vuex
1. 安装vuex
Vuex的状态存储是响应的。组件从store中读取状态,若store中的状态发生变化,那么相应的组件也会得到高效更新
//安装
npm install vuex --save
在一个模块化的打包系统中,您必须显式地通过 Vue.use() 来安装 Vuex:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
2. 创建一个store
另外创建一个目录进行Vuex状态的存储
// 如果在模块化构建系统中,请确保在开头调用了 Vue.use(Vuex)
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
}
})
Vuex通过store选项,提供一种机制状态从根组件注入到每个子组件中(需在根实例中注册store)
Vue.use(Vuex) //注册store前需要进行Vuex的引用
const app = new Vue({
el: '#app',
// 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
store,
components: { Counter }
})
子组件可通过this.$store访问store状态
const Counter = {
template: `{{ count }}`,
computed: {
count () {
return this.$store.state.count
}
}
}
3. 在Vue组件中获得Vuex状态
从store实例中读取状态:
每次状态变化的时候,都会重新求取计算属性,并且触发更新相关联的DOM
const Counter = {
template: `{{ count }}`,
computed: {
count () {
return this.$store.state.count
}
}
}
当一个组件需要获取多个状态的时候,可使用mapState辅助函数帮助我们生成计算属性
当映射的计算属性的名称与state的子节点名称相同时,我们也可以给mapState传一个字符串数组
4. 从store中的state中派生出一些状态 -- getter
getter可相当于store的计算属性,会根据依赖性被缓存起来
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: state => { //箭头语法:左侧是参数,右侧是函数的返回值
return state.todos.filter(todo => todo.done) //filter是array内置的函数,其必要参数是一个函数,根据函数返回的布尔值进行筛选
}
}
})
mapGetters辅助函数
使用对象展开运算符将getter混入computed对象中:
5. 更改Vuex的store中的状态的唯一方法是提交Mutation
注意:mutation必须是同步函数
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
// 变更状态
state.count++
}
}
})
store.commit('increment')
大多数情况下,载荷应该是一个对象,包含多个字段并
store.commit('increment', {
amount: 10
})
//对象风格的提交方式
store.commit({
type: 'increment',
amount: 10
})
在组件中使用this.$store.commit('xxx')提交mutation
使用mapMutations辅助函数将组件中的method映射为store.commit调用
import { mapMutations } from 'vuex'
export default {
// ...
methods: {
...mapMutations([
'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
// `mapMutations` 也支持载荷:
'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)`
]),
...mapMutations({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
})
}
}
6. Action
Action类似Mutation,action提交的是mutation而不是直接变更状态,action包含任何异步操作
Action函数,接受一个参数,该参数是一个对象,与store实例具有相同方法和属性
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})
// 以载荷形式分发
store.dispatch('incrementAsync', {
amount: 10
})
// 以对象形式分发
store.dispatch({
type: 'incrementAsync',
amount: 10
})
在组件中使用this.$store.dispatch('xxx')分发action,或者使用mapActions辅助函数将组件methods映射为dispatch调用
7. Module
Vuex允许将store分割成模块,每个模块拥有自己的state、mutation、action等
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
可以通过添加 namespaced: true的方式使其成为命名空间模块。当模块被注册后,它的所有getter、action及mutation都会根据模块注册的路径调整命名
const store = new Vuex.Store({
modules: {
account: {
namespaced: true,
// 模块内容(module assets)
state: { ... }, // 模块内的状态已经是嵌套的了,使用 `namespaced` 属性不会对其产生影响
getters: {
isAdmin () { ... } // -> getters['account/isAdmin']
},
actions: {
login () { ... } // -> dispatch('account/login')
},
mutations: {
login () { ... } // -> commit('account/login')
},
// 嵌套模块
modules: {
// 继承父模块的命名空间
myPage: {
state: { ... },
getters: {
profile () { ... } // -> getters['account/profile']
}
},
// 进一步嵌套命名空间
posts: {
namespaced: true,
state: { ... },
getters: {
popular () { ... } // -> getters['account/posts/popular']
}
}
}
}
}
})