項目中常用到form表單提交,並加以校驗,爲了簡化代碼,對elementUI的form表單進行一次簡單的組件封裝。
頁面大致如下:
直接上代碼~~
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>element-table</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://unpkg.com/[email protected]/lib/theme-chalk/index.css">
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/[email protected]/lib/index.js"></script>
<style>
#app {
margin-top: 100px;
}
.main-form {
width: 40%;
margin: 0 auto;
}
.submit-btn {
text-align: center;
}
</style>
</head>
<body>
<div id="app">
<form-component ref="form" :data="formData" :items="viewFormItems"></form-component>
<div class="submit-btn">
<el-button size="mini" type="primary" @click="submit">submit</el-button>
</div>
</div>
<script>
var formComponent = {
template: `
<el-form label-width="150px" :rules="rules" ref="items" :model="data">
<div class="main-form">
<div v-for="item in items" :key="item.label" :class="item.class || 'col-md-6'">
<el-form-item :label="item.label + ':'" :prop="item.prop">
<el-input
v-if="item.type === 'input'"
v-model="data[item.prop]"
:placeholder="item.props.placeholder || '請輸入'"
:disabled="item.props.disabled || false"
></el-input>
<el-select
v-if="item.type === 'select'"
v-model="data[item.prop]"
:placeholder="item.props.placeholder || '請選擇'"
:disabled="item.props.disabled || false"
style="width: 100%;"
>
<el-option
v-for="i in item.props.list"
:key="i.value"
:label="i.label"
:value="i.value"
></el-option>
</el-select>
<el-switch
v-model="data[item.prop]"
v-if="item.type === 'switch'"
:disabled="item.props.disabled || false"
></el-switch>
<el-date-picker
v-model="data[item.prop]"
v-if="item.type === 'date'"
:disabled="item.props.disabled || false"
type="date"
:placeholder="item.props.placeholder || '請選擇日期'"
style="width: 100%;"
></el-date-picker>
</el-form-item>
</div>
</div>
</el-form>
`,
props: {
formOption: Object,
items: Array,
data: Object
},
computed: {
rules () {
let rules = this.items.reduce((map, i) => {
if (i.rules) {
map[i.prop] = i.rules
}
return map
}, {})
return rules
}
},
methods: {
validate () {
return new Promise((resolve) => {
this.$refs.items.validate(resolve)
})
}
}
}
var app = new Vue({
el: '#app',
components: {
formComponent
},
data () {
return {
formData: {
actType: true,
actRegion: '',
name: '',
actDate: ''
},
viewFormItems: [
{
label: '活動名',
prop: 'name',
type: 'select',
props: {
placeholder: '請選擇活動名稱',
list: [{
value: '選項1',
label: '黃金糕'
}, {
value: '選項2',
label: '雙皮奶'
}]
},
rules: [
{ required: true, message: '請選擇活動名稱', trigger: 'blur' }
]
},
{
label: '活動區域',
prop: 'actRegion',
type: 'input',
props: {
placeholder: ''
},
rules: [
{ required: true, message: '請輸入活動區域', trigger: 'blur' }
]
},
{
label: '活動時間',
prop: 'actDate',
type: 'date',
props: {
placeholder: ''
}
},
{
label: '活動性質',
prop: 'actType',
type: 'switch',
props: {
placeholder: '',
disabled: true
}
},
]
}
},
methods: {
async submit () {
if (!(await this.$refs.form.validate())) {
return this.$message.error('請填寫完整信息')
}
console.log(this.formData)
}
},
mounted () {
}
})
</script>
</body>
</html>
此次只是簡單的封裝,可以直接拆開用到項目的vue文件中,剝離成公用的組件。這裏功能還不完善,傳參也不夠友好,後續再補充,大概會加上upload組件,自定義校驗邏輯,使用插槽slot,render-content以及優化封裝等。。。