本节课完成user页面下的diolog表单,表单里的元素都是动态渲染,以一个CommonForm组件的形式放入user页面。
1.CommonForm组件
新建CommonForm.vue组件,添加props,用于接受3个参数,formLabel为一个数组,form的相关配置,form的表单数据,类型为Object,表单布局inline,为一个布尔值。el-form添加属性,首先是ref标识,可以通过refs拿到ref实例,label-width为初始高度,但是会根据内容变化而变化,并不固定。model用来数据的双向绑定(重要),我们传入的数据是form。inline属性表示dialog样式,inline表示上下排列。对传入的form进行遍历,label表示表单域名称。表单组件有input(姓名、年龄、地址)、select(性别选择)、switch、datepicker(日期)、option(下拉)。
首先判断组件的type,input组件设置placeholder属性,表示input框内的文字,使用字符串拼接。v-model进行数据绑定,拿到form下面的[item.model],form前面已经model过了,这里就可以使用。switch、select()、switch、datepicker、option的方法也类似。
最后对组件进行扩展,slot后面会讲个slot的作用。
<template>
<el-form ref="form" label-width="100px" :model="form" :inline="inline">
<el-form-item v-for="item in formLabel" :key="item.label" :label="item.label">
<el-input
v-if="item.type === 'input'"
:placeholder="'请输入'+item.label"
v-model="form[item.model]">
</el-input>
<el-switch
v-if="item.type === 'switch'"
v-model="form[item.model]">
</el-switch>
<el-date-picker
v-if="item.type === 'date'"
type="date"
value-format="yyyy-MM-dd"
placeholder="选择日期"
v-model="form[item.model]">
</el-date-picker>
<el-select
v-if="item.type === 'select'"
placeholder="请选择"
v-model="form[item.model]">
<el-option
v-for="item in item.opts"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item>
<slot></slot>
</el-form-item>
</el-form>
</template>
<script>
export default{
name:'CommonForm',
// 由外部组件传入数据。
props:{
formLabel:Array,
form:Object,
inline:Boolean,
},
data(){
}
}
</script>
2.User引入CommonForm
引入CommonForm,
import CommonForm from '../../src/components/CommonForm.vue'
components:{
CommonForm
},
这里吧前面的表单以一个dialog弹窗显示, dialog表头可能是新增用户或更新用户,这里需要对title进行判断,这里还没写到更新,所以operateType给默认值add,visible属性表示弹窗是否显示,这里用isShow指代,给一个false默认值。在dialog里面引入CommonForm标签。operateFormLabel数组提前准备好,存放的是CommonForm的用户input内容。
<common-form
:formLabel="operateFormLabel"
:form="operateForm"
:inline="true"
ref="form">
</common-form>
operateFormLabel赋值给formLabel,operateForm赋值给form,inline默认为true,即样式为inline布局,ref拿到组件实例。加上弹窗底部footer,利用刚刚的slot标签。添加两个button。分别是“取消”“确定”。第一个button设定点击事件,将isShow设为false,第二个button添加点击事件comfirm函数,这里预留空值,type设置为primary(高亮显示)。
在dialog外还有两个button,分别是新增和搜索。新增按钮添加addUser事件。搜索按钮添加getList事件,这里再一次引入CommonForm,因为我们需要一个input输入框,但是我们考科一通过更换数据而不是更换组件达到目标效果。注意对比两次引入CommonForm组件的不同之处。formLabel数组,包含一个对象,因为只有一个搜索框,对象里包含三个属性,model、label、type,model为自定义名称、label为输入框前的标签、type为输入类型。SearchForm存放keyworld内容。
<common-form
:formLabel="formLabel"
:form="searchFrom"
:inline="true"
ref="form">
编辑addUser函数
addUser(){
this.isShow = true,
this.operateType = 'add',
this.operateForm = {
name:'',
addr:'',
age:'',
birth:'',
sex:''
}
},
自此,user下的index.vue文件如下:
<template>
<div class="manage">
<!-- dialog为弹窗内容 -->
<el-dialog
:title="operateType === 'add' ? '新增用户' : '更新用户'"
:visible.sync="isShow">
<!-- 这里冒号是将数据传送给CommonForm组件。 -->
<common-form
:formLabel="operateFormLabel"
:form="operateForm"
:inline="true"
ref="form">
</common-form>
<div slot="footer" class="dialog-footer">
<el-button @click="isShow = false">取消</el-button>
<el-button type="primary" @click="confirm">确认</el-button>
</div>
</el-dialog>
<div class="manage-header">
<el-button type="primary" @click="addUser">+新增</el-button>
<common-form
:formLabel="formLabel"
:form="searchFrom"
:inline="true"
ref="form">
<el-button type="primary" @click='getList'>+搜索</el-button>
</common-form>
</div>
</div>
</template>
<script>
import CommonForm from '../../src/components/CommonForm.vue'
export default{
name:'User',
components:{
CommonForm
},
data(){
return{
operateType:'add',
isShow:false,
operateFormLabel:[
{
model: 'name',
label: '姓名',
type: 'input'
},
{
model: 'age',
label: '年龄',
type: 'input'
},
{
model: 'sex',
label: '性别',
type: 'select',
opts: [
{
label: '男',
value: 1
},
{
label: '女',
value: 0
}
]
},
{
model: 'birth',
label: '出生日期',
type: 'date'
},
{
model: 'addr',
label: '地址',
type: 'input'
}
],
operateForm:{
name:'',
addr:'',
age:'',
birth:'',
sex:''
},
formLabel:[
{
model:"keyword",
label:'',
type:'input'
},
],
searchFrom:{
keyword:'',
}
}
},
methods:{
confirm(){
},
addUser(){
this.isShow = true,
this.operateType = 'add',
this.operateForm = {
name:'',
addr:'',
age:'',
birth:'',
sex:''
}
},
getList(){
}
}
}
</script>
添加样式,弹性布局,左右两边靠边,上下对齐。
<style lang="less" scoped>
.manage-header{
display: flex;
justify-content: space-between;
align-items: center;
}
</style>