vue create exp-mobile(项目名
2.选第三个,自定义
3.空格是选中
5.选择哈希
6.选择Less处理器
store/index.js
// 这里存放的就是vuex相关的核心代码
import Vue from 'vue'
import Vuex from 'vuex'
// 插件安装
Vue.use(Vuex)
// 创建空仓库
const store = new Vuex.Store()
// 导出给main.js
export default store
main.js
import Vue from 'vue'
import App from './App.vue'
import store from './store'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
store //! !!!!
// 仓库在所有组件都可以访问,用this.$store
}).$mount('#app')
App.vue
created () {
console.log(this.$store)
}
// 创建空仓库
const store = new Vuex.Store({
// 通过state可以提供数据,所有组件共享的数据,任意组件都可以访问
state: {
title: 'hhhhh',
count: 100
}
})
div class="box">
<h2>Son2 子组件</h2>
从vuex中获取的值:<label>{{$store.state.count}}</label>
<br />
<button>值 - 1</button>
</div>
mapState把store中的数据
自动映射到组件的计算属性computed中
computed: {
...mapState(['count', 'title'])
},
<template>
<div id="app">
<h1>根组件{{ $store.state.title }}</h1>
<!-- 3.用了 mapState ,就直接简写 -->
<h1>根组件{{ title }}</h1>
<input type="text">
<Son1></Son1>
<hr>
<Son2></Son2>
</div>
</template>
<script>
import Son1 from './components/Son1.vue'
import Son2 from './components/Son2.vue'
// 1.导入
import { mapState } from 'vuex'
console.log(mapState(['count', 'title']))
export default {
name: 'app',
// 2.展开运算符进行映射
computed: {
...mapState(['count', 'title'])
},
store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
strict: true,
state: {
title: 'hhhhh',
count: 100
},
// 通过mutations可以提供修改数据的方法
mutations: {
// 所有mutations函数,第一个参数,都是state
addCount (state) {
state.count++
}
}
})
export default store
App.vue
<span @click="handleAdd">count</span> <input type="text">
methods: {
handleAdd () {
// 调用
this.$store.commit('addCount')
}
},
不能用v-model,因为vuex是单向数据流
但是v-model 等于 :value @input
<input :value="title" @input="handleInput" type="text">
handleInput (e) {
// 1.实时获取输入框的值
console.log(e.target.value)
// 2.提交mutation,调用mutation函数
this.$store.commit('changeTitle', e.target.value)
}
changeTitle (state, newTitle) {
state.title = newTitle
}
把位于mutations中的方法
提取出来,映射到methods中
store/index.js
const store = new Vuex.Store({
strict: true,
state: {
title: 'hhhhh',
count: 100
},
// 通过mutations可以提供修改数据的方法
mutations: {
subCount (state, n) {
state.count -= n
},
changeTitle (state, newTitle) {
state.title = newTitle
},
changeCount (state, tt) {
state.count = tt
}
}
})
Son1.vue
<button @click="handleSub(10)">值 - 10</button>
<button @click="handleSub(20)">值 - 20</button>
<button @click="handleSub(30)">值 - 30</button>
<!-- 更简单的写法,连外面的函数都不套了 -->
<button @click="subCount(2)">值 - 2</button>
<br>
<button @click="changeTitle('qqq')">改成【qqq】标题</button>
...mapMutations(['subCount', 'changeTitle']),
handleSub (tt) {
this.subCount(tt)
},
把actions中的方法
提取出来,映射到组件methods
中
( …mapMutations([‘subCount’, ‘changeTitle’]),和 …mapActions([‘changeCountAction’]) 都在methods中
index.js
// action 处理异步
// 不能直接操作state,操作state还是需要commit mutation
actions: {
// 此处未分模块,可当成store仓库
// context.commit('mutation名字',额外参数)
changeCountAction (context, num) {
// 这里是setTime模拟异步,以后大部分场景是发请求
setTimeout(() => {
context.commit('changeCount', num)
}, 2000)
}
}
Son2.vue
<button @click="changeCountAction(0)">2秒后改成count=0</button>
methods: {
changeTitle () {
this.$store.commit('changeTitle', 'sssss')
},
...mapActions(['changeCountAction']) // !!!!
}
store/index.js
state: {
title: 'hhhhh',
count: 100,
list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
},
// 类似于计算属性
getters: {
// 注意点:
// 1. 形参第一个参数,就是state
// 2. 必须有返回值,返回值就是getters的值
filterList (state) {
return state.list.filter(item => item > 5)
}
}
<hr>
<div>{{$store.state.list}}</div>
<div>{{ $store.getters.filterList }}</div>
Son2.vue
<hr>
<div>{{ filterList }}</div>
import { mapGetters } from 'vuex'
computed: {
...mapGetters(['filterList'])
},
const state = {
userInfo: {
name: 'slx',
age: 18
},
score: 80
}
const mutations = {}
const actions = {}
const getters = {}
export default {
state,
mutations,
actions,
getters
}
const state = {
theme: 'light'
}
const mutations = {}
const actions = {}
const getters = {}
export default {
state,
mutations,
actions,
getters
}
import setting from './modules/setting'
modules: {
user, setting
}
子模块的状态,还是会挂到根级别的state中,属性名就是模块名
Son1.js
<div>{{ $store.state.user.userInfo.name }}</div>
Son2.js
<div>{{ user.userInfo.name }}</div>
<div>{{ setting.theme }}</div>
import { mapState } from 'vuex'
computed: {
...mapState(['user', 'setting']),
},
user.js
export default {
namespaced: true,//开启命名空间
state,
mutations,
actions,
getters
}
Son2.vue
<div>{{ userInfo.name }}</div>
<div>{{ score }}</div>
...mapState('user', ['userInfo', 'score']), //! !!!
user.js
const getters = {
// 分模块后,state就是子模块的state
UpperName (state) {
return state.userInfo.name.toUpperCase()
}
}
Son1.vue
<div>{{ $store.getters['user/UpperName'] }}</div>
Son2.vue
<div>{{ filterList }}</div>
...mapGetters(['filterList'])
getters: {
// 注意点:
// 1. 形参第一个参数,就是state
// 2. 必须有返回值,返回值就是getters的值
filterList (state) {
return state.list.filter(item => item > 5)
}
},
<div>{{ UpperName }}</div>
...mapGetters('user', ['UpperName']), //! !!!
setting.js
const mutations = {
setTheme (state, newtheme) {
state.theme = newtheme
}
}
export default {
namespaced: true,
state,
mutations,
actions,
getters
}
Son1.vue
<div>{{ $store.state.setting.theme }}</div>
<button @click="changeTheme">改主题色</button>
changeTheme () {
this.$store.commit('setting/setTheme', 'dark')
},
setting.js
const state = {
theme: 'light',
size: 16
}
const mutations = {
setTheme (state, newtheme) {
state.theme = newtheme
},
setSize (state, newSize) {
state.size = newSize
}
}
Son2.vue
<div>{{$store.state.setting.size}}px</div>
<button @click="setSize(90)">改px</button>
//真的注意,放在methods里,不是computed
methods: {
...mapMutations('setting', ['setSize']),
...mapMutations('setting', ['setTheme'])
}
Son1.vue
<button @click="updateTheme2">一秒后更新</button>
methods: {
updateTheme2 () {
this.$store.dispatch('setting/setThemeSecond', 'orange')
},
const actions = {
setThemeSecond (context, newTheme) {
setTimeout(() => {
// 调用mutation context上下文,默认提交的就是自己模块action和mutation
context.commit('setTheme', newTheme)
}, 1000)
}
}
Son2.vue
<button @click="setThemeSecond('black')">一秒后更新主题</button>
methods: {
...mapActions('setting', ['setThemeSecond'])
}