openks / learn-vue

自定义组件文档
https://openks.github.io/learn-vue
0 stars 0 forks source link

vuex使用 #34

Open openks opened 7 years ago

openks commented 7 years ago

看了vuex的demo理解不是太深刻,自己写进项目里就清楚多了

openks commented 7 years ago

store文件夹结构如下

|____store
| |____actions.js
| |____getters.js
| |____index.js
| |____modules
| | |____cart.js
| | |____index.js
| | |____trace.js
| |____mutation-types.js

index.js内容如下

import Vue from 'vue';
import Vuex from 'vuex';
import * as actions from './actions';
import * as getters from './getters';
import index from './modules/index';

Vue.use(Vuex);

const debug = process.env.NODE_ENV !== 'production';

export default new Vuex.Store({
  actions,
  getters,
  modules: {
    cart,
    index,
    trace,
  },
  strict: debug,
});

actions.js内容如下

import * as types from './mutation-types';

const changeFoodTraceNav = ({ commit }, item) => {
  commit(types.CHANGE_FOOD_TRACE_NAV, {
    value: item,
  });
};

export { changeFoodTraceNav };

modules里的index.js

import * as types from '../mutation-types';

const state = {
  data: {
    footerChecked: 'index',
    foodSafeTypeNav: 'tab-container2',
  },
};

// getters
const getters = {
  foodSafeTypeNavSelected: state =>
    // console.log('获取一次值。。');
    state.data.foodSafeTypeNav
  ,
};

// actions
const actions = {

};

// mutations
const mutations = {
  [types.CHANGE_FOOD_TRACE_NAV](state, { value }) {
    state.data.foodSafeTypeNav = value;
  },
};

export default {
  state,
  getters,
  actions,
  mutations,
};

mutation-types.js

export const CHANGE_FOOD_TRACE_NAV = 'CHANGE_FOOD_TRACE_NAV';

main.js文件里引入store

import Vue from 'vue';
import moment from 'moment';
import store from './store';

Vue.config.productionTip = false;
Vue.mixin({
  created() {
    this.$moment = moment;
  },
});
/* eslint-disable no-new */
new Vue({
  el: '#app',
  store,
  template: '<App/>',
  components: { App },
});

在页面上使用

<template lang="html">
<div class="">
  <div class="tab-bar">
    <span class="tab-buttons">
      <span :class="{'cur':foodSafeTypeNavSelected==='tab-container1'}" @click="changeFoodTraceNav('tab-container1')">食安追溯</span>
      <span :class="{'cur':foodSafeTypeNavSelected==='tab-container2'}" @click="changeFoodTraceNav('tab-container2')">食安排查</span>
    </span>
  </div>
<!-- 这里不能用v-model 应该用v-bind:value -->
  <mt-tab-container class="tab-cont" :value="foodSafeTypeNavSelected">
    <mt-tab-container-item class="tab-cont-A" id="tab-container1">
      tab-container1
    </mt-tab-container-item>
    <mt-tab-container-item class="tab-cont-B" id="tab-container1">
      tab-container1
    </mt-tab-container-item>
  </mt-tab-container>
</div>
</template>

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

export default {
  data() {
    return {
      type: '市',
    };
  },
  computed: {
    typeC: {

    },
    ...mapGetters([
      'foodSafeTypeNavSelected',// modules/index.js getter的值
    ]),
  },
  methods: {
    goPage(item, to) {

    },
    ...mapActions([
      'changeFoodTraceNav',// 这个定义在store/actions.js 里面
    ]),
  },
};
</script>
openks commented 7 years ago

一直都知道计算属性不能设值,找了很久一直找不到哪里调用了setter最后终于找到了,使用别人写好的组件要特别留意这种问题

<mt-tab-container v-model="foodSafeTypeNavSelected">
<!-- 由于foodSafeTypeNavSelected是计算属性,如果使用v-model就会触发setter事件 -->
<mt-tab-container v-bind:value="foodSafeTypeNavSelected">
openks commented 7 years ago
import {
  mapState,
  mapGetters,
  mapActions, 
  mapMutations
} from 'vuex';

export default {
  computed: {
    ...mapState({
      ttest: state => state.index.ttest,//由于模块化则这里的state和getter没区别 
      footerNa: state => state.index.data.footerNav,//个人建议还是写getter这样可以更便于别处使用
    }),
    ...mapGetters([
        'foodSafeTypeNavSelected',
    ]),
  },
  methods: {
    ...mapMutations({
      changeWarnNav: types.CHANGE_WARN_NAV,
    }),
  },
};

store结构如下

➜  store git:(master) ✗ tree
.
├── actions.js
├── getters.js
├── index.js
├── modules
│   ├── cart.js
│   ├── index.js
│   └── trace.js
└── mutation-types.js

modules/index.js内容如下

import * as types from '../mutation-types';

const state = {
  data: {
    footerNav: 'index',
    foodSafeTypeNav: 'tab-container1',
  },
  ttest: 333,
};

// getters
const getters = {
  foodSafeTypeNavSelected: state => state.data.foodSafeTypeNav,
  footerNavSelected: state => state.data.footerNav,
};

// mutations
const mutations = {
  //第二个参数为一字符串或对象根据实际需求确定
  [types.CHANGE_FOOTER_NAV](state, item) {
    state.data.footerNav = item;
  },
  [types.CHANGE_FOOD_TRACE_NAV](state, { value }) {
    state.data.foodSafeTypeNav = value;
  },
  [types.CHANGE_WARN_NAV](state, value) {
    state.warnNav = value;
  },
  //该方法为通用方法可以通过 
  //changeValue({type:'warnNav',value:'aaa'})
  //实现跟[types.CHANGE_WARN_NAV]('aaa')一样的功能
  changeValue(state, item) {
    state[item.type] = item.value;
  },
};

export default {
  state,
  getters,
  mutations,
};

mutation-types.js文件内容如下

export const CHANGE_FOOTER_NAV = 'CHANGE_FOOTER_NAV';
export const CHANGE_FOOD_TRACE_NAV = 'CHANGE_FOOD_TRACE_NAV';
export const CHANGE_WARN_NAV = 'CHANGE_WARN_NAV';

mutation使用

<span class="tab-buttons">
  <span :class="{'cur':warnNavSelected==='tab-container1'}" @click="changeWarnNav('tab-container1')">违禁管理</span>
  <span :class="{'cur':warnNavSelected==='tab-container2'}" @click="changeWarnNav('tab-container2')">项目点监管</span>
</span>