uni-app 应提供一个类似element-plus cascader的组件
uni-app 应提供一个类似element-plus cascader的组件
如题,uni-app应增加一个类似element plus Cascader 一样的级联选择组件,这样后端采用element-ui的项目移动端迁移会比较方便,当然其他的组件也需进一步丰富,但cascader有着特殊的数据结构,也较为复杂,对于普通开发者有着比较大的挑战,希望官方能够考虑,谢谢。
下面的代码是基于插件商城ba-tree-picker修改的一个简单替代,不过问题也很多,同时要求treenode id必须唯一,也不支持标签查询,对于大数据量的场景体验也很差,但可以作为参考
<!-- 树形层级选择器-->
<!-- 1、支持单选、多选 -->
<template>
<view>
<view>
<uni-easyinput :clearable="true" v-model="text" @clear="_clearTreeList"
placeholder="title" prefix-icon="search" @iconClick="_click" :disabled="readonly"></uni-easyinput>
</view>
<uni-popup type="bottom" ref="xTreepop" :is-mask-click="false">
<!-- <view class="tree-cover" :class="{'show':showDialog}" @tap="_cancel"></view>
<view class="tree-dialog" :class="{'show':showDialog}">
<view class="tree_pop">
<uni-section :title="title" titleFontSize="11pt" :color="titleColor" type="line">
<template v-slot:right>
<uni-tag text="确定" :type="readonly?'default':'success'" :circle="true" @tap="_confirm" v-show="multiple" class="uni-pr-4"></uni-tag>
<uni-tag text="关闭" type="warning" :circle="true" @tap="_cancel" class="uni-mr-3"></uni-tag>
</template>
</uni-section>
<view class="tree-view">
<scroll-view class="tree-list" :scroll-y="true">
<block v-for="(item, index) in treeList" :key="index">
<view class="tree-item" :style="[paddingLeft: item.level*30 + 'rpx'}]" :class="{itemBorder: border === true, show: item.isShow}">
<view class="item-label">
<view class="item-icon uni-inline-item" @tap.stop="_onItemSwitch(item, index)">
<view v-if="!item.isLastLevel&&item.isShowChild" class="switch-on" style="{'border-left-color':switchColor}">
</view>
<view v-else-if="!item.isLastLevel&&!item.isShowChild" class="switch-off" style="{'border-top-color':switchColor}">
</view>
<view v-else class="item-last-dot" :style="{'border-top-color':switchColor}">
</view>
</view>
<view class="uni-flex-item uni-inline-item" @tap.stop="_onItemSelect(item, index)">
<view class="item-name"> {{item.name+(item.childCount?"("+item.childCount+")":'')}}</view>
<view class="item-check" v-if="selectParent?true:(item.isLastLevel)">
<view class="item-check-yes" v-if="item.checkStatus==1" class="{'radio':!multiple}" :style="{'border-color':confirmColor}">
<view class="item-check-yes-part" style="{'background-color':confirmColor}">
</view>
</view>
<view class="item-check-yes" v-else-if="item.checkStatus==2" class="{'radio':!multiple}" :style="{'border-color':confirmColor}">
<view class="item-check-yes-all" :style="{'background-color':confirmColor}">
</view>
</view>
<view class="item-check-no" v-else-if="item.checkStatus==0" :class="{'radio':!multiple}" style="{'border-color':confirmColor}">
</view>
<view class="item-check-disabled" v-else :class="{'radio':!multiple}" style="{'border-color':confirmColor}">
</view>
</view>
</view>
</view>
</view>
</block>
</scroll-view>
</view>
</view>
</uni-popup>
</view>
</template>
1 回复
在 uni-app 中,虽然没有一个官方的组件完全等同于 Element Plus 的 Cascader(级联选择器),但你可以通过组合现有的组件和自定义逻辑来实现类似的功能。以下是一个简单的示例,展示如何在 uni-app 中创建一个自定义的级联选择器组件。
首先,你需要创建一个自定义组件,例如 Cascader.vue
:
<template>
<view class="cascader">
<picker mode="multiSelector" :range="ranges" :value="selectedValues" @change="handleChange">
<view class="picker-view">
<view v-for="(items, index) in displayedItems" :key="index">
{{ displayedItems[index][selectedValues[index]] }}
</view>
</view>
</picker>
</view>
</template>
<script>
export default {
props: {
options: {
type: Array,
required: true
}
},
data() {
return {
selectedValues: [],
ranges: []
};
},
computed: {
displayedItems() {
return this.ranges.map(range => range.map(item => item.label));
}
},
watch: {
options: {
handler(newVal) {
this.initRanges(newVal);
},
immediate: true
}
},
methods: {
initRanges(options) {
let tempRanges = [];
options.forEach(level => {
tempRanges.push(level.map(item => ({ value: item.value, label: item.label })));
});
this.ranges = tempRanges;
this.selectedValues = new Array(this.ranges.length).fill(0);
},
handleChange(e) {
this.selectedValues = e.detail.value;
this.$emit('change', this.selectedValues.map((value, index) => this.options[index].find(item => item.value === value)));
}
}
};
</script>
<style scoped>
.cascader {
/* 样式根据需要自定义 */
}
.picker-view {
display: flex;
flex-direction: column;
}
</style>
在这个组件中,我们使用了 picker
组件的 multiSelector
模式来模拟级联选择器的行为。ranges
属性存储了每一级选项的数据,selectedValues
属性存储了当前选中的值。我们通过监听 picker
的 change
事件来更新选中的值,并通过 emit
事件将选中的选项传递给父组件。
父组件可以这样使用这个自定义组件:
<template>
<view>
<Cascader :options="options" @change="handleCascaderChange" />
</view>
</template>
<script>
import Cascader from './components/Cascader.vue';
export default {
components: {
Cascader
},
data() {
return {
options: [
// 选项数据
]
};
},
methods: {
handleCascaderChange(selectedOptions) {
console.log(selectedOptions);
}
}
};
</script>
这个示例提供了一个基本的级联选择器功能,你可以根据实际需求进一步扩展和优化。