vuex

vue的数据传递是个高深的学问,数据传递得好,就不会重复请求,页面的体验感就好得飞起

常用的数据传递方式有

  1. 路由的参数(params / query)
  2. 父子组件的传递(props),隔代不能传,兄弟不能传
  3. 兄弟组件传递数据可以用eventBus,很好理解自行百度,
  4. vuex,数据管理

其中最好用的就是vuex
vuex相当于是一个全局的对象,所以在任何组件里都能获得他的值,修改他的值
vuex有五个核心对象

  1. state相当于data,是数据的存放对象
  2. getter是同步的去获取state的方法的存放对象
  3. actions是异步方法的存放对象
  4. mutations是在actions回调只有的同步的往state里存数据的方法的存放对象
  5. 还有一个modules是跟vuex一样的对象,理解为小vuex,他里面也有上面的四个对象,为了模块化好管理

开始
vuex的安装和引入自行百度
npm下载
main文件引入
main文件配置

我觉得直接上代码就能看懂
首先是创建文件夹store,红圈里的文件就各对应一个模块

image.png

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;
       }
    }
}
posted @ 2019-12-15 22:35  一个年轻淫  阅读(476)  评论(0编辑  收藏  举报