uni-app icon indicating copy to clipboard operation
uni-app copied to clipboard

vue3 项目中微信小程序调用 wxs 方法无法传入响应式变量作为参数

Open obhasqr opened this issue 1 year ago • 3 comments
trafficstars

问题描述

vue3项目在模板中调用 wxs 写的方法运行到微信小程序时传入的参数变成 undefined,运行到 h5 正常。 用 hbuilderx 新建了空白 demo 测试了三种情况:

  1. 使用 v-for 遍历响应式数组并把 item 传入 wxs 方法 微信小程序 wxs 方法使用参数时对象属性为 undefined
  2. 直接传入响应式对象变量给 wxs 方法 微信小程序不会调用 wxs 方法
  3. 调用方法时直接传入对象 都可以正常工作

以下是 demo 代码

<template>
    <view class="content">
        <image class="logo" src="/static/logo.png"></image>
        <view class="text-area">
            <text class="title" v-for="(item, index) in users" :key="index">reacitve array: {{ wxs.formatInfo(item) }}</text>
            <text class="title">reacitve object: {{ wxs.formatInfo(user) }}</text>
            <text class="title">object: {{ wxs.formatInfo({ name: 'Test5', age: '18' }) }}</text>
        </view>
    </view>
</template>

<script module="wxs" lang="wxs">
var formatInfo = function (info) {
    console.log('formatInfo: ' + info + ', name: ' + info.name + ', age: ' + info.age)
    return '我是 ' + info.name + ", 今年 " + info.age
}

module.exports = {
    formatInfo: formatInfo
}
</script>

<script>
export default {
    data() {
        return {
            title: 'Hello',
            users: [
                {
                    name: 'Test',
                    age: '18'
                },
                {
                    name: 'Test2',
                    age: '19'
                },
                {
                    name: 'Test3',
                    age: '20'
                }
            ],
            user: {
                name: 'Test4',
                age: '18'
            }
        }
    },
    onLoad() {},
    methods: {}
}
</script>

复现步骤

  1. 写一个带参 wxs 方法
  2. 在模板中调用时传入响应式变量
  3. 运行到小程序

预期结果

微信小程序可以正常使用 wxs 方法

实际结果

微信小程序不能正常调用 wxs 方法 image log image

h5可以正常运行 image log image

系统信息:

  • 发行平台: 微信小程序、H5平台
  • 操作系统 : Microsoft Windows [Version 10.0.22631.2861]
  • HBuilderX版本: 3.98
  • 设备信息: WeChatLib: 3.1.5

补充信息

demo 是用 hbuilderx 创建的默认模板 vue3 项目

obhasqr avatar Dec 14 '23 10:12 obhasqr

HbuilderX 3.99.2023121601-alpha 可以复现

obhasqr avatar Dec 16 '23 16:12 obhasqr

发现 wxs 运行到 H5 时调用 getDate() 会报错:

Uncaught (in promise) ReferenceError: getDate is not defined
    at Object.getInfo (test-wxs-method.vue:21)

测试代码如下

<template>
    <view>
        <text>{{ wxs.getInfo() }}</text>
    </view>
</template>

<script module="wxs" lang="wxs">

var getInfo = function () {
    var pi = Math.PI
    console.log('pi: ', pi)

    var now = Date.now
    console.log('now: ', now)

    var str = JSON.stringify({name: 'ddd'})
    console.log('str: ', str.indexOf('name'))

    console.log('n: ', parseInt('11'))

    var date = getDate()
    console.log('date: ' + date)

    return 'pi: ' + pi +
        ', now: ' + now +
        ', str: ' + str +
        ', parseInt: ' + parseInt('11') +
        ', date: ' + date
}

module.exports = {
    getInfo: getInfo
}
</script>

另外 wxs 运行到 Android app 的时候更奇怪,iOS 没有测 1507f203dbb69eb6c908805df05c83a

HBuilderX 版本:3.99

obhasqr avatar Dec 27 '23 13:12 obhasqr

应用下面的补丁修复

diff --git a/node_modules/@dcloudio/uni-mp-compiler/dist/transforms/transformIdentifier.js b/node_modules/@dcloudio/uni-mp-compiler/dist/transforms/transformIdentifier.js
index c674f8b..35eff71 100644
--- a/node_modules/@dcloudio/uni-mp-compiler/dist/transforms/transformIdentifier.js
+++ b/node_modules/@dcloudio/uni-mp-compiler/dist/transforms/transformIdentifier.js
@@ -31,6 +31,38 @@ const transformIdentifier = (node, context) => {
                     content,
                     `)`,
                 ]), context);
+            } else {
+                const contentStr = content.children.map((child) => {
+                    if (typeof child === 'string') return child
+                    if (typeof child.content !== 'string') throw new Error('not support argument')
+                    return child.content
+                }).join('')
+                const lhs = contentStr.substring(0, contentStr.indexOf('('))
+                let isLiteral = false
+                for (let i = lhs.length + 1; i < contentStr.length; i++) {
+                    if (contentStr[i] === ' ') {
+                        continue
+                    }
+                    if (contentStr[i] === '{' || contentStr[i] === '[') {
+                        isLiteral = true
+                        break
+                    }
+                    break
+                }
+                
+                const paramStr = contentStr.substring(contentStr.indexOf('(') + 1, contentStr.indexOf(')'))
+                const rewriteParams = isLiteral
+                    ? [utils_1.rewriteExpression(compiler_core_1.createCompoundExpression([paramStr]), context)]
+                    : paramStr
+                          .split(',')
+                          .filter((p) => p.trim().length != 0)
+                          .map((param) => {
+                              return utils_1.rewriteExpression(compiler_core_1.createCompoundExpression([param]), context)
+                          })
+                node.content = utils_1.rewriteExpression(
+                    compiler_core_1.createCompoundExpression([lhs, '(', ...rewriteParams, ')']),
+                    context,
+                )
             }
         }
         else if ((0, compiler_core_1.isSlotOutlet)(node)) {

zhylmzr avatar May 15 '24 07:05 zhylmzr