美文网首页
vuex转载抄写

vuex转载抄写

作者: 糖醋里脊120625 | 来源:发表于2022-06-24 14:24 被阅读0次

vuex

import { InjectionKey } from 'vue';
import { createStore, useStore as baseUseStore, Store} from 'vuex';
import { Product } from '../interface';

export interface State{
    shoppingCart: Product[]
}
// 创建唯一类型key
export const key: InjectionKey<Store<State>> = Symbol();
export const store = createStore<State>({
    state:{
        shoppingCart:[]
    },
    getters:{
        isInCart(state,data){
            console.log(data)
            console.log(state.shoppingCart)
            return (data:any)=>{
                return state.shoppingCart.findIndex(item=>item.id === data.id) > -1 ? true : false;
            }
        }
    },
    mutations:{
        // 添加购物车
        ADD_TO_CARD(state,data){
            state.shoppingCart.push(data);
            console.log(state.shoppingCart)
        },
        // 更新购物车数量
        CHANGE_COUNT(state,{type,data}){
         return state.shoppingCart.map(item=>{
             if(data.id=== item.id){
                 item.count += type === 'add' ? 1 : -1;
             }
             return item;
         })
        },
        // 删除购物车
        REMOVE_BY_ID(state,id){
            state.shoppingCart = state.shoppingCart.filter(item=>item.id!==id);
        }
    }
})
export function useStore(){
    // 通过key给store提供类型
    return baseUseStore(key)
}

列表页

<template>
  <div class="products">
    <div v-if="!loading">
      <div class="product-list" 
        v-for="(item,index) in products" 
        :key="index" 
      >
        <!-- 笔者比较懒没有封装成组件,大家请无视 -->
        <span class="name">{{item.title}}</span>
        <span class="price">{{item.price}}元</span>
        <van-button 
          type="primary" 
          size="small" 
          @click="addHandle(item)"
        >加入购物车</van-button>
      </div>
    </div>
    <van-loading v-else />
  </div>
</template>
<script lang="ts">
import { defineComponent,ref }from 'vue';
import { Product } from '@src/interface/index.ts';
import { apiGetProducts } from '@src/api/index.ts';
import { useStore } from '@src/store/index.ts';
import { toast } from '@src/utility/index.ts';

export default defineComponent({
  name: "Products",
  setup(){
    const products= ref<Product[]>([]);
    const loading = ref(false);
    const { commit, getters } = useStore();
    // 获取产品列表
    const getProducts = async () => {
      loading.value = true;
      products.value = await apiGetProducts();
      loading.value = false;
    }
    // 加入购物车
    const addToCart = (product:Product) => {
      commit('ADD_TO_CARD',{
        title:product.title,
        count:1,
        id:product.id
      })
    }
    // 判断是否在购物车中已存在
    const isInCart = (product:Product)=>{
      return getters.isInCart(product);
    }
    const addHandle = (product:Product) => {
      // 如果已经存在
      if(isInCart(product)) return toast('已存在');
      addToCart(product);
      toast('添加成功')
    }
    getProducts();
    return {
      loading, // 加载状态
      products, // 商品列表
      addHandle // 添加购物车
    }
  },
})
</script>

详情页

<template>
  <div class="shopping-cart">
    <h2>我的购物车</h2>
    <div 
      class="product-info" 
      v-for="item in shoppingCart" 
      :key="item.id"
    >
      <span>{{item.title}}</span>
      <div class="btn-box">
        <button @click="changeCount('reduce',item)">-</button>
        <span>{{item.count}}</span>
        <button @click="changeCount('add',item)">+</button>
      </div>
      <van-button 
        type="danger" 
        size="small" 
        @click="removeHandle(item)"
      >删除</van-button>
    </div>
  </div>
</template>
<script lang="ts">
import { defineComponent, computed } from 'vue';
import { Product } from '@src/interface/index.ts';
import { useStore } from '@src/store/index.ts';
import { toast } from '@src/utility/index.ts';
export default defineComponent({
  name: "ShoppingCart",
  setup: () => {
    const { state,commit } = useStore();
    const shoppingCart = computed(()=>{
      return state.shoppingCart
    })
    // 更新购物车数量
    const changeCount = (type:string,data:Product) => {
      // 保证购物车中最小数量为1
      if(type === 'reduce' && data.count <= 1) return;
      commit('CHANGE_COUNT',{type,data})
    }
    // 删除购物车
    const removeCart = (data:Product) => {
      commit('REMOVE_BY_ID',data.id);
    }
    // 处理函数
    const removeHandle = (data:Product) => {
      removeCart(data);
      toast('删除成功')
    }
    return {
      shoppingCart, // 购物车列表
      changeCount, // 更新购物车数量
      removeHandle // 删除购物车
    }
  },
})
</script>
<style lang="less" scoped>
  @import './index.less';
</style>
<template>
  <nav-bar :count="count" :active="activeRouteName"></nav-bar>
  <div class="body">
    <router-view/>
  </div>
</template>
<script lang="ts">
import { computed, defineComponent } from 'vue'
import { useRoute } from 'vue-router'
import { useStore } from './store/index'
import NavBar from "@components/NavBar/index.vue";

export default defineComponent({
  name: 'App',
  components:{
    NavBar
  },
  setup() {
    const store = useStore();
    const route  = useRoute();
    const count = computed(():number=>{
      return store.state.shoppingCart.length;
    })
    const activeRouteName = computed(():string =>{
       // 由于name 可能有RouteRecordName | null | undefined类型
      return route.name?.toString() || '';
    })
    return {
      count,
      activeRouteName
    }
  },
})
</script>

相关文章

网友评论

      本文标题:vuex转载抄写

      本文链接:https://www.haomeiwen.com/subject/tunvvrtx.html