为什么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

回到顶部