我们知道通过v-bind一个对象,便可以通过key与props做一个组件参数集成,一般都是用于静态属性绑定,如果我要在静态属性中绑定多个动态属性(如disabled属性由另一个按钮控制true,false),这种场景如何优雅的实现代码。虽然我实现了一个dome版本,但是实在不够优雅,有没有大神能指点一下,这类问题实在百度不到,跪谢了!
实现这个功能是为了将项目中的表单组件库抽象一个公共入口,直接配置JSON数据就可遍历生产页面和组件
详细代码在gitee仓库:gitee
线上效果地址:选择vbind下拉项
主入口index.vue
<template>
<div>
<component
v-for="(item, index) in fields"
:is="item.component"
:key="index"
v-bind="item"
v-model="item.vmodel"
></component>
<button @click="enableHandle">编辑/文本,变化</button>
<button @click="disabledHandle">禁用,变化</button>
</div>
</template>
<script>
import variableFormat from './field.js'
export default {
data() {
return {
fields: [],
enable: true,
disabled: true,
}
},
computed: {
enableCom: {
get() {
return this.enable
},
set(v) {
this.fields = this.fields.map((e) => {
e.enable = v
return e
})
this.enable = v
},
},
disabledCom: {
get() {
return this.disabled
},
set(v) {
this.fields = this.fields.map((e) => {
e.disabled = v
return e
})
this.disabled = v
},
},
},
methods: {
enableHandle() {
this.enableCom = !this.enableCom
},
disabledHandle() {
this.disabledCom = !this.disabledCom
},
},
created() {
this.fields = variableFormat(this)
},
}
</script>
<style>
</style>
input组件
<template>
<div>
<h1>input:</h1>
<el-input v-if="enable" :disabled="disabled" v-model="model" />
<span v-else>{{ value || '---' }}</span>
</div>
</template>
<script>
export default {
props: {
value: { type: String },
enable: { type: Boolean },
disabled: { type: Boolean },
},
data(){
return {
model: ''
}
},
watch: {
model(newVal) {
this.$emit('input', newVal)
},
},
}
</script>
<style>
</style>
select组件
<template>
<div>
<h1>select:</h1>
<el-select
v-if="enable"
class="path-select"
v-model="model"
filterable
placeholder="请选择"
:disabled="disabled"
>
<el-option
v-for="(item, index) in options"
:key="index"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
<span v-else>{{ value || '---' }}</span>
</div>
</template>
<script>
export default {
props: {
value: { type: [Number,String] },
enable: { type: Boolean },
disabled: { type: Boolean },
options: { type: Array },
},
data() {
return {
model: '',
}
},
watch: {
model(newVal) {
this.$emit('input', newVal)
},
},
}
</script>
<style>
</style>
字段配置
import ZbInput from './ZbInput'
import ZbSelect from './ZbSelect'
const field = [{
vmodel: '',
enable: true, // 可切换的动态值
disabled: false, // 可切换的动态值
component: ZbInput,
},
{
vmodel: '',
enable: true, // 可切换的动态值
disabled: false, // 可切换的动态值
options: [{ label: '张三', value: 1 }, { label: '李四', value: 2 }],
component: ZbSelect,
}
]
const variableFormat = vm => {
return field.map(e => {
e.enable = vm.enableCom
e.disabled = vm.disabledCom
return e
})
}
export default variableFormat