docker-compose搭建lsky Pro 兰空 自建图库,php:7.3-apache

C++创建窗口

  返回  

vuex的基本应用(vuex的购物车案例)

2021/8/20 17:58:33 浏览:

vuex的基本应用

概念

​ vuex是一个专门为vue应用程序开发的状态管理模式,“vuex采用集中式存储,管理vue应用的所有组件的状态,并以相应的规则保证状态以一种可以预测的方式发生变化。”
集中式存储,就是把所有的vue应用的状态放在一个统一的地方。所有要使用状态(数据)的角色都来这里获取状态,兄弟组件之间传递信息就不用再找父组件了。

​ view页面,也就是表现层它对我们的action做出了反馈。也就是说,你通过action改变了事物的状态,也就改变了事物的view。

​ 组件的状态,就是“这个组件现在什么样”,把所有的组件【现在是什么样?】都统一保存在一个地方,
这就是“集中式存储管理vue应用的所有组件的状态”。

​ 前端所有会引起变化的,例如,click,load,ajax,show, hide 等等,这些都是动作,它们会改变组件的状态。
vuex要管理的,就是这些东西。

​ 在vue当中,它是单向数据流,如果是多个子组件,那么就需要父组件做为中继来传递数据。这样的问题,当应用复杂到一定程度的时候,状态(数据)的跟踪控制会复杂到无法维护的程度。在这种背景之下,vuex出现了,就是把多个组件的状态,放在一个共同的地方进行集中的管理。

https://vuex.vuejs.org/vuex.png

vuex具体是怎么管理状态(数据)的呢?

通过store对象来保存和管理整个应用的状态,

在store里面包含以下对象,

​ state,存放状态的;

  • getters,用来获取state里的状态的;

  • mutations,更改状态(数据)的业务逻辑;

  • actions,提交 mutation;

  • modules,把store模块化;
    state,驱动应用的数据源,(所有的状态【数据】保存在这里)
    view,以声明的方式将state映射到视图,(也就是说,改变状态引发表现层变化)
    actions,响应在view上的用户操作导致的状态变化,(事件改变状态)

    ​ vuex的核心就是 store对象因为是统一管理状态的,所以每个vue应用只有一个store对象,在它里面包含着整个应用中的所有状态。

    数据流是单向的,组件能够调用 actions,actions用来派发 mutations,只有 mutations 可以改变 state,store是响应式的,无论 state什么时候被 更新,组件都将同步更新。

let Store = new Vuex.Store({
	state:{ 这里是状态,也就是数据 },
	getters:{
		//state的计算属性,
		//用来从store当中获取数据
	},
	mutations:{
		//更改 state 中的状态的业务逻辑,
	},
	actions:{
		//提交 mutation,
	}
})

改变store中的state的状态的唯一方法,就是调用store中的commit方法,提交 mutations,其实就是调用mutations当中的函数。

vuex需要使用npm来安装,因为它不是vue-cli脚手架的一部分。
npm install vuex -save

我们引入了自定义的组件的时候,要在父组件中进行注册,components:{组件名,组件名2}

在store目录中,创建modules目录,是因为在比较大一些的项目应用中,它的数据量会比较大,导致store文件的体积也比较大,加载的速度就慢了,所以把它拆分为多个文件,放在modules目录中。

mapGetters,将 store 中的 getter 映射到局部计算属性

三个重点:
1、vuex中的store里的getters把数据输出;
2、mapGetters,把getter输出的数据,映射到computed;
3、…扩展运算符,把mapGetters映射的值,展开

vuex的映射事件 mapActions,
它是以数组的形式,映射模块中的方法,

应用 vuex的购物车的案例

​ 做一个vuex的购物车的案例页面搭建使用,bootstrap,它有统一、规范的html、css的外观样式,能够快速的形成页面,一般使用它来搭建的网站,

// main.js
import Vue from 'vue'
import App from './App'
import store from './store'
Vue.config.productionTip = false
new Vue({
  el: '#app',
  store,
  components: { App },
  template: '<App/>'
})

// App.vue
<template>
  <div id="app">
      <!-- 商品列表 -->
      <product></product>
      <!-- 已选商品 -->
      <cart></cart>
      <!-- 总计 -->
      <info></info>
  </div>
</template>
<script>
import product from './components/product'
import cart from './components/cart'
import info from './components/info'
export default {
  name: 'App',
   //注册组件
  components:{product, cart, info}
}
</script>

// product.vue 商品信息
<template>
  <div class='product'>
  	<h3>商品信息</h3>
  	<table class="table table-hover table-bordered">
  		<thead>
  			<tr>
  				<th>id</th>
  				<th>名称</th>
  				<th>价格</th>
  				<th>操作</th>
  			</tr>
  		</thead>
  		<tbody>
  			<tr v-for="n in shoplist">
  				<td> {{n.id}} </td>
  				<td> {{n.name}} </td>
  				<td> {{n.price}} </td>
  				<td>
  					<div @click="addToCart(n)" class='btn btn-info'>添加到购物车</div>
  				</td>
  			</tr>
  		</tbody>
  	</table>
  </div>
</template>
<script>
import { mapGetters, mapActions } from 'vuex'
export default{
	name:'product',
	data(){
		return {}
	},
	computed:{
    // 映射数据的
		...mapGetters(['shoplist'])
	},
  methods:{
    // 映射事件,把事件映射到store的actions里面
    ...mapActions(['addToCart'])
  }
}
</script>

//  Cart.vue 已选商品
<template>
  <div class='product'>
  	<h3>已选商品</h3>
  	<table class="table table-hover table-bordered">
  		<thead>
  			<tr>
  				<th>id</th>
  				<th>名称</th>
  				<th>价格</th>
          <th>数量</th>
  				<th>操作</th>
  			</tr>
  		</thead>
  		<tbody>
  			<tr v-for="n in cartProducts">
  				<td> {{n.id}} </td>
  				<td> {{n.name}} </td>
  				<td> {{n.price}} </td>
          		<td> {{n.num}} </td>
  				<td>
  					<div @click="delGoods(n)" class='btn btn-danger btn-sm'>删除</div>
  				</td>
  			</tr>
  		</tbody>
  	</table>
  </div>
</template>
<script>
import { mapGetters, mapActions } from 'vuex'
export default{
	name:'cart',
	data(){
		return {}
	},
  computed:{
    // 映射数据的
    ...mapGetters(['cartProducts'])
  },
  methods:{
    // 映射事件,把事件映射到store的actions里面
    ...mapActions(['delGoods'])
  }
}
</script>
 
// Info.vue 总数量 总价格
<template>
  <div class='item-wrapper'>
      <div class='item'>
          总数:{{totalNum}}
      </div>
      <div class='item'>
          总价:{{totalPrice}}
      </div>
      <div @click="clearAllCart" class='item btn btn-danger'>清空购物车</div>
  </div>
</template>
<script>
import { mapGetters, mapActions } from 'vuex'

export default{
	name:'info',
	data(){
		return {}
	},
  computed:{
    // 映射数据的
    ...mapGetters(['totalNum','totalPrice'])
  },
  methods:{
    // 映射事件,把事件映射到store的actions里面
    ...mapActions(['clearAllCart'])
  }
}
</script>

// store/index.js
// 组装模块,并导出store,这是一个 .js 文件
import Vue from 'vue'
import Vuex from 'vuex'
import cart from './modules/cart'
Vue.use( Vuex )
let store = new Vuex.Store({
    modules:{ cart }
})
export default store

// store/modules/cart.js
/* 这就是 store 对象了 */
// 初始化数据,商品列表
const state = {
	// 所有商品
	shoplist:[{
		id:1,
		name:'汽车',
		price:'44'
	},{
		id:2,
		name:'飞机',
		price:'55'
	},{
		id:3,
		name:'大炮',
		price:'66'
	},{
		id:4,
		name:'火箭',
		price:'77'
	},{
		id:5,
		name:'卫星',
		price:'88'
	}],
	// 已选择的商品的id和数量
	added:[]
}
// 向外输出数据
const getters = {
	// 商品列表
	shoplist : state => state.shoplist,
	// 购物车列表
	cartProducts: state => {
		return state.added.map( ({id, num})=> {
			let  _n = state.shoplist.find( n => n.id === id );
			return {
				..._n,
				num
			}
		})
	},
	// 计算总数,state必须要传
	totalNum:( state, getters )=>{
		let _totalNum = 0;
		getters.cartProducts.forEach( n =>{
			_totalNum += n.num
		})
		return _totalNum;
	},
	// 计算总价
	totalPrice:( state, getters )=>{
		let _totalPrice = 0;
		getters.cartProducts.forEach( n =>{
			_totalPrice += n.num * n.price
		})
		return _totalPrice;
	},
}
// 只有actions才能修改mutations
const actions = {
	// 添加到购物车,固定的写法
	addToCart({commit},n){
		// add是一个函数名,它在mutations里面 并向它里面传入值
		commit('add',{
			id: n.id
		})
	},
	// 删除商品
	delGoods({commit}, n){
		commit('delFn',n)
	},
	// 清空购物车
	clearAllCart({commit}){
		commit('clearAll')
	}
}
const mutations = {
	// 添加到购物车,id是形参,接收的商品id
	add( state, {id} ){
		let _n = state.added.find( n => n.id == id );
		if( _n ){// 商品存在
			_n.num++;
		} else {// 商品不存在
			state.added.push({
				id,
				num:1
			})
		}
	},
	// 删除商品,_goods形参,用来接收你要删除的那个商品
	delFn( state, _goods ){
		state.added.forEach( (n, i)=>{
			if( n.id == _goods.id ){
				state.added.splice( i, 1 );
			}
		})
	},
	// 清空购物车
	clearAll( state ){
		state.added = []
	}
}
export default{
	state,
	getters,
	mutations,
	actions
}

联系我们

如果您对我们的服务有兴趣,请及时和我们联系!

服务热线:18288888888
座机:18288888888
传真:
邮箱:888888@qq.com
地址:郑州市文化路红专路93号