VUE 实现 Studio 管理后台(十二):添加输入组合,复杂输入,输入框 Input 系列
这次的功能优点复杂,组件嵌套了很多次,自己表达能力毕竟有限,分享出来未必能讲明白。为了保持内容的连贯性,最终决定写一下。先看效果:
关键点:
1、组件嵌套
手风琴式折叠组件,嵌套输入行,还嵌套输入行的组合(例子中的边框)
2、多角度重置
实时监测当前值跟缺省值是否一致,并提供重置功能。
比上次的代码增加了一个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
若有有问题,请留言交流。
本作品采用《CC 协议》,转载必须注明作者和本文链接