Vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
解决问题:
-
传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。
-
采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致无法维护的代码。
参考文档:
- https://github.com/vuejs/vuex/tree/dev/examples/shopping-cart
- https://vuex.vuejs.org/zh-cn/getting-started.html
数据流动
开始
让我们做一个添加列表的功能
目录结构
├── index.css├── index.js├── store│ ├── index.js│ ├── main.js│ └── modules│ └── card.js└── vue-mods ├── card.vue └── index.vue
定义store.js
import Vue from 'vue'import Vuex from 'vuex'import card from "./modules/card.js";//初始化storeexport default new Vuex.Store({ //store的子模块 modules : { card }, //定义状态 state : { msg : "hello, this msg is from vuex.store", name : "zhangjian", location : "zhengjiang" }, //设置状态的获取,可以做一些特殊的定制 getters : { detail : state => { return state.msg + state.name } }, //mutation,用来修改state mutations : { CHANGE_LOCATION (state, location = "beijing"){ state.location = location; } }, //事件处理,主要是由外部触发store actions : { changeLocation ({ commit, state }){ commit("CHANGE_LOCATION");//触发mutation }, changeLocationAsync ({commit, state}, {location}){ setTimeout(function (){ commit("CHANGE_LOCATION", location); }, 1000); } }});
modules/card.js
,和store.js
和一致,只是输出的是一个模块
let state = { list : [], message : "this is card"}let getters = {}let mutations = { ADD_CARD (state, card){ state.list.unshift(card) }, UPDATE_MESSAGE (state, message){ state.message = message; }, DELETE_CARD_BY_INDEX (state, index){ state.list.splice(index, 1); }}let actions = { addcard ({commit, state}, card){ let message = state.message; let time = new Date().getTime(); commit("ADD_CARD", {name : `${message} card - ${time}`}) }, updateMessage ({commit, state}, message){ commit("UPDATE_MESSAGE", message); }, deleteCard ({commit, state}, index){ commit("DELETE_CARD_BY_INDEX", index); }}export default{ state, getters, mutations, actions}
入口文件 App.vue
{
{msg}}{
{name}}{
{location}}detail : {
{detail}}
子模块 card.vue
{ {cardCount}}{ {card.name}} x
附上webpack.config.js
var webpack = require('webpack');var vue = require('vue-loader')var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('common.js');var ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = { //插件项 plugins: [ new ExtractTextPlugin("[name].css") ], //页面入口文件配置 entry: { index : './src/index.js' }, //入口文件输出配置 output: { path: './dist/', filename: '[name].js' }, module: { //加载器配置 loaders: [ { test: /\.css$/, loader: ExtractTextPlugin.extract("css") }, { test: /\.less$/, loader: ExtractTextPlugin.extract("css!less") }, { test: /\.js$/, loader: "babel",query: {presets: ['es2015']},exclude: /node_modules/ }, { test: /\.vue$/, loader: 'vue'} ] }, vue : { loaders: { css: ExtractTextPlugin.extract("css"), less: ExtractTextPlugin.extract("css!less") }, autoprefixer: { browsers: ["ios_saf >= 7", "android >= 4"] } }, externals: { vue: "window.Vue", vuex : "window.Vuex" }};
注意:这里,我针对vue和vuex2个仓库,做了一个全局引用,这样打包出来的boundle不会太大。