【Vue+DRF生鲜电商】25.商品添加购物车接口功能,Vue和购物车联调

专题:Vue+Django REST framework前后端分离生鲜电商

Vue+Django REST framework 打造前后端分离的生鲜电商项目(慕课网视频)。
Github地址:https://github.com/xyliurui/DjangoOnlineFreshSupermarket
Django版本:2.2、djangorestframework:3.9.2。

更多内容请点击 我的博客 查看,欢迎来访。

商品详情页点击加入购物车,就可以把商品加入到数据库【创建】。

对于购物车已存在的商品,如果将商品重复加入购物车,或者减少商品数量,就将它的数量进行加减【更新】。

购物车也支持对商品进行删除【删除】,以及列表展示【查询】。

综上,购物车就需要用到mixins中的所有功能。

商品添加到购物车功能实现

实现购物车视图,在 apps/trade/views.py 添加代码

from rest_framework import mixins, viewsets
from rest_framework.permissions import IsAuthenticated
from rest_framework.authentication import SessionAuthentication

from rest_framework_simplejwt.authentication import JWTAuthentication

from utils.permissions import IsOwnerOrReadOnly


class ShoppingCartViewSet(viewsets.ModelViewSet):
    """
    购物车功能实现
    list:
        获取购物车列表
    create:
        添加商品到购物车
    update:
        更新购物车商品数量
    delete:
        从购物车中删除商品
    """
    # 权限问题:购物车和用户权限关联,这儿和用户操作差不多
    permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)  # 用户必须登录才能访问
    authentication_classes = (JWTAuthentication, SessionAuthentication)  # 配置登录认证:支持JWT认证和DRF基本认证

以上就是购物车的权限和认证相关的问题,接下来开始完成Serializer的编写。

对比需要继承的serializers.ModelSerializerserializers.Serializer,根据项目逻辑需求,这儿用serializers.Serializer比较合适,因为它比较灵活。

如果用户对某个商品添加到购物车,之后再对该商品进行重复添加,那么是需要将购物车中的数据进行修改,也就是当前用户的购物车中的每一种商品都是唯一的,那么修改一下models,为其增加联合唯一的限定。

# apps/trade/models.py

class ShoppingCart(models.Model):
    """
    购物车
    """
    user = models.ForeignKey(User, verbose_name='用户', help_text='用户', on_delete=models.CASCADE, related_name='shopping_carts')
    goods = models.ForeignKey(Goods, verbose_name='商品', help_text='商品', on_delete=models.CASCADE)
    nums = models.IntegerField(default=0, verbose_name='购买数量', help_text='购买数量')
    add_time = models.DateTimeField(auto_now_add=True, verbose_name='添加时间')

    class Meta:
        verbose_name_plural = verbose_name = '购物车'
        unique_together = ['user', 'goods']  # 用户和商品联合唯一

    def __str__(self):
        return "{}({})".format(self.goods.name, self.nums)

那么试想下,如果 user 和 goods 已经存在了,再向购物车添加同一个商品,不希望得到验证说这个商品已经存在,而是希望在当前数量上加1。

如果使用的是serializers.ModelSerializer,模型中定义了unique_together = ['user', 'goods'],进行validate时就会抛出异常,就算是重写def create(self, validated_data)方法也是无效的,因为在进行该方法前,就已经进行了validate。继续解释下,ShoppingCartViewSet继承的是viewsets.ModelViewSet,在这里面有个mixins.CreateModelMixin

BLOG_20190719_191509_29

这个CreateModelMixincreate的时候首先会调用serializer.is_valid(raise_exception=True),接下来会调用self.perform_create(serializer)执行数据保存serializer.save(),在验证的时候就已经报错了,就不会调用create方法了,所以是无法保存成功的。

当然,我们也可以重写CreateModelMixin中的create的方法,就可以控制该方法的所有步骤。

如果不用serializer,那么它的验证功能就享受不到了,不用serializer做,就需要在views中去完成;另外生成文档的时候,字段是从serializer中取得,如果不用那么文档的功能就缺失了。

用了serializer,但用的是serializers.ModelSerializer,那么刚才的验证是通不过的。所以这儿用底层的serializers.Serializer,自己来做validate

购物车序列化ShoppingCartSerializer

下面一步一步去完成,ShoppingCart模型中用到了usergoodsnums这几个重要的字段,user和之前用户操作中一样,直接复制过来即可。

# apps/trade/serializers.py

from rest_framework import serializers
from goods.models import Goods


class ShoppingCartSerializer(serializers.Serializer):
    user = serializers.HiddenField(
        default=serializers.CurrentUserDefault()  # 表示user为隐藏字段,默认为获取当前登录用户
    )
    nums = serializers.IntegerField(required=True, min_value=1, label='商品数量', help_text='商品数量',
                                    error_messages={
                                        'min_value': '商品数量不能小于1',
                                        'required': '请选择购买数量'
                                    })
    goods = serializers.PrimaryKeyRelatedField(queryset=Goods.objects.all(), required=True, label='商品')

分析:访问 https://www.django-rest-framework.org/api-guide/fields/ 可以看到DRF提供的Serializer字段;而像外键这个关系型的,可以查看 https://www.django-rest-framework.org/api-guide/relations/PrimaryKeyRelatedField就是需要在这goods用到的

参数说明:

  • queryset:在验证字段输入时用于模型实例查找的queryset。关系必须显式设置queryset,或者设置read_only=True
  • many:如果应用于多对多关系,则应将此参数设置为True
  • allow_null:如果设置为True,该字段将接受None值或空字符串,用于可空关系。默认值为False
  • pk_field:设置为一个字段来控制主键值的序列化/反序列化。例如,pk_field=UUIDField(format='hex')将把UUID主键序列化为紧凑的十六进制表示形式。

ShoppingCartSerializer添加商品重写create()方法

由于使用的是serializers.Serializer,没有定义create()方法,需要自己去重写。而ModelSerializer是写好了该方法。

用户在添加购物车时,也就是在数据库中添加一条记录。还要分为两种情况,当购物车数据库中没有这个商品时,执行添加;当已存在该商品时,执行数量更新。

validated_data也就是上方定义的字段传过来之前已经处理好的数据,例如,nums如果数量为负数,那么该数据到不了create()方法。

# apps/trade/serializers.py

from rest_framework import serializers
from goods.models import Goods
from trade.models import ShoppingCart


class ShoppingCartSerializer(serializers.Serializer):
    user = serializers.HiddenField(
        default=serializers.CurrentUserDefault()  # 表示user为隐藏字段,默认为获取当前登录用户
    )
    nums = serializers.IntegerField(required=True, min_value=1, label='商品数量', help_text='商品数量',
                                    error_messages={
                                        'min_value': '商品数量不能小于1',
                                        'required': '请选择购买数量'
                                    })
    goods = serializers.PrimaryKeyRelatedField(queryset=Goods.objects.all(), required=True, label='商品')

    def create(self, validated_data):
        user = self.context['request'].user  # serializer中获取当前用户,而views是直接从request中获取
        nums = validated_data['nums']
        goods = validated_data['goods']

        # 查询记录是否存在,存在,则进行数量加,不存在则新创建
        shopping_cart = ShoppingCart.objects.filter(user=user, goods=goods)
        if shopping_cart:
            shopping_cart = shopping_cart.first()
            shopping_cart.nums += nums
            shopping_cart.save()
        else:
            shopping_cart = ShoppingCart.objects.create(**validated_data)
        # 最后要返回创建后的结果
        return shopping_cart

ShoppingCartViewSet中获取当前登录用户购物车

首先引入上方创建好的序列化类,并且指定queryset,只能显示当前登录用户的购物车列表

# apps/trade/views.py

from .serializers import ShoppingCartSerializer
from .models import ShoppingCart


class ShoppingCartViewSet(viewsets.ModelViewSet):
    """
    购物车功能实现
    list:
        获取购物车列表
    create:
        添加商品到购物车
    update:
        更新购物车商品数量
    delete:
        从购物车中删除商品
    """
    # 权限问题:购物车和用户权限关联,这儿和用户操作差不多
    permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)  # 用户必须登录才能访问
    authentication_classes = (JWTAuthentication, SessionAuthentication)  # 配置登录认证:支持JWT认证和DRF基本认证
    serializer_class = ShoppingCartSerializer
    queryset = ShoppingCart.objects.all()

    def get_queryset(self):
        # 只能显示当前用户的购物车列表
        return self.queryset.filter(user=self.request.user)

[外链图片转存失败(img-Y80mxmPa-1563550151566)(https://blog.starmeow.cn/media/blog/images/2019/07/BLOG_20190719_191447_50.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 “博客图集BLOG_20190719_191447_50.png”)]

选择某个商品添加到购物车,会返回该商品的id和添加的数量。

[外链图片转存失败(img-2Q2WCa3i-1563550151566)(https://blog.starmeow.cn/media/blog/images/2019/07/BLOG_20190719_191440_59.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 “博客图集BLOG_20190719_191440_59.png”)]

再访问 http://127.0.0.1:8000/shoppingcart/ 可以看到购物车已有的商品id及数量。

修改购物车中商品数量

ShoppingCartSerializer指定商品更新重写update()方法

由于每个用户的购物车商品都是唯一的,所以只需要传递商品的id,就可以获取到该记录。

# apps/trade/serializers.py

class ShoppingCartViewSet(viewsets.ModelViewSet):
    """
    购物车功能实现
    list:
        获取购物车列表
    create:
        添加商品到购物车
    update:
        更新购物车商品数量
    delete:
        从购物车中删除商品
    """
    # 权限问题:购物车和用户权限关联,这儿和用户操作差不多
    permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)  # 用户必须登录才能访问
    authentication_classes = (JWTAuthentication, SessionAuthentication)  # 配置登录认证:支持JWT认证和DRF基本认证
    serializer_class = ShoppingCartSerializer
    queryset = ShoppingCart.objects.all()
    lookup_field = 'goods'

    def get_queryset(self):
        # 只能显示当前用户的购物车列表
        return self.queryset.filter(user=self.request.user)

比如上方商品id为105的购物车,可以直接访问 http://127.0.0.1:8000/shoppingcart/105/ 获取该购物车详情

[外链图片转存失败(img-4XX04zvR-1563550151567)(https://blog.starmeow.cn/media/blog/images/2019/07/BLOG_20190719_191429_74.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 “博客图集BLOG_20190719_191429_74.png”)]

在这就可以对商品进行删除,也可以对商品数量进行更新。测试下更新,修改商品数量,然后点击PUT,就报错了

    raise NotImplementedError('`update()` must be implemented.')
NotImplementedError: `update()` must be implemented.

意思就是没有update()方法。

可以查看rest的源码 rest_framework.serializers.Serializer,这个类继承的BaseSerializer有这样一个方法:

# 源码:rest_framework.serializers.BaseSerializer#update
    def update(self, instance, validated_data):
        raise NotImplementedError('`update()` must be implemented.')

Serializer没有重写update()方法,使用时会抛出上面的异常。而ModelSerializer是有该方法的rest_framework.serializers.ModelSerializer#update,所以直接拿来用不会报错。

[外链图片转存失败(img-RnfjbRn6-1563550151567)(https://blog.starmeow.cn/media/blog/images/2019/07/BLOG_20190719_191421_50.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 “博客图集BLOG_20190719_191421_50.png”)]

现在数量新的商品数量后,在点击PUT就不会报错了,数量也能正常更新。

测试指定商品删除

测试删除功能,可以指定商品进行删除,删除没有返回结果。也无须重写删除方法

[外链图片转存失败(img-Nf5RIoKz-1563550151567)(https://blog.starmeow.cn/media/blog/images/2019/07/BLOG_20190719_191414_18.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 “博客图集BLOG_20190719_191414_18.png”)]

BLOG_20190719_191409_62

访问 http://127.0.0.1:8000/docs/#shoppingcart-list ,在文档页面也会出现刚才添加的接口

[外链图片转存失败(img-8YLH1Op0-1563550151568)(https://blog.starmeow.cn/media/blog/images/2019/07/BLOG_20190719_191401_74.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 “博客图集BLOG_20190719_191401_74.png”)]

Vue和购物车接口联调

ShoppingCartListSerializer购物车显示商品列表

现在购物车中只有商品的id,但是一般还需要显示商品的图片、名称、单价等信息。

而现在ShoppingCartSerializergoods=serializers.PrimaryKeyRelatedField(queryset=Goods.objects.all(), required=True, label='商品')关联商品的主键id,所以要动态设置Serializer,这是个ModelSerializer

新建一个Serializer

# apps/trade/serializers.py

from goods.serializers import GoodsSerializer


class ShoppingCartListSerializer(serializers.ModelSerializer):
    goods = GoodsSerializer(many=False)  # 一个购物车的记录只会对应一个商品,默认many=False,也就是可以不写

    class Meta:
        model = ShoppingCart
        fields = "__all__"

ShoppingCartViewSet购物车动态使用序列化类

然后在ViewSet中动态获取要使用的Serializer

# apps/trade/views.py

from .serializers import ShoppingCartSerializer, ShoppingCartListSerializer

class ShoppingCartViewSet(viewsets.ModelViewSet):
    """
    购物车功能实现
    list:
        获取购物车列表
    create:
        添加商品到购物车
    update:
        更新购物车商品数量
    delete:
        从购物车中删除商品
    """
    # 权限问题:购物车和用户权限关联,这儿和用户操作差不多
    permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)  # 用户必须登录才能访问
    authentication_classes = (JWTAuthentication, SessionAuthentication)  # 配置登录认证:支持JWT认证和DRF基本认证
    # serializer_class = ShoppingCartSerializer  # 使用get_serializer_class(),这个就不需要了
    queryset = ShoppingCart.objects.all()
    lookup_field = 'goods'

    def get_serializer_class(self):
        if self.action == 'list':
            # 当获取购物车列表时,使用ModelSerializer,可以显示购物车商品详情
            return ShoppingCartListSerializer
        else:
            return ShoppingCartSerializer

    def get_queryset(self):
        # 只能显示当前用户的购物车列表
        return self.queryset.filter(user=self.request.user)

现在访问 http://127.0.0.1:8000/shoppingcart/ 可以看到购物车商品列表

[外链图片转存失败(img-2yNhWIQM-1563550151568)(https://blog.starmeow.cn/media/blog/images/2019/07/BLOG_20190719_191347_89.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 “博客图集BLOG_20190719_191347_89.png”)]

只有在显示购物车列表时才会用到这个序列化类,显示某个商品详情,或更新就是用之前的类

Vue中配置购物车接口

修改接口,添加购物车的相关接口

// src/api/api.js

//获取购物车商品
export const getShopCarts = params => {
    return axios.get(`${local_host}/shoppingcart/`)
};
// 添加商品到购物车
export const addShopCart = params => {
    return axios.post(`${local_host}/shoppingcart/`, params)
};
//更新购物车商品信息
export const updateShopCart = (goodsId, params) => {
    return axios.patch(`${local_host}/shoppingcart/` + goodsId + '/', params)
};
//删除某个商品的购物记录
export const deleteShopCart = goodsId => {
    return axios.delete(`${local_host}/shoppingcart/` + goodsId + '/')
};

选择某一商品,点击添加到购物车

[外链图片转存失败(img-Q4qw6vyK-1563550151569)(https://blog.starmeow.cn/media/blog/images/2019/07/BLOG_20190719_191339_17.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 “博客图集BLOG_20190719_191339_17.png”)]

访问 http://127.0.0.1:8080/#/app/shoppingcart/cart 购物车可以查看到列表

[外链图片转存失败(img-vWGjsdMm-1563550151569)(https://blog.starmeow.cn/media/blog/images/2019/07/BLOG_20190719_191332_29.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 “博客图集BLOG_20190719_191332_29.png”)]

Vue加入购物车逻辑分析

加入购物车按钮位置

<!-- src/views/productDetail/productDetail.vue-->

<a class="btn" id="buy_btn" @click="addShoppingCart">
    <i class="iconfont">&#xe600;</i>
    加入购物车
</a>

当点击加入购物车按钮时,会调用

// src/views/productDetail/productDetail.vue

addShoppingCart() { //加入购物车
    addShopCart({
        goods: this.productId, // 商品id
        nums: this.buyNum, // 购买数量
    }).then((response) => {
        this.$refs.model.setShow();
        // 更新store数据
        this.$store.dispatch('setShopList');

    }).catch(function (error) {
        console.log(error);
    });
},

这里面会请求addShopCart传递商品的id和购买数量,这个数量和输入框的值一样,直接请求api中创建购物车的接口

// src/api/api.js

// 添加商品到购物车
export const addShopCart = params => {
    return axios.post(`${local_host}/shoppingcart/`, params)
};

当提交成功后,会请示this.$refs.model.setShow()显示添加成功的弹框。

页面顶部显示购物车简单列表

然后this.$store.dispatch('setShopList');更新vuex,点击setShopList可以访问到src/store/actions.jsexport const setShopList = makeAction(types.SET_SHOPLIST);,实际上就是src/store/mutations.js

// src/store/mutations.js

[types.SET_SHOPLIST](state) { //设置购物车数据
    // token = cookie.getCookie('token')
    if (cookie.getCookie('token') != null) {
        getShopCarts().then((response) => {
            // 更新store数据
            state.goods_list.goods_list = response.data;
            //console.log(response.data);
            var totalPrice = 0;
            response.data.forEach(function (entry) {
                totalPrice += entry.goods.shop_price * entry.nums
            });
            state.goods_list.totalPrice = totalPrice;

        }).catch(function (error) {
            console.log(error);
        });
    }
},

这一段的意思就是调用getShopCarts()函数,获取到购物车的商品,将这些商品的数据填充到state中,更新src/store/store.jsgoods_list.goods_list

const goods_list =  {
       totalPrice:'',
        goods_list:[]

    }

经过Vue的处理,显示到顶部

BLOG_20190719_191321_46

<!-- src/views/head/head.vue-->

<div class="hd_cart" id="ECS_CARTINFO" @mouseover="overShopCar" @mouseout="outShopCar">
    <router-link class="tit" :to="'/app/shoppingcart/cart'" target=_blank>

        <b class="iconfont">&#xe600;</b>去购物车结算<span><i class="iconfont">&#xe645;</i></span>
        <em class="num" id="hd_cartnum"
            style="visibility: visible;">{{goods_list.goods_list.length}}</em>
    </router-link>
    <div class="list" v-show="showShopCar">
        <div class="data">
            <dl v-for="(item,index) in goods_list.goods_list">
                <dt>
                    <router-link :to="'/app/home/productDetail/'+item.goods.id" target=_blank><img
                            :src="item.goods.goods_front_image"></router-link>
                </dt>
                <dd>
                    <h4>
                        <router-link :to="'/app/home/productDetail/'+item.goods.id" target=_blank>
                            {{item.goods.name}}
                        </router-link>
                    </h4>
                    <p><span class="red">{{item.goods.shop_price}}</span>&nbsp;<i>X</i>&nbsp;{{item.nums}}
                    </p>
                    <a title="删除" class="iconfont del" @click="deleteGoods(index,item.goods.id)">×</a>
                </dd>
            </dl>
        </div>
        <div class="count"><span class="red" id="hd_cart_count">{{goods_list.goods_list.length}}</span>件商品哦~
            <p>总价:<span class="red"><em id="hd_cart_total">{{goods_list.totalPrice}}</em></span>
                <router-link class="btn" :to="'/app/shoppingcart/cart'" target=_blank>去结算
                </router-link>
            </p>
        </div>
    </div>
</div>
购物车列表显示功能

当进入购物车页面时 http://127.0.0.1:8080/#/app/shoppingcart/cart 组件创建

//src/views/cart/cart.vue

created() {
    // 请求购物车商品
    getShopCarts().then((response) => {
        //console.log(response.data);
        // 更新store数据
        //this.goods_list = response.data;
        var totalPrice = 0;
        this.goods.goods_list = response.data;
        response.data.forEach(function (entry) {
            totalPrice += entry.goods.shop_price * entry.nums
            //console.log(entry.goods.shop_price);
        });

        this.goods.totalPrice = totalPrice
        this.totalPrice = totalPrice
    }).catch(function (error) {
    });
    this.getAllAddr()
},

然后向html中填充数据

<!-- src/views/cart/cart.vue -->

<li class="cle hover" style="border-bottom-style: none;" v-for="(item,index) in goods.goods_list">
    <div class="pic">
        <a target="_blank"> <img :alt="item.goods.name" :src="item.goods.goods_front_image"></a>
    </div>
    <div class="name">
        <a target="_blank">{{item.goods.name}}</a>
        <p></p>
    </div>
    <div class="price-xj">
        <p><em>¥{{item.goods.shop_price}}元</em></p>
    </div>
    <div class="nums" id="nums">
        <span class="minus" title="减少1个数量" @click="reduceCartNum(index, item.goods.id);">-</span>
        <input type="text" v-model="item.nums">
        <span class="add" title="增加1个数量" @click="addCartNum(index, item.goods.id);">+</span>
    </div>
    <div class="price-xj"><span></span>
        <em id="total_items_3137">¥{{item.goods.shop_price * item.nums}}元</em>
    </div>
    <div class="del">
        <a class="btn-del" @click="deleteGoods(index, item.goods.id)">删除</a>
    </div>
</li>
购物车中删除商品功能

当点击删除时,执行deleteGoods(index, item.goods.id),传递商品的id

// src/views/cart/cart.vue

deleteGoods(index, id) { //移除购物车
    alert('您确定把该商品移除购物车吗');
    deleteShopCart(id).then((response) => {
        //console.log(response.data);
        this.goods.goods_list.splice(index, 1);

        // 更新store数据
        this.$store.dispatch('setShopList');

    }).catch(function (error) {
        console.log(error);
    });
},

接下俩调用删除deleteShopCart(id)的api

// src/api/api.js

//删除某个商品的购物记录
export const deleteShopCart = goodsId => {
    return axios.delete(`${local_host}/shoppingcart/` + goodsId + '/')
};

删除成功后更新Vue中显示的购物车商品列表数据

购物车更新商品数量功能

在购物车中有一个增加数量和减少数量的按钮

<!-- src/views/cart/cart.vue -->

<div class="nums" id="nums">
    <span class="minus" title="减少1个数量" @click="reduceCartNum(index, item.goods.id);">-</span>
    <input type="text" v-model="item.nums">
    <span class="add" title="增加1个数量" @click="addCartNum(index, item.goods.id);">+</span>
</div>

点击reduceCartNum(index, item.goods.id),减少一个数量

// src/views/cart/cart.vue

reduceCartNum(index, id) { //删除数量
    if (this.goods.goods_list[index].nums <= 1) {
        this.deleteGoods(index, id)
    } else {
        updateShopCart(id, {
            nums: this.goods.goods_list[index].nums - 1
        }).then((response) => {
            this.goods.goods_list[index].nums = this.goods.goods_list[index].nums - 1;
            // 更新store数据
            this.$store.dispatch('setShopList');
            //更新总价
            this.setTotalPrice();

        }).catch(function (error) {
            console.log(error);
        });
    }
},

当数量减小到0,就从购物车删除该商品。

更新购物车updateShopCart()指定商品的id,传递数量(当前的数量-1)提交到api

// src/api/api.js

//更新购物车商品信息
export const updateShopCart = (goodsId, params) => {
    return axios.patch(`${local_host}/shoppingcart/` + goodsId + '/', params)
};

提交成功后更新购物车商品数据。

当点击addCartNum(index, item.goods.id)增加1个数量时,调用

// src/views/cart/cart.vue

addCartNum(index, id) { //添加数量
    updateShopCart(id, {
        nums: this.goods.goods_list[index].nums + 1
    }).then((response) => {
        this.goods.goods_list[index].nums = this.goods.goods_list[index].nums + 1;
        // 更新store数据
        this.$store.dispatch('setShopList');
        //更新总价
        this.setTotalPrice();

    }).catch(function (error) {
        console.log(error);
    });
},

请求updateShopCart()指定商品的id,传递数量(当前的数量+1)提交到api,提交成功后Vue中将当前商品数量+1,并更新购物车中的数据。

购物车收货地址获取
<li v-for="item in addrInfo" :class="{'addressActive':addressActive==item.id}" @click="selectAddr(item.id)">
    <p class="item">地址:{{item.province}} {{item.city}} {{item.district}} {{item.address}}</p>
    <p class="item">电话:{{item.signer_mobile}}</p>
    <p class="item">姓名:{{item.signer_name}}</p>
</li>

组件创建时,获取所有的收货地址,遍历显示到页面

// src/views/cart/cart.vue

getAllAddr() { //获得所有配送地址
    getAddress().then((response) => {
        this.addrInfo = response.data;
    }).catch(function (error) {
        console.log(error);
    });
},
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值