为什么vue2+antdv render()创建下拉框滚动事件绑定不生效?
项目中有许多form表单提交,前辈就封装了一个组件
使用动态render()函数创建表单,对antdv 组件进行二次封装
上代码
----------------------------------正常界面,
<template> <page-header-wrapper :title="false">
<div class="add-frame-list" style="height: 100%;">
<div class="add-frame">
<span class="title">{{ supplier_id? $t("edit")+$t('supplier') : $t("plus")+$t('supplier') }}</span>
</div>
<div class="content">
<form-container
v-if="Object.values(dictObj).length > 0"
:formParams="productInfo"
:dictObj="dictObj"
ref="formContainer"
></form-container>
<div class="action-button">
<a-button type="primary" @click="saveData">{{ $t('save') }}</a-button>
</div>
</div>
</div>
</page-header-wrapper>
</template>
<script>
import FormContainer from "@/views/common/components/FormContainer.vue";
import { dictAPI } from "@/utils/dict.js";
import industrialEnt from "@/mixin/industrialEnt.js";
export default {
mixins: [industrialEnt],
components: {
FormContainer
},
data() {
let that = this;
return {
productInfo: {
industry_id: {
category: "customer-select",
value: undefined,
title: "产业",
require: true,
isUserDefind: true,
teledata: true,
params: {
options: []
},
events: {
change(value) {
that.changeIndustry(value,'这里正常触发,change事件');
},
popupScroll(value) {
console.log(value,'问题就在这,这里是不会触发的,我要在这里使用滚动事件,下拉框数据很多,足够触发这滚动事件');
},
}
},
ent_id: {
category: "customer-select",
value: undefined,
title: "企业",
require: true,
isUserDefind: true,
teledata: true,
params: {
options: []
},
events: {
change(value) {
// console.log(value, "***************");
}
}
}
},
dictObjCopy: {},
supplier_id: ""
};
},
computed: {
dictObj() {
if (this.industryList.length > 0 && this.industryEntList.length > 0) {
return {
...this.dictObjCopy,
industry_id: this.dealDict(this.industryList, [
"industry_id",
"industry_name",
"org_id"
]),
ent_id: this.dealDict(this.industryEntList, [
"ent_id",
"ent_name",
"model_class_id"
])
};
} else {
return {};
}
}
},
created() {
this.getDict();
},
methods: {
dealDict(arr, list) {
return arr.map(item => {
return {
dic_key: item[list[0]],
dic_v1: item[list[1]],
dic_type_id: item[list[2]]
};
});
},
async getDict() {
let res = await dictAPI(["project_type_id"]);
this.dictObjCopy = res;
},
}
};
</script>
--------------------------- FormContainer 表单 组件
<template> <a-form-model
:class="coverDefineClass"
ref="formContainer"
:layout="layout"
:model="formParams"
:hideRequiredMark="true"
>
<a-form-model-item
v-for="(node, name) in formParams"
:key="name"
:prop="`${name}.value`"
v-show="!node.isHiddenCurItem"
:rules="addRules(node)"
:class="{ 'holder-one-row': node.holderOneRow }"
>
<label v-if="(node.title ?node.title: '') !== ''" :title="node.title" slot="label">
{{ node.title }}
<span v-if="node.unit">({{ node.unit }})</span>
<span class="user-defind-required" v-if="node.require">*</span>
</label>
<FormsDistribution
v-bind="node"
v-model="node.value"
:class="{ 'is-view-state': isViewModel }"
></FormsDistribution>
</a-form-model-item>
</a-form-model>
</template>
<script>
import FormsDistribution from "./FormsDistribution.vue";
import getTeledata from "@/utils/getTeledata";
import { dealDict } from "@/utils/dict.js";
let computedValueFn = null;
export default {
name: "FormContainer",
components: {
FormsDistribution
},
watch: {
formParams: {
deep: true,
handler(val) {
if (!this.needComputedValue || !computedValueFn) return;
// 当需要有计算值时 计算当前功能
computedValueFn.bind(val)();
}
},
isViewModel() {
this.setViewModel();
}
},
props: {
// 序列化参数
formParams: {
type: Object,
default() {
return {};
},
required: true
},
dictObj: {
type: Object
},
// 排列方式,同Ant form 表单
layout: {
type: String,
default: "vertical"
},
// 需要计算值
needComputedValue: {
type: Boolean,
default: false
},
// 覆盖当前默认样式
coverDefineClass: {
type: String,
default: "user-defind-form"
},
// 切换至查看转态
isViewModel: {
type: Boolean,
default: false
}
},
watch: {
dictObj: {
deep: true,
handler(val, oldVal) {
this.dealObject();
}
}
},
created() {},
mounted() {
this.dealObject();
},
methods: {
dealObject() {
// 当需要远程数据填充表单数据
// 则执行相关操作
Object.keys(this.formParams).forEach(name => {
const item = this.formParams[name];
if (item.teledata) {
item.params.options = dealDict(this.dictObj[name]);
}
// 计算出当前是否有计算函数
if (item.computedValue) {
computedValueFn = item.computedValue;
}
// 如果当前为查看转态,则将每个表单置为disabled
if (this.isViewModel) {
this.setViewModel();
}
});
},
// 设置当前为查看状态,当为查看状态是,所有输入表单为不显示
setViewModel() {
Object.keys(this.formParams).forEach(name => {
const item = this.formParams[name];
if (!item.params) {
item.params = {};
}
item.params.disabled = this.isViewModel;
});
},
addRules(node) {
const temp = [];
if (node.require) {
temp.push({
required: true,
message: `${node.title}不能为空!`,
trigger: ["change", "blur"]
});
}
// 另外添加的规则
if (node.extendRule) {
temp.push(...node.extendRule);
}
return temp;
},
// 清空或填入当前表单内的数据
handleCurInputValue(rowData) {
return {
setData: () => {
Object.keys(this.formParams).forEach(name => {
this.formParams[name].value = rowData[name];
});
},
clearAllData: () => {
Object.keys(this.formParams).forEach(name => {
this.formParams[name].value = "";
});
}
};
},
// 输出当前键值对以及extraParams中额外参数数据JSON数据需要的字段
outputSaveFormater() {
let temp = {};
Object.keys(this.formParams).forEach(name => {
const node = this.formParams[name];
temp[name] = node.value;
// 如果有额外参数,直接转入传参结构数据中
if (node.extraParams) {
temp = { ...temp, ...node.extraParams };
}
});
return temp;
},
// 校验所有需要检验的数据
validAllData() {
return new Promise((resolve, reject) => {
this.$refs.formContainer.validate(valid => {
if (valid) {
const data = this.outputSaveFormater();
resolve(data);
} else {
reject(false);
}
});
});
},
// 清空所有表单内的数据
resetFormValue() {
this.$refs.formContainer.resetFields();
},
// 校验单列表单
triggerOneColumn(name) {
this.$refs.formContainer.validateField(`${name}.value`);
}
}
};
</script>
<style lang="less" scoped>
.user-defind-required {
color: #f5222d;
font-family: SimSun, sans-serif;
}
// 查看转态下的样式
.is-view-state {
background-color: #fafafa;
color: rgba(0, 0, 0, 0.85);
border: 0;
cursor: text;
/deep/ .ant-input.ant-input-disabled {
border: 0;
color: rgba(0, 0, 0, 0.85);
cursor: text;
}
/deep/ .ant-cascader-picker-arrow {
display: none;
}
/deep/ .ant-calendar-range-picker-input {
cursor: text;
}
}
</style>
------------------------- FormsDistribution 这个是创建组件rander函数
<!-- 根据传入表单类型,派发一个ant表单 --><script>
// import Vue from "vue";
export default {
name: "functionalComponents",
functional: true,
props: {
value: undefined,
category: {
type: String,
default: "",
required: true
},
params: {
type: Object,
default() {
return {};
}
},
events: {
type: Object,
default: () => {}
}
},
// a-input组件,需明确指明functional的绑定事件为 change.value
model: {
prop: "value",
// 这里好像不影响,无论怎么写好像都不对
// event: "change.value", // 最原始只有这行代码
// events: ["change","popupScroll"] // 这行代码为了测试添加的,不生效
},
render(h, context) {
const { props, data, children, scopedSlots,listeners } = context;
console.log(props.events, data.on,'props.events 是可以输出我绑定的popupScroll 函数,但是不执行**********');
let tempParams = props.params;
// 添加上自定义事件
data.on = { ...data.on, ...props.events };
// console.log(data.on,'最终data。on 也是有我绑定的 popupScroll 函数了,是不执行的 **********');
// 如果为自定义组件,遵从预定数据格式传参,则转换prop参数类型
if ((tempParams.placeholder ?? "") === "") {
const labelTxt = props.category.match(/(select|cascader)/g)
? "选择"
: "输入";
tempParams.placeholder = `请${labelTxt}${data.attrs.title}`;
}
if (data.attrs.isUserDefind) {
tempParams = { params: tempParams };
}
return h(
props.category,
{
...data,
props: tempParams,
listeners,
scopedSlots
},
children
);
}
};
</script>
各位大佬们求指教 为什么我创建出来的下拉框,无法正确执行滚动事件,而同样创建出来的change就能触发
因为代码是前辈写的,而且找不到人,我自己对rander()也不熟悉,求指教,已经一天了,如果在无法解决,我就得 在 FormContainer 表单 组件 中手动写各种输入框了
求大佬指教
表单赋值方式
setTimeout(() => {
this.$refs.formContainer.handleCurInputValue(object).setData();
}, 100);
回答:
<template> <a-select v-model="selectedValue" @dropdownVisibleChange="handleDropdownVisibleChange">
<template #dropdownRender="{ menu }">
<div @scroll="handleScroll">
{{ menu }}
</div>
</template>
<a-select-option value="option1">Option 1</a-select-option>
<a-select-option value="option2">Option 2</a-select-option>
</a-select>
</template>
<script>
export default {
data() {
return {
selectedValue: null
};
},
methods: {
handleDropdownVisibleChange(visible) {
if (visible) {
this.$nextTick(() => {
const dropdownMenu = document.querySelector('.ant-select-dropdown-menu');
if (dropdownMenu) {
dropdownMenu.addEventListener('scroll', this.handleScroll);
}
});
}
},
handleScroll(event) {
console.log('滚动事件触发', event);
// 处理滚动事件
}
}
};
</script>
以上是 为什么vue2+antdv render()创建下拉框滚动事件绑定不生效? 的全部内容, 来源链接: utcz.com/p/934747.html