这次的功能优点复杂,组件嵌套了很多次,自己表达能力毕竟有限,分享出来未必能讲明白。为了保持内容的连贯性,最终决定写一下。先看效果:
关键点:
1、组件嵌套
手风琴式折叠组件,嵌套输入行,还嵌套输入行的组合(例子中的边框)
2、多角度重置
实时监测当前值跟缺省值是否一致,并提供重置功能。
3、不得不感叹,VUE强大!
比上次的代码增加了一个RxInputRowGroup.vue文件,在inputs目录下。基于slot实现,关键看这个代码就好:
<template> <div class="row-group"> <div class="rx-input-row group-header" :class = "changed ? 'changed' :''"> <div class="label" :class="collapsed? 'collapsed' :''" @click="click" > {{label}} <div v-if="changed" class="reset-button" @click="resetAll" > {{$t('widgets.reset')}} </div> </div> <div v-if="collapsed" class="group-value"> <div v-for="row in inputValue" v-if="row.value" class="value-label" > {{row.value}} <span class="remove-button" @click="remove(row.value)">×</span> </div> </div> </div> <div v-if="!collapsed" class="row-group-body"> <slot></slot> </div> </div> </template> <script> export default { name: 'RxInputRowGroup', props:{ label:{ default:'' }, value:{ default:[] }, }, data () { return { collapsed: true, } }, computed:{ changed(){ for(var i in this.inputValue){ let row = this.inputValue[i] if(row.value !== row.defaultValue){ return true } } return false }, inputValue: { get:function() { return this.value; }, set:function(val) { this.$emit('input', val); }, }, }, methods: { click(){ this.collapsed = !this.collapsed }, resetAll(event){ for(var i in this.inputValue){ this.inputValue[i].value = this.inputValue[i].defaultValue } event.stopPropagation() }, remove(value){ for(var i in this.inputValue){ if(this.inputValue[i].value === value){ this.inputValue[i].value = '' } } } }, } </script> <style> .row-group .group-header .label{ justify-content: space-between; } .row-group-body .rx-input-row .label{ justify-content: center; } .row-group .group-header .label{ position: relative; } .row-group .group-header .label::after{ position: absolute; content: ''; width: 0; height: 0; top: 13px; right: 7px; border-width: 4px; border-style: solid; border-color: #c2c2c2 transparent transparent transparent; } .row-group .group-header .label.collapsed::after{ position: absolute; content: ''; width: 0; height: 0; top: 11px; right: 7px; border-width: 4px; border-style: solid; border-color:transparent transparent transparent #c2c2c2; } .group-value{ display: flex; flex-flow: row; flex-wrap: wrap; } .group-value .value-label{ display: flex; flex-flow: row; padding: 0 4px; height: 24px; align-items: center; justify-content: space-between; background: rgba(255,255,255,0.1); border-radius: 3px; margin: 1px; } .group-value .value-label .remove-button{ margin-left:2px; cursor: pointer; } </style>
调用处代码:
<template> <CollapsibleItem class="option-item" @itemClick = "itemClick"> <template #heading> {{inputValue.label}} <div v-if="changed" class="reset-button" @click="resetAll">{{$t('widgets.reset')}}</div> </template> <template #body> <RxInputRowGroup v-for="(row, i) in inputValue.rows" v-if="row.isRowGroup" :key="i" :label = "row.label" v-model = "row.rows" > <RxInputRow v-for="(subRow, j) in row.rows" :key="j" :label = "subRow.label" :inputName = "subRow.inputName" :inputProps = "subRow.props" :defaultValue = "subRow.defaultValue" v-model = "subRow.value" > </RxInputRow> </RxInputRowGroup> <RxInputRow v-else="row.isRowGroup" :key="i" :label = "row.label" :inputName = "row.inputName" :inputProps = "row.props" :defaultValue = "row.defaultValue" v-model = "row.value" > </RxInputRow> </template> </CollapsibleItem> </template>
累趴了,睡觉去了。
详细代码,请参考Github:https://github.com/vularsoft/studio-ui
若有有问题,请留言交流。