vuex高级用法

2 篇文章 0 订阅
  • state:vuex的基本数据,用来存储变量
  • geeter:(可以认为是store的计算属性)。就像计算属性一样,getter的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
  • mutation:提交更新数据的方法,必须是同步的(如果需要异步使用action)。
  • action:和mutation的功能大致相同,不同之处在于 Action 提交的是 mutation,而不是直接变更状态。 Action 可以包含任意异步或多个同步操作
  • modules:模块化vuex,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。

目录结构

  • store
    • actions
      • actions.js
    • mutations
      • mutations.js
    • getters
      • getters.js
    • state
      • state.js
    • modules
      • modules.js
    • index.js

代码展示

  • actions.js
/**
 * 1、参数说明
 * @store   是store对象,可以通过store.commit来调用mutations函数(简洁化:可以通过{commit}来解构出来使用)
 * @value   传递过来的参数(要改变的值)
 * 2、注意事项
 * 提交的是 mutation方法,而不是直接变更状态。
 * 不接受第3个参数,所以传多个参数的时候,把第二个写成对象传入
 * */

export default {
  // 改变登录状态函数
  changeLoginFn ({commit},value) {
    console.log(value)
    // 代替请求后台
    setTimeout(() => {
      commit('setLoginFn',value.status)
    }, 2000)
  }
}
  • mutations.js

/**
 * 1、参数说明
 * @state   定义好的变量(要修改的变量名,通过.XXX来获取)
 * @value   传递过来的参数(要改变的值)
 * 2、注意事项
 * 不接受第3个参数,所以传多个参数的时候,把第二个写成对象传入
 * */

export default {
  // 修改名称
  setNameFn(state, value) {
    state.name = value
  },
  // 修改登录状态
  setLoginFn(state, value){
    state.isLogin = value
    console.log(state.isLogin)
  }
}
  • getter.js
/**
 * 1、参数说明
 * @state   指定义好的变量(要修改的变量名,通过.XXX来获取)
 * @getters   可以调用所有getters方法
 * */

export default {
  // 拼接名称(以方法形式调用)
  getTodoById (state) {
    return (id) => {
      return state.name + state.name2 + id
    }
  },
  // 拼接名称(以变量名称来使用)
  setSpliceFn (state, getters,) {
    return  state.name + state.name2
  }
}
  • state.js
export default {
  name: '小鸡',
  name2: '啄米',
  isLogin: 1 // 1为登录 2为未登录
}
  • modules.js

/**
 * 1、属性说明
 * @namespaced  设置为true 的时候,模块的就是私有区域,(因为Vue 默认mutations,actions,getters 是全局区域)
 * 2、注意事项
 * 使用actions,想获取全局的mutations方法  参数上添加{root: true}属性 通过this['some/nested/module/foo']()来获取值  '/'
 * 可以拿到全局的state, 就是第3个参数rootState
 * (详情说明,请参考:https://vuex.vuejs.org/zh/guide/modules.html)
 * */
export default {
  // A模块
  a: {
    namespaced: true,
    state: {
      num: 1
    }
  },
  // B模块
  b: {
    state: {
      num: 1
    }
  }
  // 以此类推
  ....
}
  • index.js
import Vue from 'vue'
import Vuex from 'vuex'

// 引入Vuex 拆分文件
import state from "./state/state";
import mutations from "./mutations/mutations";
import actions from "./actions/actions";
import getters from "./getters/getters";
import modules from "./modules/modules";


Vue.use(Vuex)

var storePublics = {
  //strict: true,开启后,外部无法直接修改strict,限制开发人员从外部改变 (切记正式环境把它给关了 process.env.NODE_ENV)
  // 它是Vuex要定义的变量(也就是全局变量)
  state,
  // 它是处理同步,修改state 数据
  mutations,
  //  它是处理异步,或者多个同步的区域 使用dispatch来调用
  actions,
  // 它就像Vue组件里的computed 计算属性,有的时候后台返回来的数据,并不是我们想要的数据,我们需要处理或者拼接后使用,可能会多个组件使用。
  getters,
  //  这个是模块区分
  modules,
  // 自定义插件(可以)
  // plugins: [
  //   (store)=>{
  //     console.log(store)
  //     console.log('每次加载就回执行一次,可以做你想做的事情')
  //   }
  // ]
};



/**
 * 全局监听,页面刷新的时候将store里state的值存到sessionStorage中,然后从sessionStorage中获取,再赋值给store。
 * 然后再把session里面存的删除即可,相当于中间件的作用。
 */
//在页面加载时读取sessionStorage里的状态信息
if (sessionStorage.getItem("store")) {
  // console.log('刷新后')
  storePublics.state = JSON.parse(sessionStorage.getItem("store"))
  sessionStorage.removeItem("store")
}
//在页面刷新时将vuex里的信息保存到sessionStorage里
window.addEventListener("beforeunload", () => {
  // console.log('刷新前')
  sessionStorage.setItem("store",JSON.stringify(storePublics.state))
});

let store = new Vuex.Store(storePublics)

// 这里是store的生命周期,特殊需求的可用
store.watch((state)=>{
  state.name + state.name1
  console.log('当state值发生改变就会触发回调函数')
},()=>{
  console.log('回调函数')
})
store.subscribe((mutation,state)=>{
  console.log(mutation)
  console.log(mutation.payload)  // 每次传的参数
  console.log('每次调用mutations 都会执行这个函数')
})
store.subscribeAction((action, state) => {
    console.log(action)
    console.log(action.payload)
    console.log('监听action')
})

/**
 * 导出的方式:
 * 1、对象形式导出 export default store
 * 2、函数形式导出 export function createStore() {return store}
 * 区别:
 * 1、引入的时候不同。
 * 对象形式引入:import store from './store'
 * 函数形式引入:import { createStore } from './store'
 * 2、函数形式引入,主要是为了SSO服务端渲染使用
 * */
//

export function createStore() {
  return store
}
  • main.js
import Vue from 'vue'
import App from './App.vue'
import { createRouter } from './router'
import { createStore } from './store'


// 引入公共组件
import { publiceCom } from "./publiceComponent";
Vue.use(publiceCom);


import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);

// import '../theme/index.css'

Vue.config.productionTip = false;


export function createApp () {
  // 创建实例
  const router = createRouter();
  const store = createStore();

  const app = new Vue({
    router,
    store,
    // 根实例简单的渲染应用程序组件。
    render: h => h(App)
  });
  return { app ,router,store}
}


// new Vue({
//   router,
//   store,
//   render: h => h(App)
// }).$mount('#app')

使用方法

<template>
  <div class="home">
    <p >她的名称: {{name}} </p>
    <p>拼接的名称:{{setSpliceFn}}</p>
    <p>拼接的名称:{{getTodoById('haha')}}</p>
    <p>登录状态:{{isLogin}}</p>
    <el-button type="primary" @click="nameClickFn">改变名称</el-button>
    <!--    <button @click="nameSpliceFn">拼接名称</button>-->
    <el-button type="primary" @click="loginClickFn">请求后台切换登录状态</el-button>
  </div>
</template>

<script>
import {mapState,mapMutations,mapActions,mapGetters} from 'vuex'

export default {
  name: 'Home',
  data () {
    return {
      flagName: true,
    }
  },
  computed: {
  	// 一般放 state he getter 
    // 数组里面写的是变量名 (也可以写对象,键值,也可以接收的是函数)
    ...mapState(['name','isLogin']),
    // 注意,getter 在通过方法访问时,每次都会去进行调用,而不会缓存结果。
    ...mapGetters([
      'setSpliceFn',
      'getTodoById'
    ]),
  },
  methods: {
    // 对象就是函数
    ...mapMutations([
      'setNameFn', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
      'setLoginFn'
    ]),
    ...mapActions([
      'changeLoginFn'
    ]),
    // 更改名称
    nameClickFn() {
      this.flagName = !this.flagName
      if(this.flagName){
        this.setNameFn('小鸡  ');
      }else {
        this.setNameFn('小鸭')
      }
    },
    // 切换登录状态
    loginClickFn () {
      let value = {
        that: this,
        status: 2
      }
      this.changeLoginFn(value)
    },
  },
  mounted() {
    console.log(this.$store.state)
  }
}
</script>

<style scoped>
  #nav {
    padding: 30px;
  }
  #nav span {
    font-weight: bold;
    color: #2c3e50;
    cursor: pointer;
  }
  #nav span .active {
    color: #42b983;
  }
</style>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值