vuex
vue的数据传递是个高深的学问,数据传递得好,就不会重复请求,页面的体验感就好得飞起
常用的数据传递方式有
- 路由的参数(params / query)
- 父子组件的传递(props),隔代不能传,兄弟不能传
- 兄弟组件传递数据可以用eventBus,很好理解自行百度,
- vuex,数据管理
其中最好用的就是vuex
vuex相当于是一个全局的对象,所以在任何组件里都能获得他的值,修改他的值
vuex有五个核心对象
- state相当于data,是数据的存放对象
- getter是同步的去获取state的方法的存放对象
- actions是异步方法的存放对象
- mutations是在actions回调只有的同步的往state里存数据的方法的存放对象
- 还有一个modules是跟vuex一样的对象,理解为小vuex,他里面也有上面的四个对象,为了模块化好管理
开始
vuex的安装和引入自行百度
npm下载
main文件引入
main文件配置
我觉得直接上代码就能看懂
首先是创建文件夹store,红圈里的文件就各对应一个模块
index.js的代码
import Vue from 'vue'
import Vuex from 'vuex'
// 这个是必须要有的
import getters from './getters'
// 这个是user模块
import user from './modules/user'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
user
},
getters
})
export default store
getters.js
页面和组件就是通过这个getter去取值和修改数据的
const getters = {
// state是固定写法,如果没有模块,就不需要user直接state.xx
avatar: state => state.user.avatar,
name: state => state.user.name,
username: state => state.user.username
}
export default getters
user.js
import Vue from 'vue'
import { getInfo } from '@/api/user'
const state = {
username:'',
name: '',
avatar: '',
}
const mutations = {
// 在mutations里的方法是为了给state对象添加数据或者修改数据
// 第一个参数 state固定写法,第二个就是从actions方法里传来的参数
SET_NAME: (state, name) => {
// 添加数据,这个跟一些方法往data里添加数据一样
// 如果是state对象里没有声明的,需要用Vue.set,否则不会被监听
// 比如 Vue.set(state,"obj",obj);
// 这里不是vue的实例里,所以this是window,不能用this.set以及其他实例方法,所以需要在最上面先引入vue
state.name = name
},
SET_USERNAME: (state, username) => {
state.username = username
},
SET_AVATAR: (state, avatar) => {
state.avatar = avatar
}
}
const actions = {
// 获取用户详细信息的接口,用的是promise
// 这里的写法很固定,方法名getInfo最好跟请求方法getInfo一样,好找好理解
// actions里的方法有两个参数
// 第一个是带有commit和state的对象
// 第二个参数是来自外部调用的传参,只支持一个,所以是个对象最好,没有参数可以不写
getInfo({commit},opt) {
return new Promise((resolve, reject) => {
// 这个请求方式是外部引入的,下一篇讲
getInfo(opt).then(data => {
// data是接口返回的数据然后对象解构赋值
const { name, avatar,username} = data
// 用commit去执行mutations对象里的方法,第一个参数是方法名,第二个是参数,最好是对象
// 为什么方法名是全大写,规范,不是规定
commit('SET_NAME', name)
commit('SET_AVATAR', avatar)
commit('SET_USERNAME',username)
resolve(data)
}).catch(error => {
reject(error)
})
})
}
}
export default {
// 固定写法就行
namespaced: true,
// 因为getter是最外层的,这里就不用了
state,
mutations,
actions
}
怎么用
// 在某个vue文件里
<script>
// vuex的所有数据都存在【vuex / this.$store】这两个一样的对象里
// vuex的取值和执行方法的方式有很多,一般都是混合使用
// 这下面的四个映射对象一般只用mapGetters,其他几个不用
import { mapState,mapGetters,mapActions,mapMutations} from 'vuex';
export default {
data() {
return { ... }
},
computed:{
// 理解为固定写法也就是取值,没有顺序之分,一定写在computed里
// 写在这里就可以直接this.username取值了
...mapGetters(['user','username','avatar']),
// 如果命名冲突怎么改名
// ...mapGetters({newUser:user}),
// 也可以用 this.$store.getters.name
// 如果不用getter
// this.$store.state.user.name 也一样
},
methods:{
xx(){
// 如果需要同步修改stute的值,需要用commit
// 第一个参数就是【模块/方法名】,后面就是参数了
this.$store.commit('user/SET_NAME',this.name)
}
},
mounted(){
// 如果需要异步获取数据
// dispatch方法是指执行action异步方法
// 第一个参数就是【模块/方法名】,后面就是参数了
this.$store.dispatch('user/getInfo',data)
}
}
</script>
vuex的数据不能双向绑定
要双向绑定需要实时的commit
computed: {
check: {
set (value) {
this.$store.commit('xxx',value)
},
get(){
return this.$store.state.xx;
}
}
}