分类 vue-element 下的文章

相信在做商城的时候,很多人都会遇到规格选择这一块功能。在我刚开始接触规格的时候,有点迷茫,不知该如何下手,因为要考虑到后端那边返回的数据结构、库存、多规格等等问题,所以当时是有点懵逼。然后仔细查找相关规格的资料,才弄清楚其中的逻辑。

规格界面图

微信截图_20240131154516.png

多规格的逻辑,

  1. 定义一个数组把选中的值存储起来。
  2. 定义一个对象存储要匹配的数据。
  3. 把选中的值与存储的数据进行遍历查找与之匹配的值的库存,若库存为0按钮为灰色不能选择。

当然,我上面只是说一个大体的逻辑,还有很多细节方面的逻辑没有说,比如点击属性的时候,要给点击当前那个属性添加颜色相邻的属性颜色去掉、选择第一个规格之后,要判断其它规格的属性库存是否为0等等细节的逻辑。不过没关系,我在代码里写了很多注释,看下注释就ok了。

多规格的时候,要确定其中的某些值之后才能判断是否有库存,比如我这里,从后台返回的数据结构是,所有的可能性组合都在同一个数组里,数组里包含着所有可能性的对象数据,对象里有库存、组合属性(比如上面的 200,白色)等等值,当点击200的时候,就可以只知道(200,白色)(200,黑色)(200,绿色)的库存情况了。

好,先贴上代码,代码里的注释写的很详细,仔细看下你就明白了。

CSS

body {
    font-family: "Microsoft YaHei", "arial";
    background-color: #f2f2f2;
    background-color: rgba(0, 0, 0, 0.6)
}
ol,
ul {
    list-style: none;
}
 
li {
    list-style-type: none;
}
.clearfix:after {
    display: block;
    overflow: hidden;
    clear: both;
    height: 0;
    visibility: hidden;
    content: "";
}
 
* {
    margin: 0;
    padding: 0;
    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
 
@media screen and (max-width: 319px) {
    html {
        font-size: 42.666665px;
    }
}
@media screen and (min-width: 320px) and (max-width: 359px) {
    html {
        font-size: 42.66666px;
    }
}
@media screen and (min-width: 360px) and (max-width: 374px) {
    html {
        font-size: 48px;
    }
}
@media screen and (min-width: 375px) and (max-width: 383px) {
    html {
        font-size: 50px;
    }
}
@media screen and (min-width: 384px) and (max-width: 399px) {
    html {
        font-size: 51.2px;
    }
}
@media screen and (min-width: 400px) and (max-width: 413px) {
    html {
        font-size: 53.333335px;
    }
}
@media screen and (min-width: 414px) {
    html {
        font-size: 55.2px;
    }
}
.productBox {
    position: fixed;
    bottom: 0;
    left: 0;
    width: 100%;
    background-color: #fff;
}
.productConten {
    margin-bottom: 1rem;
}
.product-delcom {
    padding: 0.24rem 7%;
    color: #323232;
    font-size: 0.26rem;
    border-bottom: 1px solid #EEEEEE;
}
.product-footerlist {
    margin-top: 0.1rem;
}
.product-footerlist li {
    border: 1px solid #606060;
    border-radius: 0.08rem;
    color: #606060;
    text-align: center;
    padding: 0.04rem 0.16rem;
    float: left;
    margin-right: 0.16rem;
    min-width: 0.96rem;
    margin-bottom: 0.16rem;
}
.product-footerlist li.productActive {
    background-color: #1A1A29;
    color: #fff;
    border: 1px solid #1A1A29;
}
.product-footerlist li.noneActive {
    background-color: #ccc;
    opacity: 0.4;
    color: #000;
    pointer-events: none;
}
.product-footer {
    display: -webkit-box;
    display: -webkit-flex;
    display: flex;
    -webkit-flex: 1;
    -webkit-box-flex: 1;
    flex: 1;
    background-color: #1A1A29;
    line-height: 1rem;
    text-align: center;
}
.product-footer a {
    -webkit-flex: 1;
    -webkit-box-flex: 1;
    flex: 1;
    color: #fff;
    font-size: 0.3rem;
    text-decoration: none;
}

html

<div id="vmsimulatedDATA" class="productBox">
    <div class="productConten">
        <div class="product-delcom" v-for="(ProductItem,n) in simulatedDATA.specifications">
            <p>{{ProductItem.name}}</p>
            <ul class="product-footerlist clearfix">
                <li v-for="(oItem,index) in ProductItem.item" v-on:click="specificationBtn(oItem.name,n,$event,index)" v-bind:class="[oItem.isShow?'':'noneActive',subIndex[n] == index?'productActive':'']">{{oItem.name}}</li>
            </ul>
        </div>
    </div>
    <div class="product-footer">
        <a href="javascript:">立即购买</a>
    </div>
</div>

Vue代码

var vmsimulatedDATA = new Vue({
    el: "#vmsimulatedDATA",
    data: {
        simulatedDATA: { //模拟后台返回的数据 多规格
            "difference": [{ //所有的规格可能情况都在这个数组里
                    "id": "19",
                    "price": "200.00",
                    "stock": "19",
                    "difference": "100,白色"
                },
                {
                    "id": "20",
                    "price": "300.00",
                    "stock": "29",
                    "difference": "200,白色"
                },
                {
                    "id": "21",
                    "price": "300.00",
                    "stock": "10",
                    "difference": "100,黑丝"
                },
                {
                    "id": "22",
                    "price": "300.00",
                    "stock": "0",
                    "difference": "200,黑丝"
                },
                {
                    "id": "23",
                    "price": "500.00",
                    "stock": "48",
                    "difference": "100,绿色"
                },
                {
                    "id": "24",
                    "price": "500.00",
                    "stock": "0",
                    "difference": "200,绿色"
                }
            ],
            "specifications": [{ //这里是要被渲染字段
                    "name": "尺寸",
                    "item": [{
                            "name": "100",
                        },
                        {
                            "name": "200",
                        }
                    ]
                },
                {
                    "name": "颜色",
                    "item": [{
                            "name": "白色",
                        },
                        {
                            "name": "黑丝",
                        },
                        {
                            "name": "绿色",
                        }
                    ]
                }
            ]
        },
        selectArr: [], //存放被选中的值
        shopItemInfo: {}, //存放要和选中的值进行匹配的数据
        subIndex: [], //是否选中 因为不确定是多规格还是但规格,所以这里定义数组来判断
    },
    created: function () {
        var self = this;
        for (var i in self.simulatedDATA.difference) {
            self.shopItemInfo[self.simulatedDATA.difference[i].difference] = self.simulatedDATA.difference[
                i]; //修改数据结构格式,改成键值对的方式,以方便和选中之后的值进行匹配
        }
        self.checkItem();
    },
    mounted: function () {
 
    },
    methods: {
        specificationBtn: function (item, n, event, index) {
            var self = this;
            if (self.selectArr[n] != item) {
                self.selectArr[n] = item;
                self.subIndex[n] = index;
 
            } else {
                self.selectArr[n] = "";
                self.subIndex[n] = -1; //去掉选中的颜色 
            }
            self.checkItem();
        },
        checkItem: function () {
            var self = this;
            var option = self.simulatedDATA.specifications;
            var result = [];  //定义数组存储被选中的值
            for (var i in option) {
                result[i] = self.selectArr[i] ? self.selectArr[i] : '';
            }
            for (var i in option) {
                var last = result[i];  //把选中的值存放到字符串last去
                for (var k in option[i].item) {
                    result[i] = option[i].item[k].name; //赋值,存在直接覆盖,不存在往里面添加name值
                    option[i].item[k].isShow = self.isMay(result); //在数据里面添加字段isShow来判断是否可以选择
                }
                result[i] = last; //还原,目的是记录点下去那个值,避免下一次执行循环时避免被覆盖
 
            }
            self.$forceUpdate(); //重绘
        },
        isMay: function (result) {
            for (var i in result) { 
                if (result[i] == '') {
                    return true; //如果数组里有为空的值,那直接返回true
                }
            }
            return this.shopItemInfo[result].stock == 0 ? false : true; //匹配选中的数据的库存,若不为空返回true反之返回false
        }
 
    }
})

这里为了让大家对多规格选择更加直观,我把多余的功能都删掉了,只保留了规格选择这一块,代码给到了最精简。

如图

补充一下,这里是基于vue框架来写的,别忘了引入哦。

多规格选择这一块就先写到这里了,如有疑问或者写的不对的地方,欢迎来吐槽。

原文地址: http://chijianfeng.com/web/Vue/163.html

来自你的消息:

element ui el-select 过滤id=1的值 循环显示代码

来自ChatAI的消息:

你可以在 el-select 的数据源中使用数组的 filter 方法,过滤出不等于 1 的项,然后使用 v-for 循环显示。

以下是示例代码:

<template>
  <el-select v-model="selected" placeholder="请选择">
    <el-option v-for="item in filteredOptions" :key="item.value" :label="item.label" :value="item.value"></el-option>
  </el-select>
</template>

<script>
export default {
  data() {
    return {
      options: [
        { value: 1, label: '选项1' },
        { value: 2, label: '选项2' },
        { value: 3, label: '选项3' },
        { value: 4, label: '选项4' },
        { value: 5, label: '选项5' }
      ],
      selected: null
    }
  },
  computed: {
    filteredOptions() {
      return this.options.filter(item => item.value !== 1)
    }
  }
}
</script>

在上面的代码中,options 是 el-select 的数据源,我们使用 computed 属性 filteredOptions 来过滤掉 value 等于 1 的项,然后在 v-for 中使用 filteredOptions 来循环显示 el-option

希望这可以帮到你。

来自你的消息:

过滤多个值呢

来自ChatAI的消息:

如果你想要过滤多个值,可以使用 JavaScript 中的 Array.prototype.filter 方法和 Array.prototype.includes 方法。Array.prototype.includes 方法可以检查一个数组是否包含某个值。

以下是示例代码:

<template>
  <el-select v-model="selected" placeholder="请选择">
    <el-option v-for="item in filteredOptions" :key="item.value" :label="item.label" :value="item.value"></el-option>
  </el-select>
</template>

<script>
export default {
  data() {
    return {
      options: [
        { value: 1, label: '选项1' },
        { value: 2, label: '选项2' },
        { value: 3, label: '选项3' },
        { value: 4, label: '选项4' },
        { value: 5, label: '选项5' }
      ],
      selected: null
    }
  },
  computed: {
    filteredOptions() {
      const filtered = this.options.filter(item => {
        const excluded = [1, 3]; // 要过滤掉的值的数组
        return !excluded.includes(item.value);
      });
      return filtered;
    }
  }
}
</script>

在上面的代码中,我们使用一个名为 excluded 的数组来保存要过滤的值,然后我们在 filteredOptions 计算属性中使用 !excluded.includes(item.value) 来过滤掉这些值。

!excluded.includes(item.value) 表达式将会返回一个布尔值,如果 item.value 不是 excluded 数组中的元素,则为 true,表示该对象的 value 属性可以用于渲染 el-option 组件,否则为 false,表示需要将该对象过滤掉。

希望这对你有帮助。

uni-app——规格选择判断库存(类似电商商品加购)

<template>
    <view class="detail_page" v-cloak :class="isShowPopup? 'popup-show': ''">
        <navBar :title="topInfo.title" :url="topInfo.url" :icon_title="topInfo.icon_title" :type="topInfo.type">
        </navBar>
        <view class="pages" v-cloak>
            <view class="info scroll_item" id="scroll0">
                <view class="banner_top">
                    <swiper :swiperConfig="swiperConfig"></swiper>
                </view>
                <view class="page_info page_item">
                    <view class="price">
                        <text class="large">{{listData.price}}</text>
                        元起
                    </view>
                    <view class="title">{{listData.name}}</view>
                    <view class="sub_title">强效清洗,全面爱家,重新焕发地毯新生</view>
                </view>
                <view class="form_box page_item">
                    <uni-forms ref="signUpform" :value="signUpformData" :rules="rules">
                        <uni-forms-item label="小区" name="housing_id" style="display: none;"></uni-forms-item>
                        <uni-forms-item label="地址" name="user_address_id" @tap="goAddress">
                            <text class="picker_lable">{{address}}</text>
                        </uni-forms-item>
                        <uni-forms-item label="规格" name="flag" @tap="chorceSpecs">
                            <text class="picker_lable">{{specs}}</text>
                        </uni-forms-item>
                        <uni-forms-item label="时间" name="start_time" @tap="openDatetimePicker">
                            <text class="picker_lable">{{signUpformData.start_time}}</text>
                        </uni-forms-item>
                    </uni-forms>
                </view>
            
            
            </view>
            
            <view class="details scroll_item " id="scroll1" style="padding-bottom:80px;">
                <view style="color: #a29696;margin-bottom: 20rpx; text-align: center;">——详情——</view>
                <view class="page_detail page_item" v-html="detail_content" style="margin-bottom:70px;">
                    {{detail_content}}
                </view>
            </view>    
            
            <view class="footer">
                <view>
                    <image class="service" mode="aspectFit" @tap="callPhone" src="../../static/images/service.png">
                    </image>
                    <view class="byButton" form-type="submit" @tap="handleBuy">立即购买</view>
                </view>
            </view>
        </view>

        <!-- 页面滚动到详情时再显示锚点 -->
        <view class="fixedtop" v-show="scrollDistance > 100">
            <view class="fixedtop_box">
                <view v-for="(item,index) in fixedList" :key="index" :class="{'active':currentIndex == index}"
                    @tap="changeactive(index)">{{item.name}}
                </view>
            </view>
        </view>
        <!-- 规格 -->
        <uni-popup ref="popup" type="bottom" :mask-click="false">
            <view class="specs_box spec-shade">
                <view class="specs_box_box">
                    <view class="title">
                        <text></text>
                        <text class="title">请选择服务规格</text>
                        <!--   <text @click="closeProp"
                               class="iconfont icon-close"></text> -->
                        <text></text>
                    </view>
                    <view class="spec-cont">
                        <view class="goods-choose-show flex-star">
                            <view class="goods-choose-show-right" v-if="currentItem">
                                <p>¥{{currentItem.price || 0}}</p>
                                <view>库存{{currentItem.all_count || 0}}件</view>
                                <!-- <view>{{specShowString}}</view> -->
                            </view>
                        </view>
                        <view class="spec-linebox" style="max-height: 550rpx;overflow-y: scroll;">
                            <view class="spec-item" v-for="(skuItem,skuIndex) in skuInfo">
                                <p>{{skuItem.title}}</p>
                                <view class="item-cont flex-star">
                                    <span v-for="(item,index) in skuItem.option"
                                        :class="[item.isShow ? '' : 'noProduct',subIndex[skuIndex] == item.id ? 'act' : '']"
                                        @click="item.isShow ? specificationBtn(item.info,skuIndex,item.id) : disabled">{{item.info}}</span>
                                </view>
                            </view>
                        </view>
                    </view>
                    <button class="confirm" @click="confirmSpec">确定</button>
                </view>
            </view>
        </uni-popup>

        <!-- 时间 -->
        <SimpleDateTimePicker ref="myPicker" @submit="handleSubmit" :start-year="year" :end-year="year+20" />
    </view>

</template>

<script>
    import navBar from "@/components/navBar/navBar.vue"
    import swiper from "@/components/swiper/swiper.vue"
    import forms from "@/components/uni-forms/uni-forms.vue"
    import formItems from "@/components/uni-forms-item/uni-forms-item.vue"
    import SimpleDateTimePicker
    from "uni_modules/buuug7-simple-datetime-picker/components/buuug7-simple-datetime-picker/buuug7-simple-datetime-picker.vue";
    import popup from "@/components/uni-popup/uni-popup.vue"
    import {
        mapMutations
    } from 'vuex';

    export default {
        components: {
            navBar,
            swiper,
            formItems,
            forms,
            SimpleDateTimePicker,
            popup
        },

        data() {
            return {
                isShowPopup: false,
                payParams: 0,
                goods_id: 0,
                isInit: 0, // 默认只显示第一组规格
                allCount_id: 0, // 库存为0的id
                stockIndex: 0, //库存为0的id组
                stock_flag: [],
                getSpecs: [],
                topInfo: {
                    url: "../../pages/index/index",
                    title: "预约详情",
                    icon_title: "返回",
                    type: 'tab'
                },
                token: "",
                year: "",
                listData: {},
                swiperConfig: {
                    indicatorDots: true,
                    vertical: false,
                    autoplay: true,
                    interval: 2000,
                    duration: 600,
                    bannerList: [],
                    swiperH_height: "400rpx"
                },
                detail_content: "", //详情内容
                specs: "请选择规格",
                address: "请选择服务地址",
                signUpformData: {
                    user_address_id: "",
                    housing_id: "",
                    flag: "",
                    start_time: "请选择服务时间"
                },
                currentIndex: 0,
                fixedList: [{
                        name: "商品",
                        targetDom: ".info"
                    },
                    {
                        name: "详情",
                        targetDom: ".details"
                    }
                ], // 固定顶部锚点链接
                rules: {
                    address: {
                        rules: [{
                            required: true,
                            errorMessage: "请选择服务地址"
                        }]
                    },
                    type: {
                        rules: [{
                            required: true,
                            errorMessage: "请选择服务规格"
                        }]
                    },
                    serviceTime: {
                        rules: [{
                            required: true,
                            errorMessage: "请选择服务时间"
                        }]
                    }
                },
                elHeight: "",
                scrollDistance: 0,
                doms: "",
                topList: [],
                multiIndex: 0,
                specsList: [],
                isShow: false,
                selectArr: [],
                subIndex: [],
                currentItem: {
                    flag: '',
                    price: 0,
                    all_count: 0,
                    title: ""
                },
                skuInfo: [],
                specShowString: '选择规格',
                goodsData: {
                    priceInfo: [],
                    SKUInfo: [],
                },
                category_type: 0,// 分类id(只针对垃圾回收)
            }
        },

        onLoad(option) {
            console.log('下单确定地址', option);
            /* 获取当前年份 */
            let date = new Date();
            this.year = date.getFullYear();
            /* 设置页面滚动高度 */
            let screenH = uni.getSystemInfoSync().screenHeight;
            this.elHeight = screenH;


            let loginRes = this.checkLogin();
            if (!loginRes) {
                return false;
            } else {
                /* 初始化页面 */
                if (option.id) {
                    uni.setStorageSync("goods_id", option.id);
                }
                if(option.category_type){
                    uni.setStorageSync("category_type", option.category_type);
                }
                this.token = uni.getStorageSync("token");
                this.goods_id = uni.getStorageSync("goods_id");
                this.category_type = uni.getStorageSync("category_type");
            }

            // this.firstStock();
            this.getStock();
            this.getInfo();

            /* 选择地址 */
            if (option.address_id) {
                this.signUpformData.user_address_id = option.address_id;
                this.address = option.address;

            }
            /* 小区id */
            if (option.housing_id) {
                this.signUpformData.housing_id = option.housing_id;
            }


        },
    
        methods: {
            getStock() {
                let _param = {};
                _param.operate = "order.get_price",
                    _param.goods_id = this.goods_id;
                _param.token = this.token;
                _param.flag = [0];

                this.$myRequset({
                    url: "/api?operate=goods.get_price",
                    method: "POST",
                    data: _param,
                }).then((res) => {
                    this.goodsData.priceInfo = res.data.data;
                    // console.log('获取价格', this.goodsData.priceInfo);
                });
            },
            getInfo() {
                this.$myRequset({
                    url: "/api?operate=goods.info",
                    method: "POST",
                    data: {
                        token: this.token,
                        goods_id: this.goods_id
                    },
                }).then((res) => {
                    this.swiperConfig.bannerList = res.data.data.album_images;
                    this.listData.name = this.topInfo.title = res.data.data.name;
                    this.listData.price = res.data.data.price;
                    this.detail_content = res.data.data.content;
                    this.goodsData.SKUInfo = res.data.data.spec_config;
                    this.skuInfo = this.goodsData.SKUInfo;
                    if(this.skuInfo){
                        this.skuInfo.forEach(item => {
                            item.option.forEach(specItem => {
                                specItem.isShow = true;
                            })
                        })
                    }
                    // console.log('规格列表', this.goodsData.SKUInfo);
                    // console.log('规格列表_skuInfo', this.skuInfo);
                });

            },
            disabled() {
                uni.showToast({
                    title: "不可点击"
                })
            },
            /* 规格 */
            chorceSpecs() {
                setInterval(function() {
                    uni.hideKeyboard(); //隐藏软键盘
                }, 10);
                if (!this.signUpformData.user_address_id) {
                    uni.showToast({
                        title: "请先选择地址",
                        icon: "none"
                    })
                } else if (this.specsList) {
                    this.$refs.popup.open();
                    this.isShowPopup = true;
                } else {
                    uni.showToast({
                        title: "暂无规格可选",
                        icon: "none"
                    })
                }
            },
            closeProp() {
                if (this.subIndex.length == 0) {
                    uni.showToast({
                        icon: "error",
                        title: "请选择服务规格"
                    });
                } else {
                    this.$refs.popup.close();
                }
            },
            /* 确定规格 */
            confirmSpec() {
                console.log('当前选择', this.subIndex);
                console.log('当前选择', this.selectArr);
                // this.signUpformData.type = this.subIndex.toString(",");

                this.signUpformData.flag = this.subIndex;
                this.specs = this.specShowString;
                if (this.currentItem.price == 0) {
                    uni.showToast({
                        icon: "none",
                        title: "请选择完整规格"
                    })
                } else {
                    this.$refs.popup.close();
                }
            },

            /**
             * @param {String} specName 当前点击规格按钮的值(黑色,35)
             * @param {Number} specIndex 选择的规格下标(例子中颜色是0,尺码是1)
             * @param {Number} specItemIndex 选择规格值id(例子中35下标是0)
             */
            specificationBtn(specName, specIndex, specItemIndex) {
                if (this.selectArr[specIndex] != specName) { //判断所选规格数组中是否包含当前点击规格
                    this.selectArr[specIndex] = specName; //如果没有则把当前规格添加
                    this.subIndex[specIndex] = Number(specItemIndex); //添加选中样式
                } else {
                    this.selectArr[specIndex] = '';
                    this.subIndex[specIndex] = -1; //去除样式
                }
                this.specShowString = this.spaceRemoveArr(this.selectArr).join(',') || '选择规格'; //所选规格页面中展示,数组为空则变为选择规格
                this.inventoryLookup(); //当规格选完后,去匹配
                this.clickPitch(); //库存判断,实现不可点击
            },
            spaceRemoveArr(arr) { //数组去除空字符串
                let tempArr = []
                arr.forEach(item => {
                    if (item) {
                        tempArr.push(item)
                    }
                })
                return tempArr;
            },
            /* 规格选完后,去匹配 */
            inventoryLookup() {
                try {
                    this.goodsData.priceInfo.forEach((item, index) => {
                        if (item.title == this.specShowString) {
                            this.currentItem = item;
                            this.listData.price = this.currentItem.price;
                            throw new Error();
                        } else {
                            this.currentItem = {
                                flag: '',
                                price: 0,
                                all_count: 0,
                                title: ""
                            };
                        }
                    })
                } catch (e) {}
            },
            /* 库存判断,实现不可点击 */
            clickPitch() {
                let result = [];
                // console.log('库存判断:',this.goodsData.SKUInfo);
                for (let i in this.goodsData.SKUInfo) {
                    result[i] = this.selectArr[i] ? this.selectArr[i] : '';
                }
                //最难理解的大概就是这里了,这里跟着循环里打印结果,多走几遍就大致明白了  假象.jpg
                for (let i in this.goodsData.SKUInfo) {
                    let last = result[i];
                    // console.log("最后点击======",last);
                    for (let k in this.goodsData.SKUInfo[i].option) {
                        result[i] = this.goodsData.SKUInfo[i].option[k].info;
                        // console.log('result--------', result, "last:", last);
                        this.skuInfo[i].option[k].isShow = this.isMay(result)
                    }
                    result[i] = last;
                }
                // console.log('库存结果111:',result);
            },
            isMay(result) {
                for (let i in result) {
                    if (result[i] == '') {
                        return true;
                    }
                }
                for (let i in this.goodsData.priceInfo) {
                    if (this.goodsData.priceInfo[i].title == result.join(",") && this.goodsData.priceInfo[i].all_count >
                        0) {
                        return true;
                    }
                }
            },
            goAddress() {
                console.log('goAddress');
                uni.redirectTo({
                    url: "../addressList/addressList"
                });
            },
            /* 时间 */
            openDatetimePicker() {
                if (!this.signUpformData.user_address_id) {
                    uni.showToast({
                        icon: "none",
                        title: "请选择服务地址"
                    })
                } else if (!this.signUpformData.flag) {
                    uni.showToast({
                        icon: "none",
                        title: "请选择服务规格"
                    })

                } else {
                    this.$refs.myPicker.show();
                }
            },
            /* 选择时间 */
            handleSubmit(e) {
                console.log('times', e);
                this.signUpformData.start_time = `${e.year}-${e.month}-${e.day} ${e.hour}:${e.minute}`;
            },
        // 锚点链接滚动监听
            onPageScroll(res){
                this.scrollDistance = res.scrollTop;
                // console.log('滚动距离',res.scrollTop);//距离页面顶部距离
                if(res.scrollTop >=600){
                    this.currentIndex = 1;
                }else{
                    this.currentIndex = 0;
                }
            },
                      /* 锚点点击*/          
            changeactive(index) {
                console.log('sdsd',index);
                if(index==1){
                    uni.pageScrollTo({
                        duration:300, // 毫秒
                        scrollTop:600 // 位置
                    });
                }else{
                    uni.pageScrollTo({
                        duration:300, // 毫秒
                        scrollTop:0 // 位置
                    });
                }
            },

            /* 表单提交 */
            handleBuy() {
                this.$refs.signUpform.validate().then(res => {
                    console.log('表单数据信息:', res);
                    let _param = res;
                    _param.operate = "wechat.miniapp";
                    _param.token = this.token;
                    _param.goods_id = this.goods_id;
                    
                    // 垃圾回收
                    if(this.category_type == 21){
                        _param.category_type = this.category_type;
                    }
                    console.log('(_param.flag', typeof _param.flag);
                    let _res = this.$myRequset({
                        url: "/api/pay/index",
                        method: "POST",
                        data: _param,
                    }).then((res) => {
                        console.log('_res', res);
                        if (res.data.code == 1) {
                            let signType = res.data.data.signType
                            let nonceStr = res.data.data.nonceStr;
                            let _package = res.data.data.package;
                            let paySign = res.data.data.paySign;
                            let timeStamp = res.data.data.timeStamp;

                            uni.requestPayment({
                                provider: 'wxpay',
                                timeStamp: timeStamp,
                                nonceStr: nonceStr,
                                package: _package,
                                signType: signType,
                                paySign: paySign,
                                success: function(res) {
                                    console.log('pay_success:' + JSON.stringify(res));
                                    uni.reLaunch({
                                        url: "../../pages/order/order"
                                    });
                                },
                                fail: function(err) {
                                    console.log('pay_fail:' + JSON.stringify(err));
                                    uni.reLaunch({
                                        url: "../../pages/order/order",
                                    });
                                }
                            });

                        } else {
                            uni.showToast({
                                icon: "none",
                                title: "请选择规格"
                            })
                            return false;
                        }

                    });


                }).catch(err => {
                    uni.showToast({
                        title: err[0].errorMessage,
                        icon: "none"
                    });
                })
            },
            /* 拨打电话 */
            callPhone() {
                uni.makePhoneCall({
                    phoneNumber: "15902341080"
                });

            },
        }
    }
</script>

https://www.cnblogs.com/LindaBlog/p/15570833.html