vue快速构建form表单:联动规则

29次阅读

共计 4777 个字符,预计需要花费 12 分钟才能阅读完成。

联动规则的构建(我的构建方式):构思:整个 form 表单分为 2 个部分 1 是 form 主要是整个 form 的显示,提交取消回调,错误信息显示等 2 输入控件:如 select 等
现在添加联动规则,select 为例:select 的选项获取有 2 种,参数设定和 ajax 获取两种所以联动有两种形式:过滤现有的选项和重置 ajax 请求参数获取选项 1. 设置要联动的字段参数过滤:
{
type: ‘select’,
name: ‘column2’,
column: ”,
linkage: ‘column1’, // 与 form 字段 column1 联动
linkageFilter (item, val) {
return item.value == val
},
options: [
{text: ‘ 测试 1 ’, value: ‘1’},
{text: ‘ 测试 2 ’, value: ‘2’},
{text: ‘ 测试 3 ’, value: ‘3’}
]
}
ajax 参数:
{
type: ‘select’,
name: ‘column2’,
column: ”,
linkage: ‘column1’, // 与 form 字段 column1 联动
url: ‘/’ // 只需要参数就好,到时 select 组件会自动将 column1=’val’ 作为请求参数
}
2.form.vue watch 监听选项变化检查每个字段是否有联动,如果有联动,将变化的值赋予对应的 select 组件内的 linkageVal
form: {
handler (val) {
// 联动规则
for(var i in this.options.columns){
if (this.options.columns[i].linkage){
this.$refs[this.options.columns[i].column][0].linkageVal = val[this.options.columns[i].linkage]
}
}
},
deep: true
}
3.select.vue 监听 linkageVal 的变化分别根据是否有 url 参数执行过滤还是重新 ajax 请求
我的源码:form.vue 组件
<template>
<form v-if=”options” onsubmit=”return false”>
<template v-for=”c in options.columns”>
<div class=”form-group”>
<label>
<span style=”color:red” v-if=”c.required”>*</span> {{c.name}}
</label>
<component :is=”‘v-‘+c.type” :class=”!errors[c.column]?’form-control’:’form-control is-invalid'” :options=”c” v-model=”form[c.column]” :ref=”c.column”/>
<div class=”invalid-feedback” v-if=”errors[c.column]”>{{errors[c.column] }}</div>
</div>
</template>
<a class=”btn border” v-on:click=”onCancel”> 取消 </a>
<div class=”form-group” v-if=”!options.template”>
<div class=”col-sm-12 justify-between text-right”>
<a class=”btn border” v-on:click=”onCancel”> 取消 </a>
<button class=”btn btn-primary” v-on:click=”onSave”>
<i class=”fa fa-spin fa-circle-o-notch” v-if=”options.submiting”/> 保存
</button>
</div>
</div>
</form>
</template>
<script>
import select from ‘./control/select’
export default{
name: ‘components-common-content-form’,
props: [‘options’],
data () {
return {
form: {},
errors: {}
}
},
watch: {
errors () {
this.$forceUpdate()
},
form: {
handler (val,oVal) {
if (typeof this.options.watch == ‘function’) {
this.options.watch(val)
}
// 联动规则
for(var i in this.options.columns){
if (this.options.columns[i].linkage){
this.$refs[this.options.columns[i].column][0].linkageVal = val[this.options.columns[i].linkage]
}
}
},
deep: true
}
},
methods: {
onSave () {
if (typeof this.options.onSave == ‘function’) {
this.options.onSave(this.form)
}
},
onCancel () {
if (typeof this.options.onCancel == ‘function’) {
this.options.onCancel(this.form)
}
this.$refs.ldm.getOptions()
},
setData (data) {
this.form = data
},
clearData () {
this.form = {}
},
setErrors (errors) {
this.errors = errors
},
clearErrors () {
this.errors = {}
}
},
components: {
‘v-select’: select
}
}
</script>
select.vue 组件
<template>
<div v-if=”options” class=”form-control”>
<div class=”bg-white rounded p-2″ v-if=”axiosSource”>
<span ><i class=”fa fa-spinner fa-pulse”/> 数据加载中 </span>
</div>
<div class=”bg-white rounded” v-else>
<select class=”form-control” v-model=”localValue”>
<option value=””> 请选择 {{options.name}}</option>
<option v-for=”o in showOptions” :value=”o.value”>{{o.text}}</option>
</select>
</div>
</div>
</template>
<script>
export default{
name: ‘components-common-content-control-checkbox’,
props: [‘options’,’value’],
data () {
return {
localValue: ”,
localOptions: [],
linkageVal: ”,
axiosSource: null
}
},
created () {
if (this.options.url) {
this.getOptions()
}else{
this.options.options?this.localOptions = this.options.options: this.localOptions = []
}
},
watch:{
localValue () {
this.$emit(‘input’, this.localValue)
},
value () {
this.localValue = this.value
},
// 联动 ajax 请求
linkageVal () {
if (this.options.url) {
this.getOptions()
}
}
},
computed: {
showOptions () {
var _this = this
var val = _this.linkageVal
var options = _this.localOptions
// 联动选项筛选
if (!this.options.url && typeof this.options.linkageFilter == ‘function’) {
options = options.filter(function(item){
if (val){
return _this.options.linkageFilter(item, val)
}else{
return true
}
})
}
return options
}
},
methods: {
getOptions () {
var _this = this
if (_this.axiosSource) {
_this.axiosSource.cancel(‘ 中断并开始新的请求 ’);
}
_this.axiosSource = axios.CancelToken.source()
// 联动请求
var url = _this.options.url
if (_this.linkageVal) {
url = _this.options.url + ‘?’ + this.options.linkage + ‘=’ + _this.linkageVal
}
// axios 开始请求
axios.get(url)
.then(function (response) {
_this.localOptions = response.data
_this.axiosSource = null
})
.catch(function (error) {
if (error.response.status == 400) {
_this.alert({
title: ‘ 提示 ’,
msg: error.response.data.message
});
}else{
_this.alert({
title: error.response.status + ‘ 错误 ’,
msg: error.response.data.message
});
}
_this.axiosSource = null
});
}
}
}
</script>
<style scoped>
.form-control{
padding: 0;
height: auto;
background: none;
}
.form-control .form-control{
border: 0px;
padding: 0.375rem 0.75rem;
}
.form-control select{
width: 100%;
height: 100%;
}
</style>
使用方式
<v-form :options=”options” class=”w-100″ ref=”form”/>

options: {
columns: [
{
type: ‘select’,
name: ‘select 联动主体 ’,
column: ‘ldm’,
options: [
{
text: ‘ 选择 1 ’,
value: 1
},
{
text: ‘ 选择 2 ’,
value: 2
}
]
},
{
type: ‘select’,
name: ‘select 联动附体 1 ’,
column: ‘lda1’,
linkage: ‘ldm’,
linkageFilter (item, val) {
return item.value == val
},
options: [
{
text: ‘ 联动 1 ’,
value: 1
},
{
text: ‘ 联动 2 ’,
value: 2
}
]
},
{
type: ‘select’,
name: ‘select 联动附体 2 ’,
column: ‘lda2’,
linkage: ‘ldm’,
url: ‘/’
}
]
}

正文完
 0