联动选择框组件例如:街道 楼栋 小区

联动选择框组件例如:街道 楼栋 小区

存一下代码直接用
数据结构:

解释下为啥要这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,
// })

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值