| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- <template>
- <view
- class="as-list-item"
- :class="{
- 'focus': focusValue == data[valueKey],
- 'disabled': disabled
- }">
- <view class="as-list-content" @tap="onClick">
- <view class="triangle-placeholder" v-if="hasChildren" >
- <view class="triangle-container" @tap.stop="toggle">
- <view class="triangle" :style="{'transform': open ? 'rotate(90deg)' : 'none'}"></view>
- </view>
- </view>
- <text style="margin-left: 5px;">{{data[labelKey]}}</text>
- </view>
- <view class="as-list-border"></view>
- <view v-if="hasChildren && open" class="as-list">
- <as-select-item
- v-for="item in data.children"
- :key="item[valueKey]"
- :data="item"
- :labelKey="labelKey"
- :valueKey="valueKey"
- :checkStrictly="checkStrictly"
- :disabled="item.disabled"
- @onSelect="onSelect">
- </as-select-item>
- </view>
- </view>
- </template>
- <script>
- import AsSelectItem from './as-select-item.vue';
- export default{
- name: 'AsSelectItem',
- props: {
- data: {
- type: Object,
- default: function() {
- return {}
- }
- },
- valueKey: {
- type: String,
- default: 'value'
- },
- labelKey: {
- type: String,
- default: 'label'
- },
- // 是否可以选择任意一级
- checkStrictly: {
- type: Boolean,
- default: false
- },
- disabled: {
- type: Boolean,
- default: false
- }
- },
- components: {
- AsSelectItem
- },
- data() {
- return {
- open: false,
- focusValue: null
- }
- },
- computed: {
- hasChildren: function(){
- return this.data.children && this.data.children.length
- }
- },
- methods: {
- onClick(){
- if(!this.disabled){
- this.focusValue = this.data[this.valueKey];
- setTimeout(()=> {
- this.focusValue = null;
- if(this.checkStrictly || !this.hasChildren){
- this.onSelect(this.data[this.valueKey]);
- }else{
- this.toggle();
- }
- }, 100)
- }
- },
- toggle(){
- this.open = !this.open;
- },
- onSelect(val){
- this.$emit('onSelect', val);
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- $border-color: #e5e5e5;
-
- .as-list-item{
- color: #666;
- font-size: 26rpx;
-
- .triangle-container{
- // padding: 5px 8px;
- width: 52rpx;
- height: 52rpx;
- display: flex;
- justify-content: center;
- align-items: center;;
- }
- .triangle {
- border-left: 16rpx solid #c0c4cc;
- border-top: 12rpx solid transparent;
- border-bottom: 12rpx solid transparent;
- }
- .as-list-border{
- position: relative;
- margin-left: 15px;
-
- &:after {
- position: absolute;
- top: 0;
- right: 0;
- left: 0;
- height: 1px;
- content: "";
- -webkit-transform: scaleY(.5);
- transform: scaleY(.5);
- background-color: $border-color;
- }
- }
-
- .as-list-content{
- padding: 10px 15px;
- line-height: 30px;
- display: flex;
- align-items: center;
- }
-
- .as-list{
- padding-left: 20px;
-
- .as-list-content{
- position: relative;
-
- &::before{
- content: '';
- border-left: 1px dashed $border-color;
- height: 26px;
- width: 1px;
- position: absolute;
- left: 8px;
- top: 50%;
- margin-top: -13px;
- }
- &::after{
- content: '';
- border-bottom: 1px dashed $border-color;
- height: 1px;
- width: 8px;
- position: absolute;
- top: 50%;
- left: 9px;
- margin-top: -1px;
- }
- }
- }
-
- &.focus>.as-list-content{
- background: #f1f1f1;
- }
- &.disabled>.as-list-content{
- color: #c7c7c7;
- }
- }
- </style>
|