12-vuex数据管理(数据仓库)--module模块化开发
vuex数据管理(数据仓库)--module模块化开发
vuex中的模块(module)
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、getter、mutation、action、甚至是嵌套子模块。
模块的命名空间
默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。
如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。
Vuex模块:开启命名空间
模块开启命名空间后,享有独自的命名空间。
创建模块和命名空间
创建模块最重要的规则是,尽量避免定义全局变量,任何时候你定义了一个全局变量都是冒着可能被其他模块修改的危险。
解决不使用全局变量的方法,就是使用自己定义的命名空间。
// 如果希望模块 不是全局的,我们在这里 需要添加命名空间
const cartModule = {
namespaced:true,
state:{},
getters:{},
mutations:{},
actions:{}
}
当我们不申明命名空间的时候
const cartModule = {
state:{}, 这个方法是局域的
getters:{}, 其他的几个方法是全局的
mutations:{},
actions:{}
}
大前提:vuex数据仓库 是以 module模块化 进行开发的!!
在vue单页组件中 使用 vuex数据仓库中的 共享数据,获取数据的方法如下所示:
state:【this.$store.state.模块名.key】
getters:【this.$store.getters['模块名/key']】
mutations:【this.$store.commit('模块名/method')】
actions:【this.$store.dispatch('模块名/method')】
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="./js/vue.js"></script>
<script src="./js/vuex.js"></script>
<script src="./js/axios.js"></script>
</head>
<body>
<div id="app">
<list></list>
<car-footer></car-footer>
</div>
<template id="list">
<div>
<!-- <p>我是List组件</p> -->
<p>{{message}}</p>
<table border="1" width="650" v-if="goods.length>0">
<tr>
<th>商品编号</th>
<th>商品名称</th>
<th>商品单价</th>
<th>商品数量</th>
<th>商品小计</th>
<th>操作</th>
</tr>
<tr v-for="(item,index) in goods">
<td>{{item.id}}</td>
<td>{{item.goodname}}</td>
<td>{{item.price}}</td>
<td>
<button @click="subtraction(item.id)">-</button>
<input type="text" name="" id="" v-model="item.num" style="width:100px;">
<button @click="addition(item.id)">+</button>
</td>
<td>{{item.total}}</td>
<td>
<button @click="del(item.id)">删除</button>
</td>
</tr>
</table>
</div>
</template>
<template id="carfooter">
<div>
<!-- <p>我是carFooter组件</p> -->
<div>
<span style="color:red;">{{goods.length}}</span>
件商品总计(不含运费):
<span style="color:red;">¥{{totalPrice}}</span>
</div>
</div>
</template>
<script>
// 使用Vuex
Vue.use(Vuex)
// 创建模块---定义2个模块
var cartModule = {
namespaced:true,
state:{
totalPrice:0,
message:'购物清单',
goods:[]
},
getters:{
// 1.使用getters计算“每一件商品”的总价
getGoods:function(state){
let goods = state.goods;
// 遍历
goods.forEach((item)=>{
item.total = item.price*item.num;
})
return goods;
},
// 2.使用getters计算所有商品总价
getTotalPrice:function(state){
let goods = state.goods;
let totalPrice = state.totalPrice;
// 遍历
goods.forEach((item)=>{
totalPrice += item.price*item.num
})
return totalPrice;
}
},
mutations:{
del:function(state,param){
console.log('数据仓库mutations获取 组件传过来的值:----'+param);
let goods = state.goods;
let k;
// 遍历
goods.forEach((item,i)=>{
// 在遍历的过程当中,我们去做判断
if(param == item.id){
k = i;
}
})
console.log(k);
// 从指定位置上k,删1个内容
goods.splice(k,1);
},
setGoods:function(state,param){
state.goods = param.goods;
}
},
actions:{
loadingGoods:function(store){
axios.get('./goods.php').then((response)=>{
store.commit('setGoods',{goods:response.data})
}).catch((error)=>{
console.log(error);
})
}
}
}
var CartfooterModel = {
state:{
},
getters:{
},
mutations:{
},
actions:{
}
}
// 创建数据仓库
var store = new Vuex.Store({
// 在仓库中 引用模块
modules:{
cart : cartModule,
cartfooter : CartfooterModel
}
})
// 注意:我们在组件中,用的是 cart 和carfooter 模块名称
// 子实例(子组件)
var List = {
template:'#list',
computed:{
totalPrice:function(){
// 在组件中,获取 仓库中 某个模块上的 state 中的数据
// this.$store.state.模块名称.模块中的state里面的数据
return this.$store.state.cart.totalPrice;
},
message(){
return this.$store.state.cart.message;
},
goods:function(){
// return this.$store.state.cart.goods;
return this.$store.getters['cart/getGoods'];
}
},
methods:{
del:function(id){
this.$store.commit('cart/del',id)
},
subtraction:function(id){
// 遍历计算属性中的goods这个商品列表
this.goods.forEach((v)=>{
if(id == v.id){
console.log(v.num);
if(v.num>0){
v.num--;
return false;
}
}
})
},
addition:function(id){
// console.log(id);
// 遍历计算属性中的goods这个商品列表
this.goods.forEach((v)=>{
if(id == v.id){
console.log(v.num);
v.num++;
}
})
}
}
}
// 子实例(子组件)
var carFooter = {
template:'#carfooter',
computed:{
goods:function(){
// return this.$store.state.cart.goods;
return this.$store.getters['cart/getGoods'];
},
totalPrice:function(){
// return this.$store.state.cart.totalPrice;
// 获取 数据仓库 中 car模块里 getters中的getTotalPrice方法中返回的值
return this.$store.getters['cart/getTotalPrice'];
}
}
}
// 根实例(根组件)
var vm = new Vue({
el: '#app',
store,
data: {
},
methods: {
},
components: {
List,
carFooter
},
// 生命周期
mounted:function(){
this.$store.dispatch('cart/loadingGoods')
}
});
</script>
</body>
</html>
