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";
​
//初始化store
export 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

<style lang="less">
</style>
<template>
<div>
<p>{{msg}}</p>
<p>{{name}}</p>
<p>{{location}}</p>
<p>detail : {{detail}}</p>
<button @click="change">change location</button>
<button @click="asyncChange">async change location</button>
<card></card>
</div>
</template>
<script>
import store from "../store/";
import Card from "./card.vue";
​
export default {
components : {
Card
},
store,
created () {},
computed : {
msg (){
return "msg : " + this.$store.state.msg
},
name (){
return "name :" + this.$store.state.name
},
location (){
return "location :" + this.$store.state.location
},
detail (){
return this.$store.getters.detail
}
},
ready() {
​
},
methods : {
change (){
this.$store.dispatch("changeLocation")
},
asyncChange (){
this.$store.dispatch("changeLocationAsync", {
location : "china"
});
}
},
watch : {
},
filters: {
}
}
</script>

子模块 card.vue

<style lang="less">
</style>
<template>
<div>
<button @click="add">add card</button>
<input type="text" name="" @input="updateMessage" :value="message">
<span>{{cardCount}}</span>
<div v-for="(index, card) in list">{{card.name}}<span @click="del(index)">x</span></div>
</div>
</template>
<script>
export default {
components : {
},
computed : {
list (){
return this.$store.state.card.list
},
cardCount (){
return this.$store.state.card.list.length;
},
message (){
return this.$store.state.card.message
}
},
created () { },
ready() {
​
},
methods : {
add (){
this.$store.dispatch("addcard");
},
updateMessage (e){
this.$store.dispatch("updateMessage", e.target.value)
},
del (index){
this.$store.dispatch("deleteCard", index);
}
},
watch : {
​
},
filters: {
}
}
</script>

附上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不会太大。

 

vue+vuex初入门的更多相关文章

  1. Vue+Vuex初体验

    首先: 安装vuex npm install vuex -S 需要有两个组件(HelloWord.vue 和 HelloDemo.vue)[组件自定义] 注册路由 注册store 测试 一.需要有两个 ...

  2. vue学习【四】vuex快速入门

    大家好,我是一叶,今天我们继续踩坑.今天的内容是vuex快速入门,页面传值不多的话,不建议vuex,直接props进行父子间传值就行,使用vuex就显得比较臃肿. 我们先预览一下效果,如图1所示. 图 ...

  3. Vue的简单入门

    Vue的简单入门 一.什么是Vue? vue.js也一个渐进式JavaScript框架,可以独立完成前后端分离式web项目 渐进式:vue可以从小到控制页面中的一个变量后到页面中一块内容再到整个页面, ...

  4. Vuex 2 入门与提高。

    从计数器开始 让我们从一个简单的计数器,开始进入Vuex 的世界: 计数器应用的数据模型很简单:使用一个counter属性来表示计数器的 当前值就够了. 在Vue实例的created钩子 中,应用启动 ...

  5. Vuex的入门教程

    前言 在 Vue.js 的项目中,如果项目结构简单, 父子组件之间的数据传递可以使用  props 或者 $emit 等方式,详细点击这篇文章查看. 但是如果是大型项目,很多时候都需要在子组件之间传递 ...

  6. vuex 基本入门和使用(三)-关于 mutation

    vuex 基本入门和使用(三)-关于 mutation vuex 版本为^2.3.1,按照我自己的理解来整理vuex. 关于 mutation 这里应该很好理解. 更改 Vuex 的 store 中的 ...

  7. vuex 初体验

    vuex是vue的状态管理工具,vue进阶从es6和npm开始,es6推荐阮一峰大神的教程. vuex学习从官方文档和一个记忆小游戏开始.本着兴趣为先的原则,我先去试玩了一把-->. Vuex ...

  8. 我的音乐盒子(nodejs7 + koa2 + vue + vuex + vue-router)

    你们知道的,nodejs对jser来说,是个好东西,快快的,自从接触nodejs后,总想弄点东西. 这弄个啥了,一天打开百度音乐盒,哟,自己弄一个如何了,好啊好啊. 后台: nodejs 7 + ko ...

  9. use vue vuex vue-router, not use webpack

    vue,vuex,vue-router放在一起能做什么?不用webpack之类的打包工具使用他们是否可行?各位道友在初学vue时是否有这样的困惑.因为现代构建前端项目的一般模式是: 安装webapck ...

随机推荐

  1. Ubuntu开启NFS,挂载根目录

    1.安装NFS server Ubuntu初始状态是没有NFS server的,首先要安装NFS server: $ sudo apt-get install nfs-kernel-server (安 ...

  2. 如何在网页启动Windows服务

    由于公司有许多windows服务进行业务的处理,所以对服务的维护也是一个比较头痛的问题,因为自己也不知道服务什么时候自动停了,而且更主要的原因是服务都是由运维部门在维护管理,开发这边没有直接操作服务的 ...

  3. Python Learing(二):Basic Image Processing 1

    <写在前面> Basic image processing 1: 0.(以简单的曲线图为例)对于生成的图自定义外观,使用子图,多个数据集,标题,标签,交互式标注,图例: 1.生成散点图,直 ...

  4. warfare(最大生成树裸题)

                                                                                                  战争 [问题 ...

  5. VS2012配色方案

    VS2012配色方案 这些天由于公司项目比较忙,所以天天盯着电脑8小时,而且我的开发工具VS2012是白色背景的所以每天下班都搞的眼睛巨疼. 今天在网上找到一个很好的配色方案,所以有同样烦恼的童鞋们可 ...

  6. C#制作高仿360安全卫士窗体3

    C#制作高仿360安全卫士窗体(三)   距上篇C#制作高仿360安全卫士窗体(二)也将近一个多月了,这个月事情还是像往常一样的多.不多我也乐在其中,毕竟我做的是我喜欢做的东西.今天特地抽空把怎么制作 ...

  7. Struts2.1.8 + Spring3.0+ Hibernate3.2整合笔记

    body, p, th, td, li, ul, ol, h1, h2, h3, h4, h5, h6, pre { font-family: simsun; line-height: 1.4; } ...

  8. C#跨窗体调用控件(委托回调函数使用例子)

    问题: 有两个窗体,FORM1(含一个label控件,一个名为显示form2的button控件)和FORM2(含一个button控件).启动时,FORM1中点击button控件显示form2使FORM ...

  9. HDFS中PathFilter类

    HDFS中PathFilter类 在单个操作中处理一批文件,这是很常见的需求.比如说处理日志的MapReduce作业可能需要分析一个月内包含在大量目录中的日志文件.在一个表达式中使用通配符在匹配多个文 ...

  10. 探讨C++ 变量生命周期、栈分配方式、类内存布局、Debug和Release程序的区别

    探讨C++ 变量生命周期.栈分配方式.类内存布局.Debug和Release程序的区别(一) 今天看博客园的文章,发现博问栏目中有一个网友的问题挺有趣的,就点进去看了下,标题是“C++生存期问题”,给 ...