????????前面添加了屬性,添加屬性的子級項目。也分析了如何回顯,但是在添加新的商品的時,我們也同樣需要進行選擇,還要能正常的顯示在界面上。下面對頁面的顯示進行分析。
1、界面情況回顧
屬性顯示其實是個一嵌套的數據顯示。
2、選中的界面
3、頁面顯示
使用了函數方法skuChildName,
還使用了點擊就彈窗在兩個地方都用了。clickSelect
對于默認顯示:還用到了skuTitle 計算接口,
當然這個接口也可以用方法來做,但這里值都可以取得,所以就用這方法。
前一個章節講了顯示,需要添加一個view 進行顯示:
4、相應顯示的需要的方法?skuChildName
方法很簡單,就是將讀取的數據,arr數組,找出數組中的name ,然后對name進行/ 拼接
注意使用的方法?? map
對數組中的值 使用? / 進行拼接。
注意這里只是計算了 子級 項的name??
??????????? //屬性返回子元素的名稱
??????????? skuChildName(arr) {
??????????????? let nsArr = arr.map(item => {
??????????????????? return item.name
??????????????? })
??????????????? return nsArr.join("/")
??????????? },
5、計算頁面的顯示,如果沒有值,那么就顯示點擊添加屬性
是一個計算值的接口,默認是顯示點擊添加屬性
如果this.goodsFormData.sku_select.length 不為0 ,就顯示屬性值中的name,用到的用 jion?? /? 鏈接
注意不是 children,這里只是計算了父級 屬性
在頁面上顯示 也是直接用了該函數名字
??????? computed: {
??????????? skuTitle() {
??????????????? if (this.goodsFormData.sku_select.length) {
??????????????????? let arr = this.goodsFormData.sku_select.map(item => {
??????????????????????? return item.skuName
??????????????????? })
??????????????????? return arr.join("/")
??????????????? } else {
??????????????????? return "點擊添加屬性"
??????????????? }
??????????? }
??????? },
??????????? <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>
6 整體的代碼(除開商品,屬性這一欄 界面的? 全都有了)
<template><view class="goodsView"><!-- 添加商品 --><uni-forms ref="goodsForm" :model="goodsFormData" :rules="goodsRules" :label-width="100" label-align="right"><uni-forms-item label="商品圖片" required="true"><uni-file-picker v-model="goodsFormData.thumb" fileMediatype="image" mode="grid" ></uni-file-picker></uni-forms-item><uni-forms-item label="商品名稱" required name="name" ><!-- trim 去空格 --><uni-easyinput v-model="goodsFormData.name" placeholder="請輸入商品名稱" trim="both"></uni-easyinput></uni-forms-item><uni-forms-item label="產品分類" required name="category_id"><!-- 云端數據 下拉框獲取 field 就是獲取的內容 一定要寫成 value text 這是官方定義的 value選中的值,text顯示的文本,也就是value后臺用,text前臺用 --><!-- 利用這個組件就實現了后端數據庫的讀取 --><uni-data-select collection="green-mall-categories" field="_id as value, name as text"v-model="goodsFormData.category_id"></uni-data-select></uni-forms-item><uni-forms-item label="商品價格" required name="price"><!-- trim 去空格 --><uni-easyinput type="number" v-model="goodsFormData.price" placeholder="請輸入商品價格"trim="both"></uni-easyinput></uni-forms-item><uni-forms-item label="商品原價"><!-- trim 去空格 --><uni-easyinput type="number" v-model="goodsFormData.before_price" placeholder="請輸入原價"trim="both"></uni-easyinput></uni-forms-item><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><uni-forms-item label="商品描述"><!-- type 是類型 textarea 就是大框 --><uni-easyinput type="textarea" placeholder="請輸入詳細的描述信息"v-model="goodsFormData.description"></uni-easyinput></uni-forms-item><view class="btnView"><button type="primary" @click="onSubmit">確認提交</button></view></uni-forms><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></view>
</template><script>const skuCloudObj = uniCloud.importObject("green-mall-sku", {"customUI": true});const goodsCloudObj = uniCloud.importObject("green-mall-goods", {"customUI": true})export default {data() {return {goodsFormData: {thumb: [],name: "",category_id: null,price: null,before_price: null,description: "",sku_select: []},addAttrType: "parent", //parent代表父,child代表子goodsRules: {name: {rules: [{required: true,errorMessage: "請輸入產品名稱"}]},price: {rules: [{required: true,errorMessage: "請輸入產品價格"}]},category_id: {rules: [{required: true,errorMessage: "請輸入產品分類"}]}},/*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: [],};},onLoad() {},computed: {skuTitle() {if (this.goodsFormData.sku_select.length) {let arr = this.goodsFormData.sku_select.map(item => {return item.skuName})console.log(arr);return arr.join("/")} else {return "點擊添加屬性"}}},methods: {//屬性返回子元素的名稱skuChildName(arr) {let nsArr = arr.map(item => {return item.name})return nsArr.join("/")},//點擊確認選擇 是在彈出框上選//some 數組至少有一個滿足 沒有就是false every就是每一個都要滿足,不滿足就是false// 這里filter 選出父級屬性 checked =true 被選中的 且子級屬性有一個被選中的數組對象;// 然后再對選中的對象,逐一進行map運算//運算就是filter 過濾出來選中的子級元素//返回一個 數組 arr 且元素為一個對象,對象展開了item ,然后將children的值放到里面,覆蓋item中的childrenclickConfirmSelect() {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})// console.log(item,11111111);// console.log(children,2222222);return {...item,// children //覆蓋了item中children}})this.goodsFormData.sku_select = arr //賦值后,頁面在使用這個數組來顯示 立即回顯this.$refs.attrWrapPop.close(); //關閉掉彈窗},//獲取sku列表async getSkuData() {let res = await skuCloudObj.get();this.skuArr = res.data// console.log(res);},//點擊添加屬性 index 存在就是嵌套下 父類屬性的子類選項 ,不存在就是添加父類屬性clickAddAttr(index = null) {if (index == null) {this.addAttrType = "parent"this.attrIndex = null} else {this.addAttrType = "child"this.attrIndex = index}this.$refs.addAttrPop.open();},//添加屬性彈窗的確認按鈕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)}},//點擊屬性的復選框 改變了值,也相應改變了顯示 后面也把值存到了數據庫changeCheckbox(index) {this.skuArr[index].checked = !this.skuArr[index].checked},//點擊屬性值的子元素 改變了值,也相應改變了顯示 后面也把值存到了數據庫clickChlidBtn(index, cIdx) {this.skuArr[index].children[cIdx].checked = !this.skuArr[index].children[cIdx].checked},//點擊選擇屬性clickSelect() {this.$refs.attrWrapPop.open(); //使用open方法彈出來if (this.skuArr.length) return;this.getSkuData();},//點擊提交表單onSubmit() {this.$refs.goodsForm.validate().then(res => {this.toDataBase();}).catch(err => {console.log(err);})},//上傳到云數據庫async toDataBase() {//這里缺少一個更新的按鈕,需要在list中去實現this.goodsFormData.thumb = this.goodsFormData.thumb.map(item => {return {url: item.url,name: item.name,extname: item.extname}})let res = await goodsCloudObj.add(this.goodsFormData)uni.showToast({title: "新增商品成功"})setTimeout(() => {uni.navigateBack()}, 1500)}}}
</script><style lang="scss" scoped>.goodsView {padding: 30rpx;.skuList {.item {padding: 30rpx;background: $page-bg-color;margin: 15rpx 0;@include flex-box-set(start);}}}.attrWrapper {padding: 30rpx;background: #fff;border-radius: 20rpx 20rpx 0 0;.head {@include flex-box();font-size: 34rpx;margin-bottom: 30rpx;.title {font-weight: bold;}.addAttr {color: $brand-theme-color-aux;}}.body {.item {border-top: 1px solid $border-color-light;&:last-child {border-bottom: 1px solid $border-color-light;}.top {padding: 30rpx 0;@include flex-box-set(start);.font {padding-left: 10rpx;font-weight: bold;}}.btnGroup {padding: 10rpx 0 30rpx;@include flex-box-set(start);flex-wrap: wrap;.btn {padding: 0rpx 25rpx;height: 60rpx;border: 1rpx solid $border-color-light;margin-right: 20rpx;border-radius: 10rpx;color: $text-font-color-2;margin-bottom: 20rpx;@include flex-box-set();&.active {border-color: $brand-theme-color;color: $brand-theme-color;background: rgba(236, 87, 79, 0.1);}}}}}.foot {padding: 50rpx 200rpx;}}
</style>