380 lines
9.0 KiB
Vue
380 lines
9.0 KiB
Vue
<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>
|
||
|
||
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>
|