[TOC] ## :-: 添加vuex ``` $ vue add vuex -- 集中式存储管理 ``` ***** ## :-: 项目运用 :-: main.js ``` import Vue from 'vue' import App from './App.vue'; import router from './router.js'; import './plugins/axios'; //在这里引入 bootstrap。默认只引入 bootstrap 中的 js,css 需要另外引入,我的 bootstrap.ss 在APP.vue中引入的 import "bootstrap"; //也可以在这里引入 bootstrap.css ; import "bootstrap/dist/css/bootstrap.min.css"; import x2js from 'x2js' //xml数据处理插件 // vue add vuex -- 数据仓库 import store from './store' Vue.config.productionTip = false; Vue.prototype.$x2js = new x2js() //创建x2js对象,挂到vue原型上 // 全局守卫 (main.js) // 进页面前触发 router.beforeEach((to, from, next) => { // if (['student', 'academic'].includes(to.name)) return; // some every let needLogin = to.matched.some(ele => ele.meta && ele.meta.login === true); if (needLogin) { // 判断是否需要登陆 let isLogin = document.cookie.includes('login=true'); if (isLogin) { next(); } else { isLogin = window.confirm('该页面需要登陆后才能访问 ~'); if (isLogin) { next('/login'); } // 需要登陆 } } else { next(); } }); // // 解析完毕执行 // router.beforeResolve((to, from, next) => { // // to and from are both route objects. must call `next`. // // next(); // }) new Vue({ router, store, render: h => h(App) }).$mount('#app'); ``` :-: **store.js** ``` // store.js -- 相当于是一个数据存储的仓库 import Vue from 'vue'; import Vuex from 'vuex'; // import learn from './store/learn'; Vue.use(Vuex); // $store state $store.state // this.$store.state.xxx // mapState([]) mapState({}) export default new Vuex.Store({ // strict -- 开启严格模式 (在不为生产模式的时候开启,上线后最好关掉) // strict: process.env.NODE_ENV !== 'production', strict: false, // state -- 用于存储数据、 state: { // const nowAdd: {}, tableData: [] }, // 模块 modules: { abc: { state: {}, getters: {}, mutations: {}, actions: {} }, learn }, // getters -- 用于计算属性、 getters: { // 类似于计算属性、 // 映射 在标签中通过 $store.getters.person 拿到数据、 person(state) { // console.log(state); return `姓名:${state.nowAdd.name} 年龄:${state.nowAdd.age}`; } }, mutations: { // 只能执行同步的 // 改变vuex中的状态 // 用法 this.$store.commit('xxx') // mapMutations(['xxx']) // mapMutations({newXXX:'xxx'}) addTableData(state, obj) { // console.log(state, obj); state.tableData.push(obj); } }, actions: { // 能够执行异步 // 提交mutations,让mutations去更改状态、 // 要用到异步时,使用actions // 用法 this.$store.dispatch('xxx') // mapActions(['xxx']) // mapActions({newXXX:'xxx'}) addTableData({ commit }, payload) { setTimeout(() => { commit('addTableData', payload) }, 1000); } } }) ``` ***** :-: ./Student.vue ``` <template> <div class="student"> <div class="panel panel-default"> <div class="panel-heading" style="background-color:#fff;"> <!-- add-student --> <add-student /> </div> <!-- Table --> <student-list /> </div> </div> </template> <script> import addStudent from "@/components/Student/AddStudent"; import studentList from "@/components/Student/StudentList"; export default { components: { addStudent, studentList } }; </script> ``` :-: ./Student/AddStudent.vue ``` <template> <div class="add-student" style="max-width: 300px;"> <div class="form-group"> <label for="exampleInput_sd41f">姓名:</label> <input class="form-control" id="exampleInput_sd41f" v-model="nowAdd.name" placeholder="张三" /> </div> <div class="form-group"> <label for="exampleInput_sdi25">年龄:</label> <input class="form-control" id="exampleInput_sdi25" v-model="nowAdd.age" placeholder="18" /> </div> <button class="btn btn-default" @click="addRow({name:nowAdd.name,age:nowAdd.age})">添加</button> </div> </template> <script> import { mapState, mapMutations, mapActions } from "vuex"; // console.log(mapState(["name", "age", "look"])); // this.$store.state.nowAdd = {}; export default { methods: { ...mapMutations(["addTableData"]), // ...mapActions(["addTableData"]), addRow(obj) { // 更新视图数据、 this.$set(this.nowAdd, "name", ""); this.$set(this.nowAdd, "age", ""); if (!obj.name && !obj.age) return; obj.id = +new Date(); // console.log(obj); // this.$store.state.tableData.push(obj); // this.$store.commit("addTableData", obj); this.addTableData(obj); // 异步 // this.$store.dispatch("addTableData", { obj, name: "abc" }); // this.addTableData(obj); } }, // 计算属性 computed: { // ES7 - 点点点运算符 ...mapState(["nowAdd"]) // ...mapState(["age"]), // ...mapState({ // // 自定义命名 // myName: state => state.name // }) } }; </script> ``` :-: ./Student/StudentList.vue ``` <template> <div class="Student-list"> <!-- Table --> <!-- v-if="(tableData.length||name||age)" --> <table class="table" style="margin:0;"> <thead> <tr> <th style="width:80px;">#</th> <th>Name</th> <th>Age</th> </tr> </thead> <tbody> <tr v-for="(item,index) in tableData" :key="item.id"> <th>{{index+1}}</th> <td>{{item.name}}</td> <td>{{item.age}}</td> </tr> <tr v-show="nowAdd.name||nowAdd.age" style="color:#bbb;"> <th>{{tableData.length+1}}</th> <td>{{nowAdd.name}}</td> <td>{{nowAdd.age}}</td> </tr> </tbody> </table> <!-- 类似于计算属性、 --> <!-- <p>{{$store.getters.person}}</p> --> <!-- <p>{{person}}</p> --> <!-- <p>{{newPerson}}</p> --> </div> </template> <script> // import { mapState } from "vuex"; // mapGetters -- 可以拿到 $store.getters import { mapState, mapGetters } from "vuex"; export default { computed: { ...mapState(["tableData", "nowAdd"]), // ...mapGetters(["person"]), ...mapGetters({ // 取一个别名 newPerson: "person" }) } }; </script> ``` ***** :-: ./store/learn.js ``` export default { // 添加命名空间 namespaced: true, state: { learnData:'模块数据' }, getters: { coursePrice() { return 'abc'; } }, mutations: {}, actions: {} }; ``` ## :-: vue - 修改state的方法 (标准) :-: vuex的理念是单向数据流 ``` // --------------- state // 开启严格模式,对代码进行严格检测 strict: process.env.NODE_ENV !== 'production' state:{ // 数据 xxx:'xxx', studentList:[] }, mutations:{ // 该对象存放的是同步的操作 changelist(state,{name,objData}){ state.studentList.push(objData); } }, actions:{ // 执行异步的,可以重名 changelist( {commit}, payload ){ setTimeout(()=>{ commit('changelist', payload) },1000) } } // --------------- 外部调用方式 // 执行同步 this.$state.commit('changelist',abc); // 执行异步 this.$state.dispatch('changelist'); -- 导入方式调用 import { mapMutations, mapActions } from 'vuex'; methods:{ ...mapMutations(['changelist']), ...mapActions(['changelist']) } ``` ## :-: vuex - 分模块管理数据 ``` -- 分模块管理 (在vuex对象中增加modules属性) modules:{ modulesTest:{ namespaced: true, // 添加上命名空间,定义为模块 state:{ // 数据 xxx:'xxx', studentList:[] }, getters:{ xxx(){ return xxx; } }, mutations:{ // 该对象存放的是同步的操作 changelist(state,{name,objData}){ state.studentList.push(objData); } }, actions:{ // 执行异步的,可以重名 changelist( {commit}, payload ){ setTimeout(()=>{ commit('changelist', payload) },1000) } } } } // --------------- 外部调用方式 // 1. state放入到每一个模块中,getters、mutations、actions会被放置到全局下。 // 2. 但是这么做显然不科学,所以我们需要定义上一个命名空间 (namespaced:true) 第一种调用方式: // 获取'modulesTest'模块下state对象中的数据'xxx' this.$store.state['modulesTest'].xxx // 调用'modulesTest'模块下getters对象中的'xxx'方法 (计算属性) this.$store['modulesTest/getters'].xxx // 调用'modulesTest'模块下mutations对象中的'changelist'方法 (同步) this.$store.commit('modulesTest/changelist', {abc,123} ); // 调佣'modulesTest'模块下actions对象中的'changelist'方法 (异步) this.$store.dispatch('modulesTest/changelist', {abc,123} ); 第二种调用方式: import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'; computed:{ // modulesTest -- 是模块的命名空间 ...mapState('modulesTest', ['xxx']), ...mapGetters('modulesTest', ['xxx']) }, methods:{ ...mapMutations('modulesTest', ['changelist']), ...mapActions('modulesTest', { // 传入对象的方式可以更换别名 (this.xxx) changelist:'xxx' }), } ```