联动选择框组件例如:街道 楼栋 小区
存一下代码直接用
数据结构:
解释下为啥要这3个参数,其实可以一个得 例如: url:”、api/xxx/xxx?a=1&bb“ 项目特殊所有分三个参数
baseUrl: 基本得接口请求
paramsUrl: 参数 addrCodeLevel=5&parentCode$street &后面可以自己定义方便解析
dataUrlDes: , 返回参数取label 值字段 和 value 字段
{
width: 12,
type: 'select',
label: '街道',
value: 'street',
baseUrl: api.formAjax.address,
paramsUrl: 'addrCodeLevel=4',
dataUrlDes: {
label: 'addrCodeDes',
value: 'addrCodeId',
},
validate: {
required: true,
message: '必填',
trigger: 'blur',
},
options: [],
},
{
width: 12,
type: 'select',
label: '小区',
value: 'housingEstate',
baseUrl: api.formAjax.address,
paramsUrl: 'addrCodeLevel=5&parentCode$street',
dataUrlDes: {
label: 'addrCodeDes',
value: 'addrCodeId',
},
options: [],
},
{
width: 12,
type: 'select',
label: '楼栋',
value: 'building',
baseUrl: api.formAjax.address,
paramsUrl: 'addrCodeLevel=6&parentCode$housingEstate',
dataUrlDes: {
label: 'addrCodeDes',
value: 'addrCodeId',
},
options: [],
},
初始化数据
数据初始化,有需要接口请求得主动发出接口请求,有关联得建立watch监听 (watchsBox用来去重,组件反复复用得时候不会出问题)
handleData({
dataName: 'formProps',
modelName: 'form',
watchName: '受理申请',
vue: this,
})
import axios from 'axios'
/**
* 处理数据 用处:需要远程请求数据 配置paramsUrl:“。。。。”
*
* @param {Object} dataName 数据源名字
* @param {Object} modelName 组件中v-model数据 名字
* @param {Object} watchName 保证监听属性得唯一性(组件复用得时候用到)
* @param {Object} vue vue指针
*/
const watchsBox = {}
export async function handleData(options) {
// 处理下watch
let watchName = options.watchName || 'commond'
if (!watchsBox[watchName]) {
watchsBox[watchName] = new Map()
}
let vue = options.vue || {}
let templetList = vue[options.dataName] || []
for (let templet of templetList) {
doTemplateAjax(templet, options)
}
// let target = options.options.target || {}
// let obj = common.isEmptyObject(target) ? templet : target
// // 处理datasourceList
}
/**
* 处理单个模板 templet
*
* @param {Object} dataName 数据源名字
* @param {Object} modelName 组件中v-model数据 名字
* @param {Object} watchName 保证监听属性得唯一性(组件复用得时候用到)
* @param {Object} vue vue指针
*/
const doTemplateAjax = (templet, options, isNoFirst = false) => {
let modelName = options.modelName
let vue = options.vue
// let watchName = options.watchName
// 后续这里加类型
if (templet.type === 'select') {
if (templet.baseUrl&& templet.baseUrl.length > 0) {
let { url, params } = getParams(templet, options)
// // 判断接口是否需要model中得其他参数
let isPost = true
for (let item in params) {
if (
params[item] === '' ||
params[item] === null ||
params[item] === undefined
) {
isPost = false
break
}
}
if (isPost) {
console.log('接口请求111', url, params, watchsBox, process)
axios
.post(url, {
data: params,
format: 'json',
})
.then(res => {
if (res.data && Array.isArray(res.data)) {
let isHas = false
res.data.forEach(item => {
if (templet.dataUrlDes) {
item.label = item[templet.dataUrlDes.label]
item.value = item[templet.dataUrlDes.value]
}
if (
vue[modelName][templet.value] == item.value
) {
// 说明原有得值 能匹配到数据
isHas = true
}
})
// console.log(
// isHas,
// templet,
// vue[modelName][templet.value],
// templet.value,
// vue[modelName][templet.value] &&
// !isHas &&
// isNoFirst,
// )
// vue[modelName][templet.value] &&
if (!isHas && isNoFirst) {
// 这里不知道为啥没有触发 watch
vue.$set(vue[modelName], [templet.value], '')
}
options.vue.$set(templet, 'options', res.data)
}
})
.catch(err => {
console.log(err, 'adasdasdasdad')
options.vue.$set(templet, 'options', [])
})
} else {
vue.$set(vue[modelName], [templet.value], '')
options.vue.$set(templet, 'options', [])
}
}
}
}
/**
* 处理url参数
*
* @param {Object} dataName 数据源名字
* @param {Object} modelName 组件中v-model数据 名字
* @param {Object} watchName 保证监听属性得唯一性(组件复用得时候用到)
* @param {Object} vue vue指针
*/
const getParams = (templet, options) => {
let modelName = options.modelName
let vue = options.vue
let watchName = options.watchName
// 判断url 有没有参数
let url = templet.baseUrl
let params = {}
// let headers = templet.headers || {}
let paramsList = []
if (templet.paramsUrl) {
paramsList = templet.paramsUrl.split('&')
}
// 处理参数 建立监听
paramsList.forEach(element => {
if (element.indexOf('=') >= 0) {
let tempParams = element.split('=')
params[tempParams[0]] = tempParams[1]
} else {
// 解析联动参数 xxx{aaa}
let arr = element.split('$')
params[arr[0]] = vue[modelName][arr[1]]
if (!watchsBox[watchName].get(`${modelName}.${arr[1]}`)) {
// 因为这里有联动得参数,自身需要 建立监听
vue.$watch(`${modelName}.${arr[1]}`, () => {
console.log(
`监听成功,再次执行对应得单个模板数据${modelName}.${arr[1]}`,
templet,
)
// 监听变化之后,将相关联需要它作为参数得模板对应得字段设置为“”
doTemplateAjax(templet, options, true)
})
}
watchsBox[watchName].set(`${modelName}.${arr[1]}`, true)
}
})
return { url, params }
}
// this.$template.handleTemplateData({
// dataName: 'formData',
// modelName: 'model',
// watchName: "xxxx",
// vue: this,
// })