9***@qq.com
9***@qq.com
  • 发布:2025-11-17 10:59
  • 更新:2025-11-17 11:52
  • 阅读:59

【报Bug】当我滚动scroll-view时并开启scroll监听后,滚动到底部新增数据后会触发click函数

分类:uni-app

产品分类: uniapp/小程序/微信

PC开发环境操作系统: Mac

PC开发环境操作系统版本号: 15.3.1 (24D70)

第三方开发者工具版本号: 4.85 (ARM)

基础库版本号: 3.11.0

项目创建方式: CLI

CLI版本号: 3.0.0-4080420251103001

示例代码:

<template>
<scroll-view scroll-y class="session-list-container" @scroll="onScroll" @scrolltoupper="onScrolltoupper"
@scrolltolower="getList" v-if="list.length > 0" :throttle="false">
<view class="session-list-item" v-for="(item) in list" @click="handleClickSession(item)">
{{ item }}
</view>
</scroll-view>
</template>

<script setup>
import { ref } from 'vue';

const list = ref([]);
const loading = ref(false);
const has_more = ref(null);
const queryForm = ref({ page: 1, page_size: 10, is_active: false });

const getList = () => {
if (has_more.value === false || loading.value) {
return;
}
loading.value = true;
getData().then((res) => {
if (has_more.value === null) {
list.value = res;
} else {
list.value = [...list.value, ...res];
}
has_more.value = true;
loading.value = false;
}).catch(() => {
loading.value = false;
});
};

const getData = () => {
return new Promise((resolve) => {
setTimeout(() => {
resolve([{ id: 1 }, { id: 1 }, { id: 1 }, { id: 1 }, { id: 1 }, { id: 1 }, { id: 1 }, { id: 1 }, { id: 1 }, { id: 1 }, { id: 1 }, { id: 1 }, { id: 1 }, { id: 1 }, { id: 1 }, { id: 1 }, { id: 1 }, { id: 1 }, { id: 1 }, { id: 1 }, { id: 1 }, { id: 1 }]);
}, 100);
});
};

const onScroll = (event) => {
};
const onScrolltoupper = () => {
};
const handleClickSession = (item) => {
console.log('handleClickSession');
uni.showToast({
title: 'handleClickSession被触发',
icon: 'none',
});
// uni.navigateTo({
// url: '/pages/session/info?id=' + item.session_id,
// });
};

getList();
</script>

<style scoped lang="scss">
.session-list-container {
// padding: 40rpx;
// overflow: auto;
height: 100vh;
width: 100vw;
}

.session-list-item {
border-radius: 28rpx;
background: rgba(255, 255, 255, 0.1);
padding: 30rpx 0;
width: 100%;
position: relative;

.session-list-item-bar-name {
position: absolute;
right: 14rpx;
top: 30rpx;
font-size: 26rpx;
font-weight: 500;
color: rgba(255, 255, 255, 0.5);
width: 300rpx;
text-align: right;
}

.session-list-item-time {
font-size: 26rpx;
font-weight: 500;
color: rgba(255, 255, 255, 0.5);
padding: 0 36rpx;
}

.session-list-item-user {
display: flex;
align-items: center;
margin-top: 28rpx;

>view {  
  flex: 1;  
  text-align: center;  
  font-size: 20rpx;  
  font-weight: 500;  
  color: #fff;  

  &:first-child {  
    border-right: 1px solid #FFFFFF4C  
  }  

  >view:first-child {  
    font-size: 48rpx;  
    font-weight: 500;  
    color: rgba(131, 242, 230, 1);  
  }  

}  

}

&:not(:last-child) {
margin-bottom: 20rpx;
}
}
</style>

操作步骤:

滑动滚动到底部,就会触发@click里面的函数

预期结果:

应该不会触发click里面的函数,这个函数应该是点击以后才会触发的

实际结果:

滑动滚动到底部,就会触发@click里面的函数

bug描述:

当我滚动scroll-view时并开启scroll监听后,滑动滚动到底部新增数据后触发click函数,按正常应该是不会触发的我没点击具体view

2025-11-17 10:59 负责人:无 分享
已邀请:
DCloud_UNI_JBB

DCloud_UNI_JBB

替换 node_modules/@dcloudio/uni-mp-compiler/dist/transforms/vOn.js 为下面的内容试试能不能解决问题

"use strict";  
var __importDefault = (this && this.__importDefault) || function (mod) {  
    return (mod && mod.__esModule) ? mod : { "default": mod };  
};  
Object.defineProperty(exports, "__esModule", { value: true });  
exports.wrapperVOn = exports.transformOn = void 0;  
const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared");  
const compiler_core_1 = require("@vue/compiler-core");  
const shared_1 = require("@vue/shared");  
const crypto_1 = __importDefault(require("crypto"));  
const __1 = require("..");  
const runtimeHelpers_1 = require("../runtimeHelpers");  
const transformExpression_1 = require("./transformExpression");  
const vFor_1 = require("./vFor");  
const utils_1 = require("./utils");  
const fnExpRE = /^\s*([\w$_]+|(async\s*)?\([^)]*?\))\s*=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/;  
const transformOn = (dir, node, _context, augmentor) => {  
    const context = _context;  
    const { loc, modifiers, arg } = dir;  
    if (!dir.exp && !modifiers.length) {  
        context.onError((0, compiler_core_1.createCompilerError)(compiler_core_1.ErrorCodes.X_V_ON_NO_EXPRESSION, loc));  
    }  
    let eventName;  
    if (arg.type === compiler_core_1.NodeTypes.SIMPLE_EXPRESSION) {  
        if (arg.isStatic) {  
            const rawName = arg.content;  
            // for all event listeners, auto convert it to camelCase. See issue #2249  
            eventName = (0, compiler_core_1.createSimpleExpression)((0, shared_1.toHandlerKey)((0, shared_1.camelize)(rawName)), true, arg.loc);  
        }  
        else {  
            // #2388  
            eventName = (0, compiler_core_1.createCompoundExpression)([  
                // `${context.helperString(TO_HANDLER_KEY)}(`,  
                arg,  
                // `)`,  
            ]);  
        }  
    }  
    else {  
        // already a compound expression.  
        eventName = arg;  
        eventName.children.unshift(`${context.helperString(compiler_core_1.TO_HANDLER_KEY)}(`);  
        eventName.children.push(`)`);  
    }  
    // handler processing  
    let exp = dir.exp;  
    if (exp && !exp.content.trim()) {  
        exp = undefined;  
    }  
    let shouldCache = context.cacheHandlers && !exp && !context.inVOnce;  
    if (exp) {  
        const isMemberExp = (0, compiler_core_1.isMemberExpression)(exp.content, context);  
        const isInlineStatement = !(isMemberExp || fnExpRE.test(exp.content));  
        const hasMultipleStatements = exp.content.includes(`;`);  
        // process the expression since it's been skipped  
        if (context.prefixIdentifiers) {  
            isInlineStatement && context.addIdentifiers(`$event`);  
            exp = dir.exp = (0, transformExpression_1.processExpression)(exp, context, false, hasMultipleStatements);  
            isInlineStatement && context.removeIdentifiers(`$event`);  
            // with scope analysis, the function is hoistable if it has no reference  
            // to scope variables.  
            shouldCache =  
                context.cacheHandlers &&  
                    // unnecessary to cache inside v-once  
                    !context.inVOnce &&  
                    // runtime constants don't need to be cached  
                    // (this is analyzed by compileScript in SFC <script setup>)  
                    !(exp.type === compiler_core_1.NodeTypes.SIMPLE_EXPRESSION && exp.constType > 0) &&  
                    // #1541 bail if this is a member exp handler passed to a component -  
                    // we need to use the original function to preserve arity,  
                    // e.g. <transition> relies on checking cb.length to determine  
                    // transition end handling. Inline function is ok since its arity  
                    // is preserved even when cached.  
                    !(isMemberExp && node.tagType === compiler_core_1.ElementTypes.COMPONENT) &&  
                    // bail if the function references closure variables (v-for, v-slot)  
                    // it must be passed fresh to avoid stale values.  
                    !(0, compiler_core_1.hasScopeRef)(exp, context.identifiers) &&  
                    // wxs event  
                    !(0, utils_1.isFilterExpr)(exp, context);  
            // If the expression is optimizable and is a member expression pointing  
            // to a function, turn it into invocation (and wrap in an arrow function  
            // below) so that it always accesses the latest value when called - thus  
            // avoiding the need to be patched.  
            if (shouldCache && isMemberExp) {  
                if (exp.type === compiler_core_1.NodeTypes.SIMPLE_EXPRESSION) {  
                    exp.content = `${exp.content} && ${exp.content}(...args)`;  
                }  
                else {  
                    exp.children = [...exp.children, ` && `, ...exp.children, `(...args)`];  
                }  
            }  
        }  
        if (isInlineStatement || (shouldCache && isMemberExp)) {  
            // wrap inline statement in a function expression  
            exp = (0, compiler_core_1.createCompoundExpression)([  
                `${isInlineStatement  
                    ? context.isTS  
                        ? `($event: any)`  
                        : `$event`  
                    : `${context.isTS ? `\n//@ts-ignore\n` : ``}(...args)`} => ${hasMultipleStatements ? `{` : `(`}`,  
                exp,  
                hasMultipleStatements ? `}` : `)`,  
            ]);  
        }  
    }  
    let ret = {  
        props: [  
            (0, compiler_core_1.createObjectProperty)(eventName, exp || (0, compiler_core_1.createSimpleExpression)(`() => {}`, false, loc)),  
        ],  
    };  
    // apply extended compiler augmentor  
    if (augmentor) {  
        ret = augmentor(ret);  
    }  
    // TODO  
    if (shouldCache) {  
        // cache handlers so that it's always the same handler being passed down.  
        // this avoids unnecessary re-renders when users use inline handlers on  
        // components.  
        // ret.props[0].value = wrapper(  
        //   context.cache(ret.props[0].value) as ExpressionNode,  
        //   context  
        // )  
        ret.props[0].value = wrapperVOn(ret.props[0].value, node, context);  
    }  
    else {  
        ret.props[0].value = wrapperVOn(ret.props[0].value, node, context);  
    }  
    // mark the key as handler for props normalization check  
    ret.props.forEach((p) => (p.key.isHandlerKey = true));  
    return ret;  
};  
exports.transformOn = transformOn;  
function wrapperVOn(value, node, context) {  
    if ((0, transformExpression_1.isBuiltInIdentifier)(value)) {  
        return value;  
    }  
    // wxs event  
    if ((0, utils_1.isFilterExpr)(value, context)) {  
        return value;  
    }  
    const keys = [];  
    if (context.miniProgram.event?.key && context.inVFor) {  
        let keyProp = (0, compiler_core_1.findProp)(node, 'key');  
        if (!keyProp) {  
            const vForScope = (0, vFor_1.parseVForScope)(context.currentScope);  
            if (vForScope) {  
                keyProp = (0, compiler_core_1.findProp)(vForScope.node, 'key');  
            }  
        }  
        // 对 for 中的所有事件增加 key 标记,避免微信小程序不更新事件对象  
        if (keyProp && (0, uni_cli_shared_1.isDirectiveNode)(keyProp) && keyProp.exp) {  
            const keyCode = (0, __1.genExpr)(keyProp.exp);  
            if (keyCode) {  
                keys.push(',');  
                keys.push((0, __1.genExpr)(keyProp.exp));  
            }  
        }  
    }  
    // 给事件添加一标识,避免小程序事件覆盖问题 (question/198957)  
    const eventHashId = crypto_1.default  
        .createHash('sha256')  
        .update(JSON.stringify(value), 'utf8')  
        .digest('hex')  
        .slice(0, 2);  
    if (keys.length === 0) {  
        keys.push(`, "${eventHashId}"`);  
    }  
    const newExpr = (0, compiler_core_1.createCompoundExpression)([  
        `${context.helperString(runtimeHelpers_1.V_ON)}(`,  
        value,  
        ...keys,  
        `)`,  
    ]);  
    // 保存原始事件表达式  
    // @ts-expect-error 内部 parseVOn 时使用  
    newExpr.__withoutKeysVOnExpr = (0, compiler_core_1.createCompoundExpression)([  
        `${context.helperString(runtimeHelpers_1.V_ON)}(`,  
        value,  
        `)`,  
    ]);  
    return newExpr;  
}  
exports.wrapperVOn = wrapperVOn;  
  • 9***@qq.com (作者)

    可以了谢谢大佬,感动哭了!!!!!

    2025-11-17 12:02

  • DCloud_UNI_JBB

    回复 9***@qq.com: 记得打个patches,要不然你重新install了代码就丢了

    2025-11-17 12:03

  • 9***@qq.com (作者)

    回复 DCloud_UNI_JBB: 好的!谢谢!太感谢了!

    2025-11-17 12:04

DCloud_UNI_JBB

DCloud_UNI_JBB

用 v-show 替换 v-if 试试能不能解决问题

  • 9***@qq.com (作者)

    不行,不用v-if和v-show都不行

    2025-11-17 11:11

  • DCloud_UNI_JBB

    回复 9***@qq.com: 你清缓存了吗?

    2025-11-17 11:11

  • 9***@qq.com (作者)

    回复 DCloud_UNI_JBB: 清了,直接整个文件删了重新编译的

    2025-11-17 11:16

  • 9***@qq.com (作者)

    回复 DCloud_UNI_JBB: 我只要开启scroll监听,并往List里面增加数据就会出现这个问题,我不增加数据没有这个情况,或者我不监听没有这个情况,两个同时出现就会有这个情况

    2025-11-17 11:19

DCloud_UNI_JBB

DCloud_UNI_JBB

  • 9***@qq.com (作者)

    那我现在是需要怎么来解决这个问题

    2025-11-17 11:36

  • 9***@qq.com (作者)

    我那个代码把v-if删掉以后也会出现一样的问题

    2025-11-17 11:41

  • DCloud_UNI_JBB

    回复 9***@qq.com: 试一下上面贴的代码能不能解决你的问题

    2025-11-17 11:55

要回复问题请先登录注册