# vuex-car-demo
**Repository Path**: cloveryuan/cartdemo
## Basic Information
- **Project Name**: vuex-car-demo
- **Description**: 初识vuexdemo
- **Primary Language**: JavaScript
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2020-08-14
- **Last Updated**: 2020-12-17
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
### 先启动后端服务
node server
### 再启动个面板,启动前端服务
npm install
npm run serve
项目就跑起来了,点击悬浮框去购物车,会跳转到car模块,购物车商品通过插件plugins做了缓存
## Vuex状态管理
### 一、组件内的状态管理流程
#### 1. 状态管理
+ state:驱动应用的数据源
+ view:以声明方式将state映射到视图
+ actions:相应在view上的用户输入导致的状态变化
count: {{ count }} msg: {{ msg }}
### 二、组件间通信方式
#### 1. 父组件给子组件传值
+ 子组件通过props接受数据
```vue
{{title}}
Props Down Child
Event Up Parent
这里的文字不需要变化
Event Bus sibling01
Event Bus sibling02
ref Child
ref Parent
componentA
user name : {{ sharedState.user.name }}
componentB
user name : {{ sharedState.user.name }}
store/index.js
```js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 0,
msg: 'Hello Vuex'
},
mutations: {
},
actions: {
},
modules: {
}
})
```
App.vue
```vue
Vuex - Demo
count: {{ num }}
msg: {{ message }}
``` ```js ...mapState({ num: 'count', message: 'msg' }) ``` #### 3. Getter Vuex中的getter相当于VUE中的计算属性。 store/index.js ```js import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { count: 0, msg: 'Hello Vuex' }, getters: { reverseMsg (state) { return state.msg.split('').reverse().join('') } }, mutations: { }, actions: { }, modules: { } }) ``` App.vue ```vuecount: {{ num }}
msg: {{ message }}
reverseMsg: {{ reverseMsg }}
count: {{ num }}
msg: {{ message }}
reverseMsg: {{ reverseMsg }}
#### 5. Action
Action中可以进行异步操作,不过如果需要修改state,得提交Mutation。
Store/index.js
```js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 0,
msg: 'Hello Vuex'
},
getters: {
reverseMsg (state) {
return state.msg.split('').reverse().join('')
}
},
mutations: {
increate (state, payload) {
state.count += payload
}
},
actions: {
increateAsync (context, payload) {
setTimeout(() => {
context.commit('increate', payload)
}, 2000)
}
},
modules: {
}
})
```
App.vue
mapActions用法同mapMutations
```vue
count: {{ num }}
msg: {{ message }}
reverseMsg: {{ reverseMsg }}
count: {{ num }}
msg: {{ message }}
reverseMsg: {{ reverseMsg }}
products: {{ products }}
> 注意:不要在生产模式下开启严格模式,严格模式会深度检查状态树,检查不合规的状态改变,会影响性能。
>
> 我们可以在开发模式下开启严格模式,在生产模式中关闭严格模式:
>
> ` strict: process.env.NODE_ENV !== 'production',`
### 七、购物车案例
#### 1. 模板
地址:https://github.com/goddlts/vuex-cart-demo-template.git
用到了ElementUI、Vuex、Vue-Router
项目根目录下的server.js文件是一个node服务,为了模拟项目接口。
页面组件和路由已经完成了,我们需要使用Vuex完成数据的交互。
三个组件:
+ 商品列表组件
+ 购物车列表组件
+ 我的购物车组件(弹出窗口)
#### 2. 商品列表组件
+ 展示商品列表
+ 添加购物车
#### 3. 我的购物车组件
+ 购买商品列表
+ 统计购物车中的商品数量和价格
+ 购物车上的商品数量
+ 删除按钮
#### 4. 购物车组件
+ 展示购物车列表
+ 全选功能
+ 增减商品功能和统计当前商品的小计
+ 删除商品
+ 统计选中商品和价格
#### 5. Vuex插件介绍
+ Vuex的插件就是一个函数
+ 这个函数接受一个store参数
这个参数可以订阅一个函数,让这个函数在所有的mutation结束之后执行。
```js
const myPlugin = store => {
// 当store初始化后调用
store.subscribe((mutation, state) => {
// 每次mutation之后调用
// mutation的格式为{ type, payload }
})
}
```
Store/index.js
```js
import Vue from 'vue'
import Vuex from 'vuex'
import products from './modules/products'
import cart from './modules/cart'
Vue.use(Vuex)
const myPlugin = store => {
store.subscribe((mutation, state) => {
if (mutation.type.startsWith('cart/')) {
window.localStorage.setItem('cart-products', JSON.stringify(state.cart.cartProducts))
}
})
}
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
modules: {
products,
cart
},
plugins: [myPlugin]
})
```
### 八、模拟实现Vuex
Myvuex/index.js
```js
let _Vue = null
class Store {
constructor (options) {
const {
state = {},
getters = {},
mutations = {},
actions = {}
} = options
this.state = _Vue.observable(state)
this.getters = Object.create(null)
Object.keys(getters).forEach(key => {
Object.defineProperty(this.getters, key, {
get: () => getters[key](state)
})
})
this._mutaions = mutations
this._actions = actions
}
commit (type, payload) {
this._mutaions[type](this.state, payload)
}
dispatch (type, payload) {
this._actions[type](this, payload)
}
}
function install (Vue) {
_Vue = Vue
_Vue.mixin({
beforeCreate () {
if (this.$options.store) {
_Vue.prototype.$store = this.$options.store
}
}
})
}
export default {
Store,
install
}
```
将store/index.js中的vuex的导入替换成myvuex
```js
import Vuex from '../myvuex'
```
----