| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- <template>
- <view class="as-select-container" :class="{'as-select-disabled': disabled, 'as-select-border': border}">
- <view class="as-select-input" @tap="open">
- <input :name="name" :value="label" :placeholder="placeholder" :placeholderStyle="placeholderStyle" disabled/>
-
- <slot name="suffix-icon">
- <uni-icons type="bottom" size="18" color="#999"></uni-icons>
- </slot>
- </view>
- <as-popup ref="popup" type="bottom">
- <view class="as-tree-select-popup">
- <view class="as-tree-select-popup-mask" @tap="close"></view>
- <view class="as-tree-select-popup-content">
- <as-nav-bar :color="titleColor" :backgroundColor="titleBackgroundColor" :border="false" :statusBar="false"
- :title="title" class="as-select-nav-bar">
- <template slot="right">
- <uni-icons class="rightIcon" :color="titleColor" type="closeempty"
- size="23" @click="close"></uni-icons>
- </template>
- </as-nav-bar>
-
- <scroll-view scroll-y="true" :style="{'height': listHeight}">
- <view class="as-list" v-if="options && options.length">
- <as-select-item
- v-for="item in options"
- :key="item[valueKey]"
- :data="item"
- :labelKey="labelKey"
- :valueKey="valueKey"
- :checkStrictly="checkStrictly"
- :disabled="item.disabled"
- @onSelect="confirm">
- </as-select-item>
- </view>
- <as-empty v-else text="暂无数据"></as-empty>
- </scroll-view>
- </view>
- </view>
- </as-popup>
- </view>
- </template>
- <script>
- import AsSelectItem from './as-select-item.vue';
- export default {
- name: "as-tree-select",
- model: {
- prop: 'value',
- event: 'input'
- },
- // options: {
- // styleIsolation: 'shared'
- // },
- components: {
- AsSelectItem
- },
- props: {
- name: {
- type: String,
- require: true
- },
- disabled: {
- type: Boolean,
- default: false
- },
- // 是否可以选择任意一级
- checkStrictly: {
- type: Boolean,
- default: false
- },
- value: {
- type: String,
- default: ''
- },
- listHeight: {
- type: String,
- default: '258px'
- },
- placeholder: {
- type: String
- },
- options: {
- type: Array,
- default: function() {
- return []
- }
- },
- valueKey: {
- type: String,
- default: 'value'
- },
- labelKey: {
- type: String,
- default: 'label'
- },
- // 标题
- title: {
- type: String,
- default: ''
- },
- // 标题栏文字颜色
- titleColor: {
- type: String,
- default: '#3a3a3a'
- },
- // 标题栏背景色
- titleBackgroundColor: {
- type: String,
- default: '#fff'
- },
- // 是否显示边框
- border: {
- Type: Boolean,
- default: true
- },
- // placeholder的样式(内联样式,字符串),如"color: #ddd"
- placeholderStyle: {
- Type: String
- }
- },
- data() {
- return {
- }
- },
- computed:{
- label: function(){
- const getParent = (data, nodeId) => {
- let arrRes = [];
- if (data.length === 0) {
- return arrRes;
- }
- const rev = (options, nodeId) => {
- for (let i = 0, length = options.length; i < length; i++) {
- const node = options[i];
- if (node[this.valueKey] === nodeId) {
- arrRes.unshift(node[this.labelKey]);
- rev(data, node.parentId);
- break;
- } else {
- if (node.children) {
- rev(node.children, nodeId);
- }
- }
- }
- return arrRes;
- }
- arrRes = rev(data, nodeId);
- return arrRes;
- }
- const label = getParent(this.options, this.value);
- return label.join('/');
- }
- },
- methods: {
- open() {
- if(!this.disabled){
- this.$refs.popup.open();
- }
- },
- close(){
- this.$refs.popup.close();
- },
- confirm(val){
- this.$emit('change', val);
- this.$emit('input', val);
- this.close();
- }
- }
- }
- </script>
- <style lang="scss">
-
- .as-select-container {
- width: 100%;
- border-radius: 4px;
- box-sizing: border-box;
- .as-select-input{
- display: flex;
- align-items: center;
- min-height: 36px;
- position: relative;
- gap: 16rpx;
-
- /deep/ .uni-input-input{
- pointer-events: none;
- }
- }
- input {
- width: 100%;
- height: 1.4em;
- min-height: 1.4em;
- line-height: 1;
- font-size: 14px;
- color: rgb(51, 51, 51);
- }
- uni-icons {
- flex-shrink: 0;
- }
-
- &.as-select-disabled{
- background-color: #eee;
- }
- &.as-select-border{
- border: 1px solid #e5e5e5;
- padding: 0 10px;
- }
- }
- .as-tree-select-popup {
- height: calc(100vh - 50px);
- position: relative;
-
- .as-tree-select-popup-mask{
- position: absolute;
- width: 100%;
- height: 100%;
- top: 0;
- }
-
- .as-tree-select-popup-content{
- background: #fff;
- // display: flex;
- flex-direction: column;
- position: absolute;
- bottom: 0;
- width: 100%;
- }
-
- }
-
- .as-select-nav-bar{
- border-bottom:1px solid #e5e5e5;
- display: block;
- }
-
- .as-list{
- text-align: left;
- }
- .as-empty{
- height: 258px;
- }
- </style>
|