mirror of
http://git.coreshop.cn/jianweie/coreshoppro.git
synced 2025-12-06 20:03:26 +08:00
uniapp【修复】:sku优化多层选择,默认,置灰等问题
This commit is contained in:
@@ -134,6 +134,7 @@ export interface GoodsSkuListType {
|
|||||||
sku_name_arr ?: Array<string>;
|
sku_name_arr ?: Array<string>;
|
||||||
stock ?: number;
|
stock ?: number;
|
||||||
_id ?: string
|
_id ?: string
|
||||||
|
[key:string]:any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GoodsSpecListType {
|
export interface GoodsSpecListType {
|
||||||
@@ -141,6 +142,7 @@ export interface GoodsSpecListType {
|
|||||||
name ?: string;
|
name ?: string;
|
||||||
select ?: boolean;
|
select ?: boolean;
|
||||||
show ?: boolean;
|
show ?: boolean;
|
||||||
|
[key:string]:any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GoodsFootprintType {
|
export interface GoodsFootprintType {
|
||||||
|
|||||||
@@ -56,11 +56,10 @@
|
|||||||
.tag {
|
.tag {
|
||||||
position: relative;
|
position: relative;
|
||||||
font-size: 27rpx;
|
font-size: 27rpx;
|
||||||
padding: 15rpx 20rpx;
|
border: 1rpx solid #f4f4f4;
|
||||||
border: 1rpx solid #6e737d;
|
|
||||||
border-radius: 15rpx;
|
border-radius: 15rpx;
|
||||||
text-align: center;
|
margin: inherit;
|
||||||
height: max-content;
|
background-color: #fff;
|
||||||
.icon-select {
|
.icon-select {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
@@ -68,6 +67,9 @@
|
|||||||
width: 28rpx;
|
width: 28rpx;
|
||||||
height: 30rpx;
|
height: 30rpx;
|
||||||
}
|
}
|
||||||
|
&:after{
|
||||||
|
content: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.active {
|
.active {
|
||||||
border: 1px solid #d33123;
|
border: 1px solid #d33123;
|
||||||
@@ -75,9 +77,9 @@
|
|||||||
background-color: rgba(211, 49, 35, 0.04);
|
background-color: rgba(211, 49, 35, 0.04);
|
||||||
}
|
}
|
||||||
.gray {
|
.gray {
|
||||||
border: 1px solid #eee;
|
color: #c3c3c3;
|
||||||
background-color: #eee;
|
border-color: #f6f6f6;
|
||||||
color: #6e737d;
|
background-color: #f6f6f6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,230 +1,283 @@
|
|||||||
<template>
|
<template>
|
||||||
<uv-popup ref="skuPopup" mode="bottom" :closeable="true" :safeAreaInsetBottom="props.safeAreaInsetBottom"
|
<uv-popup ref="skuPopup" mode="bottom" :closeable="true" :safeAreaInsetBottom="props.safeAreaInsetBottom"
|
||||||
@change="handleChangePopup">
|
@change="handleChangePopup">
|
||||||
<view class="sku-content">
|
<view class="sku-content">
|
||||||
<view class="godds-box">
|
<view class="godds-box">
|
||||||
<image class="img" :src="state?.chooseSku?.image"></image>
|
<image class="img" :src="state?.chooseSku?.image"></image>
|
||||||
<view class="price-box">
|
<view class="price-box">
|
||||||
<view class="price">¥{{ state.chooseSku?.price }}</view>
|
<view class="price">¥{{ state.chooseSku?.price }}</view>
|
||||||
<view class="stock">库存:{{ state.chooseSku?.stock }}</view>
|
<view class="stock">库存:{{ state.chooseSku?.stock }}</view>
|
||||||
<view class="specs">规格:{{ state.chooseSku?.sku_name_arr?.join(',') }}</view>
|
<view class="specs">规格:{{ state.chooseSku?.sku_name_arr?.join(',') }}</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="specs-box">
|
<view class="specs-box">
|
||||||
<view class="item-box" v-for="item, index in state?.spec_list" :key="index">
|
<view class="item-box" v-for="item, index in state?.spec_list" :key="index">
|
||||||
<view class="title">{{ item.name }}</view>
|
<view class="title">{{ item.name }}</view>
|
||||||
<view class="tag-box">
|
<view class="tag-box">
|
||||||
<view v-for="itemChild, indexChild in item?.list" :key="indexChild"
|
<button v-for="itemChild, indexChild in item?.list" :key="indexChild"
|
||||||
:class="['tag', { 'active': itemChild.select }, { 'gray': !itemChild.show && state.skuLength == 1 }]"
|
:class="['tag',{'active':getSkuSelected(itemChild.name)},{'gray':getSkuDisabled(itemChild.name)}]"
|
||||||
@click="handleChooseSku(index, itemChild)">
|
@click="handleChooseSku(itemChild.name)" :disabled="getSkuDisabled(itemChild.name)">
|
||||||
{{ itemChild.name }}
|
{{ itemChild.name }}
|
||||||
<image v-if="itemChild.select" class="icon-select"
|
<image v-if="getSkuSelected(itemChild.name)" class="icon-select"
|
||||||
:src="handleStaticResources('/static/images/tag-select.png')"> </image>
|
:src="handleStaticResources('/static/images/tag-select.png')"> </image>
|
||||||
</view>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="number-box">
|
<view class="number-box">
|
||||||
<view class="tit">数量:</view>
|
<view class="tit">数量:</view>
|
||||||
<uv-number-box v-model="state.numberVal" :disabledInput="true"
|
<uv-number-box v-model="state.numberVal" :disabledInput="true"
|
||||||
@change="handleChangeNumberVal"></uv-number-box>
|
@change="handleChangeNumberVal"></uv-number-box>
|
||||||
</view>
|
</view>
|
||||||
<view class="btn-box">
|
<view class="btn-box">
|
||||||
<!-- <view v-if="props.isShowAddCartBtn" class="btn add-cart" @click="handleAddCart">加入购物车</view> -->
|
<!-- <view v-if="props.isShowAddCartBtn" class="btn add-cart" @click="handleAddCart">加入购物车</view> -->
|
||||||
<view v-if="props.isShowAddCartBtn" class="core-button-confirm add-cart">
|
<view v-if="props.isShowAddCartBtn" class="core-button-confirm add-cart">
|
||||||
<coreshop-button :loading="props.addCartloading" class="core-button-confirm_" :radius="0" title="加入购物车"
|
<coreshop-button :loading="props.addCartloading" class="core-button-confirm_" :radius="0"
|
||||||
:customStyle="addCartCustomStyle" @onClick="handleAddCart()"></coreshop-button>
|
title="加入购物车" :customStyle="addCartCustomStyle" @onClick="handleAddCart()"></coreshop-button>
|
||||||
</view>
|
</view>
|
||||||
<!-- <view class="btn buy-now" @click="handleBuyNow">{{ props.btnBuyTitlt }}</view> -->
|
<!-- <view class="btn buy-now" @click="handleBuyNow">{{ props.btnBuyTitlt }}</view> -->
|
||||||
<view class="core-button-confirm">
|
<view class="core-button-confirm">
|
||||||
<coreshop-button :loading="props.buyNowNowloading" class="core-button-confirm_" :radius="0"
|
<coreshop-button :loading="props.buyNowNowloading" class="core-button-confirm_" :radius="0"
|
||||||
:title="props.btnBuyTitlt" :customStyle="buyNowCustomStyle" @onClick="handleBuyNow()"></coreshop-button>
|
:title="props.btnBuyTitlt" :customStyle="buyNowCustomStyle"
|
||||||
</view>
|
@onClick="handleBuyNow()"></coreshop-button>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</uv-popup>
|
</view>
|
||||||
|
</uv-popup>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { watch, reactive, ref } from 'vue';
|
import { watch, reactive, ref, computed } from 'vue';
|
||||||
import type { GoodsSkuListType, GoodsSpecListType } from '@/core/models';
|
import type { GoodsSkuListType, GoodsSpecListType } from '@/core/models';
|
||||||
import { handleStaticResources, handleShowToast } from '@/core/utils';
|
import { handleStaticResources, handleShowToast } from '@/core/utils';
|
||||||
import { deepClone } from '@/uni_modules/uv-ui-tools/libs/function/index.js';
|
import { deepClone } from '@/uni_modules/uv-ui-tools/libs/function/index.js';
|
||||||
|
|
||||||
const buyNowCustomStyle = {
|
type SpecWeight = Record<string, {
|
||||||
'border': 'none',
|
weight : number;
|
||||||
'background-color': '#d33123',
|
sort : number;
|
||||||
'flex': 1,
|
}>
|
||||||
'padding': '32rpx 0',
|
|
||||||
'font-size': '27rpx',
|
|
||||||
'text-align': 'center',
|
|
||||||
'color': '#fff',
|
|
||||||
'height': '90rpx'
|
|
||||||
}
|
|
||||||
|
|
||||||
const addCartCustomStyle = {
|
type SelectedSpec = {
|
||||||
...buyNowCustomStyle,
|
name : string;
|
||||||
'background-color': '#000',
|
weight : number;
|
||||||
}
|
sort : number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const buyNowCustomStyle = {
|
||||||
|
'border': 'none',
|
||||||
|
'background-color': '#d33123',
|
||||||
|
'flex': 1,
|
||||||
|
'padding': '32rpx 0',
|
||||||
|
'font-size': '27rpx',
|
||||||
|
'text-align': 'center',
|
||||||
|
'color': '#fff',
|
||||||
|
'height': '90rpx'
|
||||||
|
}
|
||||||
|
|
||||||
|
const addCartCustomStyle = {
|
||||||
|
...buyNowCustomStyle,
|
||||||
|
'background-color': '#000',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
showSku : boolean,
|
showSku : boolean,
|
||||||
goodsDetailData : any,
|
goodsDetailData : any,
|
||||||
isShowAddCartBtn : boolean,
|
isShowAddCartBtn : boolean,
|
||||||
btnBuyTitlt : string,
|
btnBuyTitlt : string,
|
||||||
safeAreaInsetBottom : boolean;
|
safeAreaInsetBottom : boolean;
|
||||||
buyNowCustomStyle : { [key : string] : any },
|
buyNowCustomStyle : any,
|
||||||
buyNowNowloading : boolean,
|
buyNowNowloading : boolean,
|
||||||
addCartloading : boolean
|
addCartloading : boolean
|
||||||
}>(), {
|
}>(), {
|
||||||
showSku: false,
|
showSku: false,
|
||||||
goodsDetailData: {},
|
goodsDetailData: {},
|
||||||
isShowAddCartBtn: true,
|
isShowAddCartBtn: true,
|
||||||
btnBuyTitlt: '立即购买',
|
btnBuyTitlt: '立即购买',
|
||||||
safeAreaInsetBottom: true,
|
safeAreaInsetBottom: true,
|
||||||
buyNowCustomStyle: {
|
buyNowCustomStyle: {
|
||||||
'border': 'none',
|
'border': 'none',
|
||||||
'background-color': '#d33123',
|
'background-color': '#d33123',
|
||||||
'flex': 1,
|
'flex': 1,
|
||||||
'padding': '25rpx 0',
|
'padding': '25rpx 0',
|
||||||
'font-size': '27rpx',
|
'font-size': '27rpx',
|
||||||
'text-align': 'center',
|
'text-align': 'center',
|
||||||
'color': '#fff',
|
'color': '#fff',
|
||||||
'height': '90rpx'
|
'height': '90rpx'
|
||||||
},
|
},
|
||||||
buyNowNowloading: false,
|
buyNowNowloading: false,
|
||||||
addCartloading: false
|
addCartloading: false
|
||||||
});
|
});
|
||||||
|
|
||||||
const emits = defineEmits(['handleChangePopup', 'handleAddCart', 'handleBuyNow', 'handleChangeGoodSku']);
|
const emits = defineEmits(['handleChangePopup', 'handleAddCart', 'handleBuyNow', 'handleChangeGoodSku']);
|
||||||
|
|
||||||
const skuPopup = ref();
|
const skuPopup = ref();
|
||||||
|
|
||||||
const state = reactive<{
|
const state = reactive<{
|
||||||
numberVal : number;
|
numberVal : number;
|
||||||
spec_list : Array<GoodsSpecListType>;
|
spec_list : Array<GoodsSpecListType>;
|
||||||
chooseSku : GoodsSkuListType;
|
chooseSku : GoodsSkuListType;
|
||||||
skuLength : number;
|
specCombinationList : Array<GoodsSkuListType>;
|
||||||
}>({
|
specMap : SpecWeight;
|
||||||
numberVal: 1,
|
selectedSpecs : Array<SelectedSpec>
|
||||||
spec_list: [],
|
}>({
|
||||||
chooseSku: {},
|
numberVal: 1,
|
||||||
skuLength: 1,
|
spec_list: [],
|
||||||
});
|
chooseSku: {},
|
||||||
|
specCombinationList: [],
|
||||||
|
specMap: {},
|
||||||
|
selectedSpecs: [],
|
||||||
|
});
|
||||||
|
|
||||||
watch(() => props.goodsDetailData, (newVal : any) => {
|
watch(() => props.goodsDetailData, (newVal : any) => {
|
||||||
if (newVal) {
|
if (newVal) {
|
||||||
/** 获取sku有几层 */
|
// 构造规格权重
|
||||||
state.skuLength = newVal?.skuList?.spec_list.length;
|
let i = 0, j = 0;
|
||||||
/** 默认选择第一个sku */
|
state.spec_list = deepClone(newVal?.skuList?.spec_list.map((item : GoodsSpecListType) => {
|
||||||
state.chooseSku = newVal?.skuList?.sku_list.find((item : any) => item.stock != 0);
|
item.list.forEach((itemChild : GoodsSpecListType) => {
|
||||||
|
state.specMap[itemChild.name] = {
|
||||||
|
sort: i,
|
||||||
|
weight: 1 << j
|
||||||
|
}
|
||||||
|
j++;
|
||||||
|
})
|
||||||
|
i++;
|
||||||
|
return item;
|
||||||
|
}));
|
||||||
|
|
||||||
state.spec_list = deepClone(newVal?.skuList?.spec_list.map((item : GoodsSpecListType) => {
|
state.specCombinationList = (props.goodsDetailData?.skuList?.sku_list.filter((item : GoodsSkuListType) => item.stock > 0)).map((item : GoodsSkuListType) => {
|
||||||
item.list.forEach((itemChild : GoodsSpecListType, indexChild : number) => {
|
return {
|
||||||
let findSku = newVal?.skuList?.sku_list.find((item : any) => item.sku_name_arr.includes(itemChild.name))
|
...item,
|
||||||
if (findSku && state.skuLength == 1) {
|
weight: item.sku_name_arr.reduce((prev, current) => prev + state.specMap[current]?.weight, 0),
|
||||||
itemChild['show'] = true;
|
}
|
||||||
} else {
|
})
|
||||||
itemChild['show'] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let findChooseSku = state.chooseSku.sku_name_arr.includes(itemChild.name);
|
/** 获取数据返回的默认sku,如果有就用没有就找第一个库存不为0的sku */
|
||||||
if (findChooseSku) {
|
let systemDefaultSku:Array<string> = (props.goodsDetailData?.product?.spesDesc?.split(',')).map((item:string)=> item.split(':')[1]);
|
||||||
itemChild['select'] = true;
|
let skuDefaultSku:GoodsSkuListType = state.specCombinationList.find((item:GoodsSkuListType)=> item.sku_name_arr.every((name:string)=> systemDefaultSku.includes(name)));
|
||||||
} else {
|
if(!systemDefaultSku || !skuDefaultSku){
|
||||||
itemChild['select'] = false;
|
state.specCombinationList[0].sku_name_arr.forEach((item:string)=>{
|
||||||
}
|
handleChooseSku(item);
|
||||||
})
|
});
|
||||||
return item;
|
return ;
|
||||||
}))
|
}
|
||||||
}
|
skuDefaultSku.sku_name_arr.forEach((item:string)=>{
|
||||||
}, {
|
handleChooseSku(item);
|
||||||
deep: true
|
});
|
||||||
})
|
}
|
||||||
|
}, {
|
||||||
|
deep: true
|
||||||
|
})
|
||||||
|
|
||||||
watch(() => props.showSku, (newVal : boolean) => {
|
watch(() => props.showSku, (newVal : boolean) => {
|
||||||
if (newVal) {
|
if (newVal) {
|
||||||
skuPopup.value.open();
|
skuPopup.value.open();
|
||||||
} else {
|
} else {
|
||||||
skuPopup.value.close();
|
skuPopup.value.close();
|
||||||
state.numberVal = 1;
|
state.numberVal = 1;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
/** 商品数量加减变化 */
|
const getSkuDisabled = computed(() => {
|
||||||
const handleChangeNumberVal = (e : any) => {
|
return (item : string) => {
|
||||||
state.numberVal = e.value;
|
// 每次选中之后要判断其他规格是否能够被选中
|
||||||
}
|
const weights = state.selectedSpecs.reduce((prev, current) => prev + current.weight, 0);
|
||||||
|
// 所有是初始状态,则所有属性均可选,因此disabled为false.
|
||||||
|
if (weights === 0) return false;
|
||||||
|
const current = state.specMap[item];
|
||||||
|
const weight = current.weight;
|
||||||
|
// 假如选择该属性,这是选中后的“权重之和”
|
||||||
|
let sum = weight + weights;
|
||||||
|
// 找到是否存在同一维度的规格已被选中的规格
|
||||||
|
const existEle = state.selectedSpecs.find(o => o.sort === current.sort);
|
||||||
|
if (existEle) {
|
||||||
|
// 如果存在,则减去即前选中的规格权重,即替换为当前权重。
|
||||||
|
sum -= existEle.weight;
|
||||||
|
}
|
||||||
|
for (let i = 0; i < state.specCombinationList.length; i++) {
|
||||||
|
const sWeight = state.specCombinationList[i].weight!;
|
||||||
|
// 与“权重之和”按位与运算后与其进行比较,如果相等,说明该属性是可选的
|
||||||
|
if ((sWeight & sum) === sum) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return state.selectedSpecs.findIndex(o => o.name === item) == -1;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
|
||||||
/** sku弹框显示或者隐藏 */
|
const getSkuSelected = computed(() => {
|
||||||
const handleChangePopup = (e : any) => {
|
return (item : string) => {
|
||||||
emits('handleChangePopup', e.show)
|
return state.selectedSpecs.findIndex(o => o.name === item) > -1;
|
||||||
}
|
};
|
||||||
|
})
|
||||||
|
|
||||||
/** sku选择 */
|
/** 商品数量加减变化 */
|
||||||
const handleChooseSku = (index : number, sku : GoodsSpecListType) => {
|
const handleChangeNumberVal = (e : any) => {
|
||||||
let chooseSku : GoodsSkuListType = {}; // 选中的sku
|
state.numberVal = e.value;
|
||||||
|
}
|
||||||
|
|
||||||
if (state.skuLength === 1) { /** 当sku只有一层的时候 */
|
/** sku弹框显示或者隐藏 */
|
||||||
chooseSku = props.goodsDetailData?.skuList?.sku_list.find((item : GoodsSkuListType) => item.sku_name_arr.includes(sku.name));
|
const handleChangePopup = (e : any) => {
|
||||||
} else { /** 当sku多层的时候 */
|
emits('handleChangePopup', e.show)
|
||||||
let nameArr : Array<string> = [sku.name];
|
}
|
||||||
let noClickSpecList = state.spec_list.filter((item : any, idx : number) => idx !== index);
|
|
||||||
noClickSpecList.forEach((item : GoodsSpecListType) => {
|
|
||||||
item.list.forEach((itemChild : GoodsSpecListType) => {
|
|
||||||
if (itemChild.select) {
|
|
||||||
nameArr.push(itemChild.name)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
chooseSku = props.goodsDetailData.skuList?.sku_list.find((item : GoodsSkuListType) => item.sku_name_arr.every((itemChild : string) => nameArr.includes(itemChild)));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!chooseSku || chooseSku.stock <= 0) {
|
/** sku选择 */
|
||||||
handleShowToast('没有库存了,请选择其它规格');
|
const handleChooseSku = (name : string) => {
|
||||||
return false;
|
const spec = state.specMap[name];
|
||||||
}
|
const eleIndex = state.selectedSpecs.findIndex(item => item.name === name);
|
||||||
|
const sortIndex = state.selectedSpecs.findIndex(item => item.sort === spec.sort);
|
||||||
|
// 如果当前元素已经存在,则从列表中删除
|
||||||
|
if (eleIndex > -1) {
|
||||||
|
state.selectedSpecs.splice(eleIndex, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 如果列表中的元素存在和当前元素的维度相同,则从列表中把那个元素删除,保证同一纬度只有一个元素。
|
||||||
|
if (sortIndex > -1) {
|
||||||
|
state.selectedSpecs.splice(sortIndex, 1);
|
||||||
|
}
|
||||||
|
state.selectedSpecs.push({ name: name, weight: spec.weight, sort: spec.sort });
|
||||||
|
|
||||||
state.spec_list[index].list.forEach((item : any) => item.select = false);
|
/** 判断sku是否选择完毕 */
|
||||||
sku.select = !sku.select;
|
if(state.selectedSpecs.length === state.spec_list.length){
|
||||||
state.chooseSku = chooseSku;
|
let skuName:Array<string> = state.selectedSpecs.map(item => item.name);
|
||||||
emits('handleChangeGoodSku', state.chooseSku);
|
state.chooseSku = state.specCombinationList.find((item:GoodsSkuListType)=> item.sku_name_arr.every((name:string)=> skuName.includes(name)));
|
||||||
};
|
emits('handleChangeGoodSku', state.chooseSku);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/** 加入购物车 */
|
/** 加入购物车 */
|
||||||
const handleAddCart = () => {
|
const handleAddCart = () => {
|
||||||
if (!handleHaveStock()) {
|
if (!handleHaveStock()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
emits('handleAddCart', {
|
emits('handleAddCart', {
|
||||||
productId: state.chooseSku._id,
|
productId: state.chooseSku._id,
|
||||||
nums: state.numberVal,
|
nums: state.numberVal,
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 立即购买 */
|
/** 立即购买 */
|
||||||
const handleBuyNow = () => {
|
const handleBuyNow = () => {
|
||||||
if (!handleHaveStock()) {
|
if (!handleHaveStock()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
emits('handleBuyNow', {
|
emits('handleBuyNow', {
|
||||||
productId: state.chooseSku._id,
|
productId: state.chooseSku._id,
|
||||||
nums: state.numberVal,
|
nums: state.numberVal,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 判断库存 */
|
/** 判断库存 */
|
||||||
const handleHaveStock = () => {
|
const handleHaveStock = () => {
|
||||||
if (state.chooseSku.stock === 0) {
|
if (state.selectedSpecs.length !== state.spec_list.length) {
|
||||||
handleShowToast('没有库存了,请选择其它规格');
|
handleShowToast('请选择sku');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import './goods-detail-sku.scss';
|
@import './goods-detail-sku.scss';
|
||||||
</style>
|
</style>
|
||||||
Reference in New Issue
Block a user