欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > uniapp-商城-56-后台 新增商品(弹窗属性继续分析)

uniapp-商城-56-后台 新增商品(弹窗属性继续分析)

2025/11/7 14:44:49 来源:https://blog.csdn.net/weixin_43613170/article/details/147919540  浏览:    关键词:uniapp-商城-56-后台 新增商品(弹窗属性继续分析)

1、概述

前面我们讲了布局和相应商品属性的页面布局。属性是一个弹窗,它是一个cell的组件的实现属性。点击该cell就会调用uni-popup 进行弹窗。基本的页面布局如下:

属性显示其实是个一嵌套的数据显示。

2  页面显示商品属性  点击添加属性

2.1 代码如下:

			<uni-forms-item label="商品属性" ><u-cell :title="skuTitle" isLink :border="false" @click="clickSelect"></u-cell><view class="skuList"><view class="item" v-for="item in goodsFormData.sku_select" @click="clickSelect"><view class="left">{{item.skuName}}:</view><view class="right">{{skuChildName(item.children)}}</view></view></view></uni-forms-item>

2.2 代码解读

cell :

该组件就是cell单元格。一般用于一组列表的情况,比如个人中心页,设置页等,默认有一个边框,且整个可以被点击 。

title是组件显示的名称; 

isLink  就是显示一个右侧的箭头;

border:不用显示默认的边框; 注意使用加v-band(也就是加 :)

            <uni-forms-item label="商品属性" >

              // label 显示在界面上的文本 就是商品属性
                <u-cell :title="skuTitle" isLink :border="false" @click="clickSelect"></u-cell>

                // cell 实现点击的组件  title 就是 该如何显示?-----见2.3      

                // clickSelect 是一个函数 ----见 2.4 

                //下面是 显示选中后效果,后面还会继续分析
                <view class="skuList">
                    <view class="item" v-for="item in goodsFormData.sku_select" @click="clickSelect">
                        <view class="left">{{item.skuName}}:</view>
                        <view class="right">{{skuChildName(item.children)}}</view>
                    </view>
                </view>
            </uni-forms-item>

2.3 title的计算

默认就是显示的点击添加属性,如果已经添加了属性就会进行显示,把数据传递给this.goodsFormData.sku_select

如果数据有,那就是数据库有,数据库的值也是来自于 一开始选中的,后面再来分析这个选择接口。

computed: {
            skuTitle() {
                if (this.goodsFormData.sku_select.length) {
                    let arr = this.goodsFormData.sku_select.map(item => {
                        return item.skuName
                    })
                    return arr.join("/")
                } else {
                    return "点击添加属性"
                }
            }
        },

2.4 对cell 的点击clickSelect

//点击选择属性
            clickSelect() {

                //通过uni-popup 的pen方法,弹出来, 看---2.5 uni-popup
                this.$refs.attrWrapPop.open(); //使用open方法弹出来
                if (this.skuArr.length) return;   //如果数据存在就不用继续执行getSkuData 函数了
                this.getSkuData(); },   //如果数据不存在就继续执行getSkuData  ---看2.6 getSkuData

2.5 弹窗 中的属性布局和处理   unipopup

2.5.1 解析

        <uni-popup ref="attrWrapPop" type="bottom">
            <!-- 底部弹出 type
             ref 是一个名字属性,便于被调用 给 clickSelect
             在 clickSelect 函数中调用了该接口 见2.6.1
             -->
            <view class="attrWrapper">
                <!-- 分三部分  就是上中下 头身体和尾部 -->
                <view class="head">
                    <view class="title">商品属性</view>
                    <!-- clickAddAttr函数  添加属性的  见 2.7  -->
                    <view class="addAttr" @click="clickAddAttr()">+ 添加属性</view>
                </view>

                <view class="body">
                    <!-- 读取 skuArr 循环显示 分两部分显示 top 和 btngroup    skuArr 见2.8 -->
                    <view class="item" v-for="(item,index) in skuArr">
                        <view class="top">
                            <checkbox :checked="item.checked" @click="changeCheckbox(index)"></checkbox>
                            <!-- changeCheckbox  选中就做这个操作  见 2.9  -->
                            <!-- checked 是否被选中的属性标识 -->
                            <view class="font">{{item.skuName}}</view>
                        </view>
                        <view class="btnGroup" v-if="item.checked">
                            <!-- 需要判断checked 是不是true  是不是选中,选中了就展示-->
                            <view class="btn" :class="child.checked?'active':''" v-for="(child,cIdx) in item.children"
                                @click="clickChlidBtn(index,cIdx)">{{child.name}}</view>
                                <!-- btn 读取skuArr ,循环显示
                                选中就加class 为active  
                                点击 就执行 clickChlidBtn函数  见-2.10
                                -->
                            <view class="btn" @click="clickAddAttr(index)">
                                <!-- btn 该盒子就是一个 + 号,用来添加该属性下的选项
                                 clickAddAttr 点就执行   见 2.11
                                 uicon就一个 + 号图标
                                 -->
                                <u-icon name="plus"></u-icon>
                            </view>
                        </view>
                    </view>
                </view>

                <view class="foot">
                    <button type="primary" @click="clickConfirmSelect">确认选择</button>
                    <!-- 按钮 ,蓝色提交按钮
                     type 就是颜色格式
                     点击就是确认该商品的属性
                     clickConfirmSelect 见2.12
                     -->
                </view>
            </view>

            <view class="safe-area-bottom"></view>
            <!--防止被苹果虚拟home键 挡住 -->
            <!--
            这里就是直接调用的app.vue的全局样式。
            什么是全局样式:就是样式那里没有scoped 的,所以在以前老是要写一个表示局部样式,就怕vue 中class名字一样了
            如果你不些scoped ,就要把全局的view 的class 写在最前面。
            不知道懂不懂,慢慢悟吧    见2.13
            -->
        </uni-popup>

        <!-- 这里是点击的添加属性的弹窗 -->
        <!-- 你可能懵逼了
        那个添加属性的弹窗?
         两个弹窗都要用
         一个是第一个弹窗中的右上角的添加属性  class名字 addAttr
         一个是属性规格下的选项中的 + class的名字就是btn
        -->
        <uni-popup ref="addAttrPop">
            <uni-popup-dialog mode="input" title="新增" placeholder="请输入新增的内容"
                @confirm="dialogConfirm"></uni-popup-dialog>
                <!-- dialogConfirm 是一个确认后处理逻辑  见 2.14-->
        </uni-popup>

2.5.2 具体代码:

		<uni-popup ref="attrWrapPop" type="bottom"><!-- 底部弹出 type ref 是一个名字属性,便于被调用 给 clickSelect 在 clickSelect 函数中调用了该接口--><view class="attrWrapper"><!-- 分三部分  就是上中下 头身体和尾部 --><view class="head"><view class="title">商品属性</view><!-- clickAddAttr函数  添加属性的--><view class="addAttr" @click="clickAddAttr()">+ 添加属性</view></view><view class="body"><!-- 读取 skuArr 循环显示 分两部分显示 top 和 btngroup--><view class="item" v-for="(item,index) in skuArr"><view class="top"><checkbox :checked="item.checked" @click="changeCheckbox(index)"></checkbox><!-- changeCheckbox  选中就做这个操作 --><!-- checked 是否被选中的属性标识 --><view class="font">{{item.skuName}}</view></view><view class="btnGroup" v-if="item.checked"><!-- 需要判断checked 是不是true  是不是选中,选中了就展示--><view class="btn" :class="child.checked?'active':''" v-for="(child,cIdx) in item.children"@click="clickChlidBtn(index,cIdx)">{{child.name}}</view><!-- btn 读取skuArr ,循环显示选中就加class 为active  点击 就执行 clickChlidBtn函数--><view class="btn" @click="clickAddAttr(index)"><!-- btn 该盒子就是一个 + 号,用来添加该属性下的选项 clickAddAttr 点就执行uicon就一个 + 号图标  --><u-icon name="plus"></u-icon></view></view></view></view><view class="foot"><button type="primary" @click="clickConfirmSelect">确认选择</button><!-- 按钮 ,蓝色提交按钮type 就是颜色格式点击就是确认该商品的属性clickConfirmSelect--></view></view><view class="safe-area-bottom"></view><!--防止被苹果虚拟home键 挡住 --><!-- 这里就是直接调用的app.vue的全局样式。什么是全局样式:就是样式那里没有scoped 的,所以在以前老是要写一个表示局部样式,就怕vue 中class名字一样了如果你不些scoped ,就要把全局的view 的class 写在最前面。不知道懂不懂,慢慢悟吧--></uni-popup><!-- 这里是点击的添加属性的弹窗 --><!-- 你可能懵逼了那个添加属性的弹窗?两个弹窗都要用一个是第一个弹窗中的右上角的添加属性  class名字 addAttr一个是属性规格下的选项中的 + class的名字就是btn--><uni-popup ref="addAttrPop"><uni-popup-dialog mode="input" title="新增" placeholder="请输入新增的内容"@confirm="dialogConfirm"></uni-popup-dialog><!-- dialogConfirm 是一个确认后处理逻辑 --></uni-popup>

2.6 属性表单中,添加属性和获取数据

2.6.1  clickSelect 如果点击添加属性  对cell单元的点击和2.4一样

/点击选择属性
            clickSelect() {

                //通过uni-popup 的pen方法,弹出来, 看---2.5 uni-popup
                this.$refs.attrWrapPop.open(); //使用open方法弹出来
                if (this.skuArr.length) return;   //如果数据存在就不用继续执行getSkuData 函数了
                this.getSkuData(); },   //如果数据不存在就继续执行getSkuData  ---看2.6.2 getSkuData

2.6.2  弹窗中获取数据接口 getSkuData

云对象方式处理:后面再分析

            //获取sku列表
            async getSkuData() {
                let res = await skuCloudObj.get();
                this.skuArr = res.data
                console.log(res);
            },

2.7  函数方法添加属性   clickAddAttr

页面弹窗:

        <!-- 这里是点击的添加属性的弹窗 -->
        <!-- 你可能懵逼了
        那个添加属性的弹窗?
         两个弹窗都要用
         一个是第一个弹窗中的右上角的添加属性  class名字 addAttr
         一个是属性规格下的选项中的 + class的名字就是btn
        -->
        <uni-popup ref="addAttrPop">
            <uni-popup-dialog mode="input" title="新增" placeholder="请输入新增的内容"
                @confirm="dialogConfirm"></uni-popup-dialog>
                <!-- dialogConfirm 是一个确认后处理逻辑 -->
        </uni-popup>

方法:

            //点击添加属性
            clickAddAttr(index = null) {
                if (index == null) {
                    this.addAttrType = "parent"
                    this.attrIndex = null
                } else {
                    this.addAttrType = "child"
                    this.attrIndex = index
                }
                this.$refs.addAttrPop.open();
            },

2.8 skuArr 数据结构

         skuArr: [{_id:1,skuName:"颜色",checked:false,children:[{name:"红",checked:false},{name:"蓝",checked:false}]},{_id:2,skuName:"规格",checked:false,children:[{name:"M",checked:false},{name:"S",checked:false}]}],// 上面是一个数据结构例子,后台数据就应该着这样存// 实际是下面的[]// skuArr: [],

2.9 选中属性类的操作,不是属性下面的选项  changeCheckbox 

            //点击属性的复选框    改变了值,也相应改变了显示 后面也把值存到了数据库
            changeCheckbox(index) {
                this.skuArr[index].checked = !this.skuArr[index].checked
            },

2.10 选中属性类下的选项 clickChlidBtn

            //点击属性值的子元素  改变了值,也相应改变了显示 后面也把值存到了数据库
            clickChlidBtn(index, cIdx) {
                this.skuArr[index].children[cIdx].checked = !this.skuArr[index].children[cIdx].checked
            },

2.11 clickAddAttr 添加属性中的选项  点击 + 图 标

            //点击添加属性
            clickAddAttr(index = null) {
                if (index == null) {
                    this.addAttrType = "parent"
                    this.attrIndex = null
                } else {
                    this.addAttrType = "child"
                    this.attrIndex = index
                }
                this.$refs.addAttrPop.open();
            },

2.12 选中属性后,点击确认button,使用函数 clickConfirmSelect

            //点击确认选择
            clickConfirmSelect() {
                let arr = this.skuArr.filter(item => {
                    let state = item.children.some(child => child.checked)
                    return item.checked && state
                }).map(item => {
                    let children = item.children.filter(child => {
                        return child.checked
                    })
                    return {
                        ...item,
                        children
                    }
                })
                this.goodsFormData.sku_select = arr
                this.$refs.attrWrapPop.close();

            },

2.13 全局的样式以及苹果底部安全区域,这样就不用在本vue写样式safe-area-bottom,直接调用app.vue中写。

            <view class="safe-area-bottom"></view>
            <!--防止被苹果虚拟home键 挡住 -->
            <!--
            这里就是直接调用的app.vue的全局样式。
            什么是全局样式:就是样式那里没有scoped 的,所以在以前老是要写一个表示局部样式,就怕vue 中class名字一样了
            如果你不些scoped ,就要把全局的view 的class 写在最前面。
            不知道懂不懂,慢慢悟吧
            -->

2.14 dialogConfirm  弹窗 确认后的处理逻辑

通过云对象的方式解析处理:
            //添加属性弹窗的确认按钮
            async dialogConfirm(e) {
                if (!e) return;
                if (this.addAttrType == "parent") {
                    let obj = {
                        skuName: e,
                        checked: true,
                        children: []
                    }
                    let res = await skuCloudObj.add(obj)
                    obj._id = res.id;
                    this.skuArr.push(obj)

                } else if (this.addAttrType == "child") {
                    let obj = {
                        name: e,
                        checked: true
                    }
                    let id = this.skuArr[this.attrIndex]._id;
                    let res = await skuCloudObj.updateChild(id, obj)
                    this.skuArr[this.attrIndex].children.push(obj)
                }

            },

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词