<template> <view class="select_popup_container"> <view class="popup_title"> <navigator v-if="mer_id" :url="`pages/product/addGoods/freightTemplate?mer_id=${mer_id}`" hover-class="none" class="manage_btn">管理</navigator> <view class="popup_title_msn">{{ selectProductTitle }}</view> <view class="close" @click="close"><text class="iconfont"></text></view> </view> <!-- 已选列表 --> <view class="selected_list" v-if="selectProductItem.multiple && multipleList.length"> <view class="selected_list_item" v-for="(item, index) in multipleList" :key="index"> <view>{{ item.label }}</view> <view @click="deleteSelectedList(item, index)"><view class="iconfont"></view></view> </view> </view> <!-- 标签头部 --> <view class="tap"> <scroll-view scroll-x="true" class="popup_tap"> <view class="popup_tap_content"> <view class="popup_tap_item" v-for="(item, index) in tap" :key="index" @click="handleSelectTapId(item, index)" :class="{ selectTapEd: selectTapId == item.value }"> <view>{{ item.label }}</view> </view> </view> </scroll-view> </view> <!-- 内容选择 --> <view class="content"> <scroll-view scroll-y="true" class="popup_sroll" @scrolltolower="scrolltolower"> <view class="content_list"> <view v-for="(item, index) in assemblyList" :key="index" class="content_list_item" :class="{ selectSingleCase: item.selectEd }"> <view @click="selectItem(item, assemblyList)">{{ item.label }}</view> <view v-if="selectProductItem.multiple && !item.children"><text class="iconfont" @click="selectPushMultiple(item, assemblyList)"></text></view> </view> </view> </scroll-view> </view> </view> </template> <script> // +---------------------------------------------------------------------- // | CRMEB [ CRMEB赋能开发者,助力企业发展 ] // +---------------------------------------------------------------------- // | Copyright (c) 2016~2024 https://www.crmeb.com All rights reserved. // +---------------------------------------------------------------------- // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权 // +---------------------------------------------------------------------- // | Author: CRMEB Team <admin@crmeb.com> // +---------------------------------------------------------------------- import { serialize } from '../../../libs/uniApi.js'; export default { props: { selectProductTitle: { type: String, default: '' }, // 从外部传入的分类数据 classifiedData: { type: Array, default: () => { return []; } }, // 表单数据 form: { type: Object, default: () => { return {}; } }, // 外部选项数据,携带需要进项判断的参数 selectProductItem: { type: Object, default: () => { return { // multiple true || false 是否多选 // model 外部表单的key值 // showTap 是否展示tap // allreadySelect 曾经的选项,用于再次打开后回显 // singleColumn 单列单选 }; } }, mer_id: { type: Number, default: 0 } }, data() { return { assemblyList: [], tap: [], // 标签数据 selectTapId: '', tapIndex: '', // 选中d的tap的下标 multipleList: [] // 多选的数组, 可用于展示 }; }, watch: { tap: { handler(val) { // console.log(val); }, deep: true }, multipleList: { handler(val) { this.$emit('multipleList', val, this.selectProductItem.model); } }, // 监听外部传入的数据变化,重新渲染数据 classifiedData: { handler(val) { this.initData(); }, deep: true } }, created() { this.initData(); this.tap.push({ value: '', label: '请选择', samelevel: this.assemblyList }); }, methods: { initData() { this.addClassifiedAttr(this.classifiedData, 'children', 'selectEd', false); // 代表有选中项 if (this.selectProductItem.singleColumn && (this.selectProductItem.allreadySelect && this.selectProductItem.allreadySelect.length) ) { this.assemblyList = serialize(this.classifiedData); this.assemblyList.forEach(item => { if (this.selectProductItem.allreadySelect.map(val => val.value).includes(item.value)) { item.selectEd = true; } }); return; } // 多选有数据 if (this.selectProductItem.allreadySelect && this.selectProductItem.allreadySelect.length && !this.selectProductItem.multiple) { this.tap = this.selectProductItem.allreadySelect; this.selectTapId = this.tap[0].value; this.handleSelectTapId(this.tap[0], 0); return; } // 品牌数据没有 value, label 字段 this.classifiedData.forEach(item => { if (!item.value) { this.$set(item, 'value', item.brand_id); } if (!item.label) { this.$set(item, 'label', item.brand_name); } }); this.assemblyList = serialize(this.classifiedData); }, selectItem(item, samelevel) { console.log(item); if (this.selectProductItem.multiple) { // 注意,只能选择最后一级 if (!item.children || !item.children.length) { item.selectEd = !item.selectEd; } } else { this.assemblyList.forEach(val => { val.selectEd = false; }); item.selectEd = true; } if (this.tap.filter(val => val.value === item.value).length) { return; } this.$set(item, 'samelevel', samelevel); if (this.selectTapId !== '') { if (!item.children || !item.children.length) { this.tap[this.tap.length - 1].label = item.label; this.tap[this.tap.length - 1].value = item.value; this.$emit('getLinkageData', this.tap, this.selectProductItem.model); return; } this.tap.splice(this.tapIndex, 1, item); this.tap.splice(this.tapIndex + 1, this.tap.length); this.selectTapId = ''; this.assemblyList = item.children; this.tap.push({ value: '', label: '请选择', samelevel: this.assemblyList }); return; } if (item.children && item.children.length && !this.selectTapId) { this.tap.splice(this.tap.length - 1, 0, item); this.assemblyList = item.children; } else { this.tap[this.tap.length - 1].label = item.label; this.tap[this.tap.length - 1].value = item.value; if (this.selectProductItem.multiple) { return; } this.$emit('getLinkageData', this.tap, this.selectProductItem.model); } }, // 多选时添加事件 selectPushMultiple(item, samelevel) { item.selectEd = true; this.multipleList.push(item); this.multipleList = this.unique(this.multipleList); }, // 数组去重 unique(arr) { var obj = {}; return arr.filter(ele => { if (!obj[ele]) { obj[ele] = true; return true; } }); }, // 删除已选项 deleteSelectedList(item, index) { this.multipleList.splice(index, 1); this.assemblyList.forEach(val => { if (item.value == val.value) { val.selectEd = false; } }); }, // 将数组用 "/" 连接 connectionString(arr, lab = '/') { return arr.map(item => item.label).join('/'); }, handleSelectTapId(item, index) { if (!item.value) { this.assemblyList = this.tap[this.tap.length - 2].children; this.selectTapId = ''; return; } if (index == this.tap.length - 1) { this.selectTapId = item.value; this.assemblyList = this.tap[this.tap.length - 2].children; return; } this.selectTapId = item.value; this.tapIndex = index; this.assemblyList = item.samelevel; }, // 递归添加属性 addClassifiedAttr(arr, childKey, addkey, value) { arr.forEach(item => { this.$set(item, addkey, value); if (item[childKey] && item[childKey].length) { this.addClassifiedAttr(item[childKey], childKey, addkey, value); } }); }, close() { this.$emit('close'); }, // 滑动组件滑倒底部时触发事件 scrolltolower() { this.$emit('scrolltolower', this.selectProductItem.model); } } }; </script> <style lang="scss" scoped> .select_popup_container { background: #fff; border-radius: 16rpx 16rpx 0 0; } .popup_title { display: flex; justify-content: flex-end; padding: 36rpx 30rpx; position: relative; .manage_btn{ font-weight: normal; color: #e93323; font-size: 24rpx; position: absolute; left: 30rpx; top: 40rpx; } &_msn { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: #282828; font-size: 32rpx; font-weight: bold; } .close { position: relative; z-index: 10; font-size: 28rpx; color: #8a8a8a; } } .selected_list { display: flex; flex-wrap: wrap; padding: 50rpx 30rpx; &_item { display: flex; align-items: center; color: #e93323; margin-right: 31rpx; margin-bottom: 40rpx; padding: 3rpx 11rpx; background: #fff6f5; .iconfont { display: inline-block; margin-left: 14rpx; font-size: 24rpx; } } } .popup_tap { display: flex; padding: 0 30rpx; color: #333333; font-size: 28rpx; border-bottom: 1px solid #eeeeee; margin-bottom: 40rpx; .popup_tap_content { display: flex; } &_item { margin-right: 60rpx; padding-bottom: 21rpx; white-space: nowrap; } .selectTapEd { color: #e93323; border-bottom: 3rpx solid #e93323; } } .content { .popup_sroll { max-height: 742rpx; min-height: 300rpx; } &_list { &_item { color: #333333; margin-bottom: 50rpx; margin-left: 40rpx; margin-right: 40rpx; display: flex; align-items: center; justify-content: space-between; > view { flex: 0.6; } > view:nth-child(2) { flex: 0.4; display: flex; justify-content: flex-end; } .iconfont { color: #e93323; font-size: 36rpx !important; } } } } .selectSingleCase { color: #e93323; } .selectTapEd { color: #e93323; border-bottom: 3rpx solid #e93323; } </style>