文章目录
- 自定义创建项目
- ESlint 代码规范
- vuex 概述
- 创建仓库
- 向仓库提供数据
- 使用仓库中的数据
- 通过store直接访问
- 通过辅助函数 mapState(简化)
- mutations传参语法(同步
- 实时输入,实时更新
- 辅助函数 mapMutations
- action (异步
- 辅助函数mapActions
- getters (类似于计算属性
- 通过store访问getters
- 通过辅助函数mapGetters映射
- 模块module
- 使用模块中的数据 / 模块中state的访问语法
- 直接通过模块名访问
- 通过mapState映射
- 默认根级别的映射 ...mapState(['user', 'setting'])
- 子模块映射 mapState('模块名',['xxx]) +开启命名空间
- 使用模块中getters中的数据 / 模块中getters的访问语法
- 直接通过模块名访问 $store.getters['模块名/xxx']
- 通过mapGetters映射
- 默认根级别映射mapGetters(['xxx'])
- 子模块映射mapGetters('模块名',['xxx'])+开启命名空间Son2.vue
- 掌握模块中的mutation调用语法
- 直接通过store调用 $store.commit('模块名/xxx',额外参数)
- 通过mapMutations映射
- 默认根级别映射mapMutations(['xxx'])
- 子模块映射mapMutations('模块名',['xxx'])+开启命名空间
- 直接通过模块名访问 $store.dispatch('模块名/xxx',额外参数)
- 通过mapActions映射
- 默认根级别映射mapActions(['xxx'])
- 子模块映射mapActions('模块名',['xxx'])+开启命名空间
自定义创建项目
vue create exp-mobile(项目名
2.选第三个,自定义
3.空格是选中
4.选vue 2.x
5.选择哈希
6.选择Less处理器
7.选择无分号规范
8.选择保存时校验
9.将配置文件放在单独文件中
小结
ESlint 代码规范
vuex 概述
创建仓库
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 = falsenew Vue({render: h => h(App),store //! !!!!// 仓库在所有组件都可以访问,用this.$store}).$mount('#app')
App.vue
created () {console.log(this.$store)}
向仓库提供数据
store/index.js
// 创建空仓库
const store = new Vuex.Store({// 通过state可以提供数据,所有组件共享的数据,任意组件都可以访问state: {title: 'hhhhh',count: 100}
})
使用仓库中的数据
通过store直接访问
components/Son2.vue
div class="box"><h2>Son2 子组件</h2>从vuex中获取的值:<label>{{$store.state.count}}</label><br /><button>值 - 1</button></div>
通过辅助函数 mapState(简化)
mapState把store中的数据
自动映射到组件的计算属性computed中
computed: {...mapState(['count', 'title'])},
App.vue 节选
<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'])},
# 组件(间接)修改仓库数据 mutation
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函数,第一个参数,都是stateaddCount (state) {state.count++}}
})export default store
App.vue
<span @click="handleAdd">count</span> <input type="text">methods: {handleAdd () {// 调用this.$store.commit('addCount')}},
mutations传参语法(同步
提交参数只能有一个,如果有多个参数,包装成一个对象传递
实时输入,实时更新
不能用v-model,因为vuex是单向数据流
但是v-model 等于 :value @input
App.vue
<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)}
store/index.js
changeTitle (state, newTitle) {state.title = newTitle}
辅助函数 mapMutations
把位于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)},
action (异步
辅助函数mapActions
把actions中的方法
提取出来,映射到组件methods
中
( …mapMutations([‘subCount’, ‘changeTitle’]),和 …mapActions([‘changeCountAction’]) 都在methods中
index.js
// action 处理异步// 不能直接操作state,操作state还是需要commit mutationactions: {// 此处未分模块,可当成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']) // !!!!}
getters (类似于计算属性
通过store访问getters
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)}}
Son1.vue
<hr>
<div>{{$store.state.list}}</div>
<div>{{ $store.getters.filterList }}</div>
通过辅助函数mapGetters映射
Son2.vue
<hr>
<div>{{ filterList }}</div>import { mapGetters } from 'vuex'computed: {...mapGetters(['filterList'])},
模块module
store/modules/user.js
const state = {userInfo: {name: 'slx',age: 18},score: 80
}
const mutations = {}
const actions = {}
const getters = {}export default {state,mutations,actions,getters
}
store/modules/setting.js
const state = {theme: 'light'
}
const mutations = {}
const actions = {}
const getters = {}export default {state,mutations,actions,getters
}
store/index.js
import setting from './modules/setting'modules: {user, setting}
使用模块中的数据 / 模块中state的访问语法
子模块的状态,还是会挂到根级别的state中,属性名就是模块名
直接通过模块名访问
Son1.js
<div>{{ $store.state.user.userInfo.name }}</div>
通过mapState映射
默认根级别的映射 …mapState([‘user’, ‘setting’])
Son2.js
<div>{{ user.userInfo.name }}</div>
<div>{{ setting.theme }}</div>
import { mapState } from 'vuex'computed: {...mapState(['user', 'setting']),},
子模块映射 mapState(‘模块名’,['xxx]) +开启命名空间
user.js
export default {namespaced: true,//开启命名空间state,mutations,actions,getters
}
Son2.vue
<div>{{ userInfo.name }}</div>
<div>{{ score }}</div>...mapState('user', ['userInfo', 'score']), //! !!!
使用模块中getters中的数据 / 模块中getters的访问语法
直接通过模块名访问 $store.getters[‘模块名/xxx’]
user.js
const getters = {// 分模块后,state就是子模块的stateUpperName (state) {return state.userInfo.name.toUpperCase()}
}
Son1.vue
<div>{{ $store.getters['user/UpperName'] }}</div>
通过mapGetters映射
默认根级别映射mapGetters([‘xxx’])
Son2.vue
<div>{{ filterList }}</div>...mapGetters(['filterList'])
store/index.js
getters: {// 注意点:// 1. 形参第一个参数,就是state// 2. 必须有返回值,返回值就是getters的值filterList (state) {return state.list.filter(item => item > 5)}},
子模块映射mapGetters(‘模块名’,[‘xxx’])+开启命名空间Son2.vue
<div>{{ UpperName }}</div>...mapGetters('user', ['UpperName']), //! !!!
掌握模块中的mutation调用语法
直接通过store调用 $store.commit(‘模块名/xxx’,额外参数)
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')},
通过mapMutations映射
默认根级别映射mapMutations([‘xxx’])
子模块映射mapMutations(‘模块名’,[‘xxx’])+开启命名空间
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里,不是computedmethods: {...mapMutations('setting', ['setSize']),...mapMutations('setting', ['setTheme'])}
## 模块中action的访问语法 ![在这里插入图片描述](https://img-blog.csdnimg.cn/ae6beb82840640eab8df3c6d8d540061.png)
直接通过模块名访问 $store.dispatch(‘模块名/xxx’,额外参数)
Son1.vue
<button @click="updateTheme2">一秒后更新</button>
methods: {updateTheme2 () {this.$store.dispatch('setting/setThemeSecond', 'orange')},
setting.js
const actions = {setThemeSecond (context, newTheme) {setTimeout(() => {// 调用mutation context上下文,默认提交的就是自己模块action和mutationcontext.commit('setTheme', newTheme)}, 1000)}
}
通过mapActions映射
默认根级别映射mapActions([‘xxx’])
子模块映射mapActions(‘模块名’,[‘xxx’])+开启命名空间
Son2.vue
<button @click="setThemeSecond('black')">一秒后更新主题</button>methods: {...mapActions('setting', ['setThemeSecond'])}