状态管理模式 Vuex入门

150 阅读1分钟

开发简单的购物车

  • 购物车页面
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>购物车</title>
        <script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
    </head>
    <body>
        <div id="app">
            标题: <input type="text" v-model="title" />
            价格: <input type="text" v-model="price" />
            <button type="button" @click="addGoods">添加商品</button>
            <ul>
                <li v-for="(item,index) in goods">
                    商品标题: {{item.title}} -- 商品价格: {{item.price}} 
                    <button @click="addCart(index)">添加到购物车</button>
                </li>
            </ul>
            <cart :cart="cart"></cart>
        </div>
        <script type="text/javascript">
            var cart = {
            template: `
                <div>
                    购物车
                    <table border="1">
                        <tr>
                            <th>选中</th>
                            <th>商品</th>
                            <th>数量</th>
                            <th>价格</th>
                        </tr>
                        <tr v-for="(item,index) in cart">
                            <td><input type="checkbox" v-model="item.checked"/></td>
                            <td>{{item.title}}</td>
                            <td>
                                <span @click="jian(index)">- </span>
                                {{item.count}}
                                <span @click="jia(index)"> +</span>
                            </td>
                            <td>{{item.price*item.count}}</td>
                        </tr>
                        <tr>
                            <td colspan="2">选择: {{checkedCount}}/{{count}}</td>
                            <td colspan="2">结算: {{totalPrice}}</td>
                        </tr>
                    </table>
                </div>
            `,
            props:["cart"],
            methods:{
                jia(index) {
                    this.cart[index].count++;
                },
                jian(index) {
                    if (this.cart[index].count > 1) {
                        this.cart[index].count--;
                    } else {
                        // 注意es6语法``
                        if (confirm(`是否删除${this.cart[index].title}`)) {
                            this.cart.splice(index, 1)
                        }
                    }
                }
            },
            computed:{
                checkedCount(){
                    // 过滤
                    return this.cart.filter(c=>c.checked).length
                },
                count(){
                    return this.cart.length
                },
                totalPrice(){
                    let total=0;
                    // forEach的使用
                    this.cart.forEach(c=>{
                        if(c.checked){
                            total+=c.price*c.count
                        }
                    })
                    return total;
                }
            },
            watch:{
                cart:{
                    handler(){
                        // 本地缓存
                        localStorage.setItem("cart",JSON.stringify(this.cart));
                    },
                    deep:true
                }
            }

            new Vue({
                el: "#app",
                data: {
                    title: "",
                    price: "",
                    // 商品数据
                    goods: [{
                        title: "html5",
                        price: 9.9
                    }, {
                        title: "css3",
                        price: 19.9
                    }, {
                        title: "java script",
                        price: 29.9
                    }],
                    // 购物车数据
                    cart: []
                },
                components: {
                    cart
                },
                methods: {
                    // 添加商品
                    addGoods() {
                        this.goods.push({
                            title: this.title,
                            price: this.price
                        })
                        this.title = "";
                        this.price = "";
                    },
                    // 添加到购物车
                    addCart(index) {
                        var goods = this.goods[index];
                        // 注意,es6语法箭头函数和find()
                        var result = this.cart.find(c => c.title == goods.title);
                        if (result) {
                            result.count += 1;
                        } else {
                            this.cart.push({ ...goods,
                            count: 1,
                            checked: true
                            });
                        }
                    }					
                },
                created() {
                    this.cart=JSON.parse(localStorage.getItem("cart"));
                }
            })
        </script>
    </body>
</html>
  • vuex
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

let store = new Vuex.Store({
  state: {
    token: "",
    cartArr: JSON.parse(localStorage.getItem("cartArr")) || []
  },
  mutations: {
    setToken(state, token) {
      state.token = token
    },
    // 添加到购物车
    toCart(state, goods) {
      let cart = state.cartArr.find(v => v.title == goods.lable)
      if (cart) {
        cart.count += 1
      } else {
        state.cartArr.push({
          title: goods.lable,
          count: 1
        })
      }
    },
    // 添加购物车
    addCart(state, index) {
      state.cartArr[index].count++
    },
    // 减少购物车
    removeCart(state, index) {
      if (state.cartArr[index].count > 1) {
        state.cartArr[index].count--
      } else {
        if (confirm("确定删除该商品吗?")) {
          state.cartArr.splice(index, 1)
        }
      }
    },
    // 清空购物车
    clearCart(state) {
      state.cartArr = []
    }
  },
  actions: {
  },
  modules: {
  },
  getters: {
    cartCount: state => {
      let count = 0
      state.cartArr.forEach(v => {
        count += v.count
      })
      return count
    }
  }
})

// 数据持久化
store.subscribe((mutations, state) => {
  localStorage.setItem("cartArr", JSON.stringify(state.cartArr))
})

export default store