Vue case-versión avanzada del carrito de compras (componentización, vuex, datos simulados)

1. Estructura de directorio

Inserte la descripción de la imagen aquí

2. datos simulados

Los datos simulados solo se pueden obtener a través de solicitudes ajax, para simular el papel de la interfaz de fondo

Definir datos data.json

[
  {
    
    
    "id": 1,
    "name": "TCL彩电",
    "price": 1000,
    "num": 1
  },
  {
    
    
    "id": 2,
    "name": "机顶盒",
    "price": 1000,
    "num": 1

  },
  {
    
    
    "id": 3,
    "name": "海尔冰箱",
    "price": 1000,
    "num": 1

  },
  {
    
    
    "id": 4,
    "name": "小米手机",
    "price": 1000,
    "num": 1

  },
  {
    
    
    "id": 5,
    "name": "PPTV电视",
    "price": 1000,
    "num": 2

  }
]

Proporcionar interfaz de datos mockServer.js

/*
使用mockjs提供mock数据接口
 */
import Mock from 'mockjs'
import data from './data.json'

// 返回goods的接口
Mock.mock('/', {
    
    data:data});

// export default ???  不需要向外暴露任何数据, 只需要保存能执行即可

Importación de main.js

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import store from './store'  // 导入vuex
import './mock/mockServer'  // 导入mock接口


Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
    
    
  el: '#app',
  store,  // 实例化
  components: {
    
     App },
  template: '<App/>'
})

3. gestión del estado de vuex

action.js


/*
  通过mutation间接更新state的多个方法
 */

import {
    
    LIST, DELETE_GOOD, ADD_GOOD_COUNT, SUB_GOOD_COUNT, UPDATE_GOOD_COUNT} from './mutation_types'
import axios from 'axios'

export default {
    
    
  // 异步请求mock数据接口获取list数据
  async reqList({
    
    commit}){
    
    
    const result = await axios.get('/');
    const list = result.data.data;
    commit(LIST, {
    
    list})
  },
  // 删除商品
  deleteGood({
    
    commit}, id){
    
    
    commit(DELETE_GOOD, {
    
    id})
  },
  // 添加商品
  addGood({
    
    commit}, id){
    
    
    commit(ADD_GOOD_COUNT, {
    
    id})
  },
  // 减少商品
  subGood({
    
    commit}, id){
    
    
    commit(SUB_GOOD_COUNT, {
    
    id})
  },
  // 更新商品
  updateGood({
    
    commit}, {
    
    id, value}){
    
    
    commit(UPDATE_GOOD_COUNT, {
    
    id, value})
  }
}

getters.js

/*
包含多个基于state的getter计算属性的对象
 */

export default {
    
    
  // 计算商品总数
  total(state){
    
    
    let sumPrice = 0;
    state.list.forEach((item)=>{
    
    
      sumPrice += item.price * item.num
    });
    return sumPrice
  }
}

index.js

/*
vuex最核心的管理对象store
 */
import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import mutations from './mutation'
import actions from './action'
import getters from './getters'

Vue.use(Vuex);

export default new Vuex.Store({
    
    
  state,
  mutations,
  actions,
  getters
})

mutatioan.js


/*
  直接更新state的多个方法
 */

import {
    
     LIST, DELETE_GOOD, ADD_GOOD_COUNT, SUB_GOOD_COUNT, UPDATE_GOOD_COUNT} from './mutation_types'

export default {
    
    

  [LIST](state, {
    
    list}){
    
    
    state.list = list
  },
  [DELETE_GOOD](state, {
    
    id}){
    
    
    // 通过id获取索引
    const index = state.list.findIndex(item=>{
    
    
      return item.id === id;
    });
    state.list.splice(index,1)
  },

  [ADD_GOOD_COUNT](state, {
    
    id}){
    
    
    // 通过id获取索引
    const index = state.list.findIndex(item=>{
    
    
      return item.id === id;
    });

    state.list[index].num ++
  },
  [SUB_GOOD_COUNT](state, {
    
    id}){
    
    
    // 通过id获取索引
    const index = state.list.findIndex(item=>{
    
    
      return item.id === id;
    });
    state.list[index].num --
  },

  [UPDATE_GOOD_COUNT](state, {
    
    id, value}){
    
    
    // 通过id获取索引
    const index = state.list.findIndex(item=>{
    
    
      return item.id === id;
    });
    state.list[index].num = value;
  },
}

mutation_type.js

/*
  所有常量
 */


export const LIST = 'list';  // 数据列表

export const DELETE_GOOD = 'delete_good';  //  删除商品

export const ADD_GOOD_COUNT = 'add_good_count';  // 添加商品数量
export const SUB_GOOD_COUNT = 'sub_good_count';  // 减少商品数量
export const UPDATE_GOOD_COUNT = 'update_good_count';  // 修改商品数量

state.js


/*
  所有管理的状态对象
 */
export default {
    
    

  list: []
}

Importación de main.js, ver arriba

4. Uso de componentes

app.vue

<template>
  <div id="app">
    <div class="container">
      <div class="cart">

        <Header></Header>
        <!-- $event 接受子组件传过来的参数 -->
        <List :list="list" @del="del($event)" @changeNum="changeNum($event)"></List>
        <Footer :list="list"></Footer>

      </div>
    </div>
  </div>


</template>

<script>
    import Header from "./components/Header";
    import List from "./components/List";
    import Footer from "./components/Footer";

    import {
    
    mapState} from 'vuex'

    export default {
    
    
        components:{
    
    
            Header, List, Footer
        },
        computed:{
    
    
          ...mapState(['list'])
        },
        
        // 页面刷新请求数据
        mounted(){
    
    
          this.$store.dispatch('reqList')
        }
    }
</script>

<style type="text/css">
  .container {
    
    
  }

  .container .cart {
    
    
    width: 300px;
    margin: auto;
  }

  .container .title {
    
    
    background-color: lightblue;
    height: 40px;
    line-height: 40px;
    text-align: center;
    /*color: #fff;*/
  }

  .container .total {
    
    
    background-color: #FFCE46;
    height: 50px;
    line-height: 50px;
    text-align: center;
  }

  .container .total button {
    
    
    margin: 0 10px;
    background-color: #DC4C40;
    height: 35px;
    width: 80px;
    border: 0;
  }

  .container .total span {
    
    
    color: red;
    font-weight: bold;
  }

  .container .item {
    
    
    height: 55px;
    line-height: 55px;
    position: relative;
    border-top: 1px solid #ADD8E6;
  }

  .container .item img {
    
    
    width: 45px;
    height: 45px;
    margin: 5px;
  }

  .container .item .name {
    
    
    position: absolute;
    width: 90px;
    top: 0;
    left: 55px;
    font-size: 16px;
  }

  .container .item .change {
    
    
    width: 100px;
    position: absolute;
    top: 0;
    right: 50px;
  }

  .container .item .change a {
    
    
    font-size: 20px;
    width: 30px;
    text-decoration: none;
    background-color: lightgray;
    vertical-align: middle;
  }

  .container .item .change .num {
    
    
    width: 40px;
    height: 25px;
  }

  .container .item .del {
    
    
    position: absolute;
    top: 0;
    right: 0px;
    width: 40px;
    text-align: center;
    font-size: 40px;
    cursor: pointer;
    color: red;
  }

  .container .item .del:hover {
    
    
    background-color: orange;
  }
</style>


cabeza

<template>
  <div class="title">我的商品</div>
</template>

<script>
    export default {
    
    
        name: "Header"
    }
</script>

<style scoped>

</style>

Lista

<template>
  <div>
    <div class="item" v-for="item in list">
      <img src="../img/a.jpg">
      <div class="name"> {
    
    {
    
     item.name }} </div>
      <div class="change"><a href="" @click.prevent="sub(item.id)"></a>
        <input type="text" class="num" :value="item.num" @blur="updateCount(item.id, $event)">
        <a href="" @click.prevent="add(item.id)"></a></div>
      <div class="del" @click="del(item.id)">×</div>
    </div>

  </div>
</template>

<script>
  import {
    
    mapState} from  'vuex'
    export default {
    
    
        name: "List",
        computed:{
    
    
          ...mapState(['list'])
        },
        methods:{
    
    
          del(id){
    
    
              this.$store.dispatch('deleteGood', id)
          },

            add(id){
    
    
                this.$store.dispatch('addGood', id);

            },
            sub(id){
    
    
                this.$store.dispatch('subGood', id)
            },
            updateCount(id, event){
    
    

                this.$store.dispatch('updateGood',{
    
    id:id, value: event.target.value})
            }
        }
    }
</script>

<style scoped>

</style>

Cola

<template>
  <div class="total"><span>总价:{
    
    {
    
     total }}</span>

  </div>
</template>

<script>
  import {
    
    mapGetters} from 'vuex'
    export default {
    
    
        name: "Footer",
        props:['list'],
        computed:{
    
    
            ...mapGetters(['total'])
        }

    }
</script>

<style scoped>

</style>

Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/gklcsdn/article/details/111167553
Recomendado
Clasificación