Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

支付宝小程序中,往原生组件中传递function参数时,调用不到 #2273

Closed
NicInvade opened this issue Nov 16, 2020 · 42 comments

Comments

@NicInvade
Copy link

问题描述
mycomponents原生组件中,在props中有定义一个参数:onInit: () => { }
但是在vue中,传递的方法调用不到,以下几种方式都有问题:
1.
该写法是支付宝小程序要求的写法,但是原生组件中打印onInit,会出现:ƒ (){for(var e=arguments.length,t=new Array(e),r=0;r<e;r++)t[r]=arguments[r];return n.triggerEvent.apply(n,[a.method].concat(t))}
2.
这种写法,原生组件中的onInit方法还是预定义的默认函数。但是该写法,在微信小程序中是有效的。

补充信息
使用第一种写法的时候,断点测试了效果
以下代码,应该是支付宝小程序运行时的代码
微信图片_20201116104806
微信图片_20201116104812

@zhetengbiji
Copy link
Collaborator

改用 vue 事件的方式调用

@NicInvade
Copy link
Author

@zhetengbiji

onInitChart(F2, config) { const chart = new F2.Chart(config) return chart }
这里用事件没办法处理的,需要返回个chart对象给子组件
参数依赖,也是子组件传进来的

@zhetengbiji
Copy link
Collaborator

@zhetengbiji

onInitChart(F2, config) { const chart = new F2.Chart(config) return chart }
这里用事件没办法处理的,需要返回个chart对象给子组件
参数依赖,也是子组件传进来的

事件可以传递具体的参数,如遇到问题可以具体说下

@NicInvade
Copy link
Author

@zhetengbiji
这里的使用场景,不是子组件传事件给父组件
而是父组件往子组件中传函数,这个函数的调用上下文是子组件
上面写的onInitChart方法,定义在父组件中的,参数F2和config是子组件传进来的
而且该函数定义在父组件上,需要返回个chart对象给子组件使用

以上的代码使用的是蚂蚁金服的antv-f2图表库
https://github.com/antvis/my-f2
但是该库的使用示例找不到uniapp的
uniapp在支付宝中,往原生小程序传函数
貌似问题比较大,多种写法都不支持
而微信小程序是支持的

@zhetengbiji
Copy link
Collaborator

@zhetengbiji
这里的使用场景,不是子组件传事件给父组件
而是父组件往子组件中传函数,这个函数的调用上下文是子组件
上面写的onInitChart方法,定义在父组件中的,参数F2和config是子组件传进来的
而且该函数定义在父组件上,需要返回个chart对象给子组件使用

以上的代码使用的是蚂蚁金服的antv-f2图表库
https://github.com/antvis/my-f2
但是该库的使用示例找不到uniapp的
uniapp在支付宝中,往原生小程序传函数
貌似问题比较大,多种写法都不支持
而微信小程序是支持的

尝试变通为如下两种方式之一:

  1. 将props的onInitChart改为onInitChart事件,子组件中原本的直接执行onInitChart方法,改为emit onInitChart事件,并传入F2, config参数,父组件接收到事件后通过ref获取子组件实例,调用子组件方法传入chart对象给子组件
  2. 子组件直接通过 $parent 获取父组件实例上的onInitChart方法

@NicInvade
Copy link
Author

@zhetengbiji
这种方式改动比较大,而且还需要改第三方库的源码
uniapp中,没有往支付宝原生组件中传递函数的方法吗?
我看支付宝小程序是有这个写法的
微信图片_20201116161834
地址:https://opendocs.alipay.com/mini/framework/component_object

@NicInvade
Copy link
Author

@zhetengbiji
而且,提到的两种方法也是有问题的
方法一,子组件是原生组件,父组件用ref是调用不到的。
方法二,这种写法就限定了父组件只有一种调用方式。
如果多组件调用,将会有问题。该写法还有其他问题,不一一讨论了。

希望能够从本质上解决问题。

@mengxianren
Copy link

@NicInvade
子组件
1c964ab0c9c2107309a104bf4f6bfa5
vue 父组件
159ebbd30b5ef175fb91cb16d6c1c77
cc75d7d6559abf075958ec24e1b24c5
父组件中e打印undefind 可以用ref获取子组件中值

@mengxianren
Copy link

@NicInvade 我封的是select组件

@NicInvade
Copy link
Author

@mengxianren 图片看不到是...

@mengxianren
Copy link

@NicInvade
子组件:
import fmtEvent from "../fmtEvent.js"
Component({
mixins: [], // minxin 方便复用代码
data: {
changValue:""
}, // 组件内部数据
props: {
dataSource:[
{label:'option1', value:'option1'},
{label:'option2', value:'option2'},
{label:'disabled', value:'disabled11' ,disabled:true}],
placeholder:'请选择',
disabled:false,
value:'',
defaultValue:'',
mode:'single',
hasClear:false,
showSearch:false,
hasSelectAll:false,
onChange:function onChange(){}
// state:'error'
}, // 可给外部传入的属性添加默认值
didMount(){
}, // 生命周期函数
didUpdate(){},
didUnmount(){},
methods: { // 自定义方法
onChange(e) {
this.setData({changValue:e.detail.value})
var event = fmtEvent(this.props,e)//处理事件格式
this.props.onChange(event)
},
},
})
父组件:
<all-select ref="allSelect" @change="onChange">
onChange(e){
console.log(e)//打印undefinde 获取不到事件
let aa = this.$refs.allSelect.data.changValue
console.log(aa )//可以获取子组件值
}

@NicInvade
Copy link
Author

@mengxianren
你打印的undefined,应该是下面这里的打印
企业微信截图_16055176636779

这个地方应该是undefined了,后面继续调属性,这里应该报错了
也有可能下面这里没有走到,可以打个断点试试
企业微信截图_16055176271291

有没有方法直接传属性啊 =-=!!

@mengxianren
Copy link

@NicInvade 父组件给子组件传值,直接传就好啊,子组件props里定义属性,父组件直接传

@NicInvade
Copy link
Author

@mengxianren 支付宝子组件是原生组件,props中的属性是function类型的时候,父组件传进去的function,获取不到啊。。

@NicInvade
Copy link
Author

@mengxianren
下面这个是支付宝原生子组件
企业微信截图_16055188776089

这个是vue父组件,是支付宝推荐的写法
企业微信截图_16055188867392

这个是vue父组件的另外一种写法,微信小程序中正常的,但是支付宝小程序子组件还是拿不到父组件的test方法
企业微信截图_1605518893302

@mengxianren
Copy link

@NicInvade 图片看不到,f2图表,uni有个vue的插件你看看好不好用

@NicInvade
Copy link
Author

@mengxianren
子组件
Component({ props: { onChange:function onChange(){ console.log('origin:function') } }, didMount(){ this.props.onChange() } })

父组件调用方式一:
`
<template>
<all-select onChange="test">
</template>

<script> export default { name: "test", methods: { test() { console.log('test') } } } </script>

`

父组件调用方式二:
`
<template>
<all-select :on-change="test">
</template>

<script> export default { name: "test", methods: { test() { console.log('test') } } } </script>

`

@mengxianren
Copy link

@NicInvade 首先你先看下你封的组件在支付宝中可不可已调用,然后vue中调用的写法要把onChange 改为@change

@NicInvade
Copy link
Author

@mengxianren
组件是可以调用的,子组件didMount钩子函数有执行到
改为@change的方法是无效的,测试过了。而且这里不是子组件往父组件传事件。。

@NicInvade
Copy link
Author

@mengxianren @zhetengbiji
问题已经解决,需要启用支付宝component2编译模式
才可以像微信小程序一样传递function,具体细节还待研究下

@mengxianren
Copy link

@NicInvade ......我一直以为你是启用的

@zhetengbiji
Copy link
Collaborator

@mengxianren
Copy link

转化为小程序时获取不到第三方包怎么办? @NicInvade

@thxl2010
Copy link

thxl2010 commented May 9, 2021

@NicInvade #2273 (comment)

我这边本地开发者工具可以调用父组件方法,但是预览和线上测试没有触发,已启用component2。

@zhetengbiji
Copy link
Collaborator

@NicInvade #2273 (comment)

我这边本地开发者工具可以调用父组件方法,但是预览和线上测试没有触发,已启用component2。

是这样监听事件吗? @xxx="xxx"

@thxl2010
Copy link

@NicInvade #2273 (comment)
我这边本地开发者工具可以调用父组件方法,但是预览和线上测试没有触发,已启用component2。

是这样监听事件吗? @xxx="xxx"

子组件:

{
  methods: {
    async onClose(event) {
      console.log('join-member onClose event :', event);
      this.props.onClose(event);
      // this.$page.data.onClose(event);
    },

    async onAuthSuccess(res) {
      console.log('join-member onAuthSuccess res :', res);
      this.props.onAuthSuccess(res);
    },

    async onAuthFail(res) {
      console.log('join-member onAuthFail res :', res);
      this.props.onAuthFail(res);
    }
  }
}

父组件:

    <join-member
      :expend="showMemberCenter"
      :sellerId="sellerId"
      @close="onClose"
      @authFail="onAuthFail"
      @authSuccess="onAuthSuccess"
    />

@zhetengbiji
Copy link
Collaborator

@NicInvade #2273 (comment)
我这边本地开发者工具可以调用父组件方法,但是预览和线上测试没有触发,已启用component2。

是这样监听事件吗? @xxx="xxx"

子组件:

{
  methods: {
    async onClose(event) {
      console.log('join-member onClose event :', event);
      this.props.onClose(event);
      // this.$page.data.onClose(event);
    },

    async onAuthSuccess(res) {
      console.log('join-member onAuthSuccess res :', res);
      this.props.onAuthSuccess(res);
    },

    async onAuthFail(res) {
      console.log('join-member onAuthFail res :', res);
      this.props.onAuthFail(res);
    }
  }
}

父组件:

    <join-member
      :expend="showMemberCenter"
      :sellerId="sellerId"
      @close="onClose"
      @authFail="onAuthFail"
      @authSuccess="onAuthSuccess"
    />

用法看起来没有问题,后续我测试一下你说的预览问题,你先切换不同的基础库试试

@thxl2010
Copy link

@zhetengbiji 我升级了uni包,本地提示事件信息不存在,改用了 #917 (comment) 的事件绑定方法,可以触发了

@zhetengbiji
Copy link
Collaborator

@zhetengbiji 我升级了uni包,本地提示事件信息不存在,改用了 #917 (comment) 的事件绑定方法,可以触发了

之前不是最新的吗?用的版本多少?现在用的多少?

使用 vue 事件监听是 3.1.0+ 开始支持的

@Consifire
Copy link

Consifire commented Mar 17, 2022

@mengxianren @zhetengbiji 问题已经解决,需要启用支付宝component2编译模式 才可以像微信小程序一样传递function,具体细节还待研究下

你好,我这也遇到跟你差不多的问题,也是function传进去props里面null。另外请问知道如何在父组件中获取原生子组件的实例吗,因为ref无效而又必须在父组件中调用子组件的方法。全用原生来写的话就可以通过ref=saveref saveref(e){this.childcomponent = e } 来获取,但是在uniapp .vue中该写法不可行,有没有了解可替代的方案

-----------------。。。启用component2就可以了,之前浪费了好多时间尝试【😀】

@tyust512
Copy link

@zhetengbiji 我升级了uni包,本地提示事件信息不存在,改用了 #917 (comment) 的事件绑定方法,可以触发了

我也通过这个方法搞定了支付宝烽火feeds插件,不过我是在组件中展示,用的mounted生命周期,如果是页面中才用onLoad。解决这些问题太难了。我发现跟着 @zhetengbiji 的代码和思路走,怎么都是不对,要不是不执行,要不就是报:事件方法不存在。

@zhetengbiji
Copy link
Collaborator

@zhetengbiji 我升级了uni包,本地提示事件信息不存在,改用了 #917 (comment) 的事件绑定方法,可以触发了

我也通过这个方法搞定了支付宝烽火feeds插件,不过我是在组件中展示,用的mounted生命周期,如果是页面中才用onLoad。解决这些问题太难了。我发现跟着 @zhetengbiji 的代码和思路走,怎么都是不对,要不是不执行,要不就是报:事件方法不存在。

版本多少?

@tyust512
Copy link

@zhetengbiji 我升级了uni包,本地提示事件信息不存在,改用了 #917 (comment) 的事件绑定方法,可以触发了

我也通过这个方法搞定了支付宝烽火feeds插件,不过我是在组件中展示,用的mounted生命周期,如果是页面中才用onLoad。解决这些问题太难了。我发现跟着 @zhetengbiji 的代码和思路走,怎么都是不对,要不是不执行,要不就是报:事件方法不存在。

版本多少?

指的是谁的版本?vue? uni?支付宝基础库版本?

@zhetengbiji
Copy link
Collaborator

@zhetengbiji 我升级了uni包,本地提示事件信息不存在,改用了 #917 (comment) 的事件绑定方法,可以触发了

我也通过这个方法搞定了支付宝烽火feeds插件,不过我是在组件中展示,用的mounted生命周期,如果是页面中才用onLoad。解决这些问题太难了。我发现跟着 @zhetengbiji 的代码和思路走,怎么都是不对,要不是不执行,要不就是报:事件方法不存在。

版本多少?

指的是谁的版本?vue? uni?支付宝基础库版本?

uni-app 版本

@tyust512
Copy link

@zhetengbiji 我升级了uni包,本地提示事件信息不存在,改用了 #917 (comment) 的事件绑定方法,可以触发了

我也通过这个方法搞定了支付宝烽火feeds插件,不过我是在组件中展示,用的mounted生命周期,如果是页面中才用onLoad。解决这些问题太难了。我发现跟着 @zhetengbiji 的代码和思路走,怎么都是不对,要不是不执行,要不就是报:事件方法不存在。

版本多少?

指的是谁的版本?vue? uni?支付宝基础库版本?

uni-app 版本

你看看下面的版本不,不知道你要哪个~

"@dcloudio/uni-cli-shared": "2.0.0-29320201014001", "@dcloudio/uni-migration": "2.0.0-29320201014001", "@dcloudio/uni-template-compiler": "2.0.0-29320201014001", "@dcloudio/vue-cli-plugin-hbuilderx": "2.0.0-29320201014001", "@dcloudio/vue-cli-plugin-uni": "2.0.0-29320201014001", "@dcloudio/vue-cli-plugin-uni-optimize": "2.0.0-29320201014001", "@dcloudio/webpack-uni-mp-loader": "2.0.0-29320201014001", "@dcloudio/webpack-uni-pages-loader": "2.0.0-29320201014001", "@types/uni-app": "^1.4.3",

@zhetengbiji
Copy link
Collaborator

@zhetengbiji 我升级了uni包,本地提示事件信息不存在,改用了 #917 (comment) 的事件绑定方法,可以触发了

我也通过这个方法搞定了支付宝烽火feeds插件,不过我是在组件中展示,用的mounted生命周期,如果是页面中才用onLoad。解决这些问题太难了。我发现跟着 @zhetengbiji 的代码和思路走,怎么都是不对,要不是不执行,要不就是报:事件方法不存在。

版本多少?

指的是谁的版本?vue? uni?支付宝基础库版本?

uni-app 版本

你看看下面的版本不,不知道你要哪个~

"@dcloudio/uni-cli-shared": "2.0.0-29320201014001", "@dcloudio/uni-migration": "2.0.0-29320201014001", "@dcloudio/uni-template-compiler": "2.0.0-29320201014001", "@dcloudio/vue-cli-plugin-hbuilderx": "2.0.0-29320201014001", "@dcloudio/vue-cli-plugin-uni": "2.0.0-29320201014001", "@dcloudio/vue-cli-plugin-uni-optimize": "2.0.0-29320201014001", "@dcloudio/webpack-uni-mp-loader": "2.0.0-29320201014001", "@dcloudio/webpack-uni-pages-loader": "2.0.0-29320201014001", "@types/uni-app": "^1.4.3",

哦,你的版本比较老的原因,执行 npx @dcloudio/uvm 更新一下依赖

@tyust512
Copy link

npx @dcloudio/uvm 3.2.12.20211029

@zhetengbiji 我升级了uni包,本地提示事件信息不存在,改用了 #917 (comment) 的事件绑定方法,可以触发了

我也通过这个方法搞定了支付宝烽火feeds插件,不过我是在组件中展示,用的mounted生命周期,如果是页面中才用onLoad。解决这些问题太难了。我发现跟着 @zhetengbiji 的代码和思路走,怎么都是不对,要不是不执行,要不就是报:事件方法不存在。

版本多少?

指的是谁的版本?vue? uni?支付宝基础库版本?

uni-app 版本

你看看下面的版本不,不知道你要哪个~
"@dcloudio/uni-cli-shared": "2.0.0-29320201014001", "@dcloudio/uni-migration": "2.0.0-29320201014001", "@dcloudio/uni-template-compiler": "2.0.0-29320201014001", "@dcloudio/vue-cli-plugin-hbuilderx": "2.0.0-29320201014001", "@dcloudio/vue-cli-plugin-uni": "2.0.0-29320201014001", "@dcloudio/vue-cli-plugin-uni-optimize": "2.0.0-29320201014001", "@dcloudio/webpack-uni-mp-loader": "2.0.0-29320201014001", "@dcloudio/webpack-uni-pages-loader": "2.0.0-29320201014001", "@types/uni-app": "^1.4.3",

哦,你的版本比较老的原因,执行 npx @dcloudio/uvm 更新一下依赖

npx @dcloudio/uvm 3.2.12.20211029 可以吗?哪个版本以下,就不支持funtion传递了?

@zhetengbiji
Copy link
Collaborator

npx @dcloudio/uvm 3.2.12.20211029

@zhetengbiji 我升级了uni包,本地提示事件信息不存在,改用了 #917 (comment) 的事件绑定方法,可以触发了

我也通过这个方法搞定了支付宝烽火feeds插件,不过我是在组件中展示,用的mounted生命周期,如果是页面中才用onLoad。解决这些问题太难了。我发现跟着 @zhetengbiji 的代码和思路走,怎么都是不对,要不是不执行,要不就是报:事件方法不存在。

版本多少?

指的是谁的版本?vue? uni?支付宝基础库版本?

uni-app 版本

你看看下面的版本不,不知道你要哪个~
"@dcloudio/uni-cli-shared": "2.0.0-29320201014001", "@dcloudio/uni-migration": "2.0.0-29320201014001", "@dcloudio/uni-template-compiler": "2.0.0-29320201014001", "@dcloudio/vue-cli-plugin-hbuilderx": "2.0.0-29320201014001", "@dcloudio/vue-cli-plugin-uni": "2.0.0-29320201014001", "@dcloudio/vue-cli-plugin-uni-optimize": "2.0.0-29320201014001", "@dcloudio/webpack-uni-mp-loader": "2.0.0-29320201014001", "@dcloudio/webpack-uni-pages-loader": "2.0.0-29320201014001", "@types/uni-app": "^1.4.3",

哦,你的版本比较老的原因,执行 npx @dcloudio/uvm 更新一下依赖

npx @dcloudio/uvm 3.2.12.20211029 可以吗?哪个版本以下,就不支持funtion传递了?

可以直接使用 3.4.7.20220422,如果一定要找版本可以看下更新日志:https://download1.dcloud.net.cn/hbuilderx/changelog/3.4.7.20220422.html

@tyust512
Copy link

npx @dcloudio/uvm 3.2.12.20211029

@zhetengbiji 我升级了uni包,本地提示事件信息不存在,改用了 #917 (comment) 的事件绑定方法,可以触发了

我也通过这个方法搞定了支付宝烽火feeds插件,不过我是在组件中展示,用的mounted生命周期,如果是页面中才用onLoad。解决这些问题太难了。我发现跟着 @zhetengbiji 的代码和思路走,怎么都是不对,要不是不执行,要不就是报:事件方法不存在。

版本多少?

指的是谁的版本?vue? uni?支付宝基础库版本?

uni-app 版本

你看看下面的版本不,不知道你要哪个~
"@dcloudio/uni-cli-shared": "2.0.0-29320201014001", "@dcloudio/uni-migration": "2.0.0-29320201014001", "@dcloudio/uni-template-compiler": "2.0.0-29320201014001", "@dcloudio/vue-cli-plugin-hbuilderx": "2.0.0-29320201014001", "@dcloudio/vue-cli-plugin-uni": "2.0.0-29320201014001", "@dcloudio/vue-cli-plugin-uni-optimize": "2.0.0-29320201014001", "@dcloudio/webpack-uni-mp-loader": "2.0.0-29320201014001", "@dcloudio/webpack-uni-pages-loader": "2.0.0-29320201014001", "@types/uni-app": "^1.4.3",

哦,你的版本比较老的原因,执行 npx @dcloudio/uvm 更新一下依赖

npx @dcloudio/uvm 3.2.12.20211029 可以吗?哪个版本以下,就不支持funtion传递了?

可以直接使用 3.4.7.20220422,如果一定要找版本可以看下更新日志:download1.dcloud.net.cn/hbuilderx/changelog/3.4.7.20220422.html

只能说一个坑接着一个坑,我升级依赖,启动后。现在报错这个:

支付宝小程序TypeError: Cannot set property 'stopPropagation' of undefined
 
支付宝原生组件如此,调用this.props.onFunc()就报上面错误。
`
Component({
props: {
onFunc: function onFunc(args) {},
},
data: {
isShow: 'none',
imgsrc: '',
placeholder: '',
value: '',
fp: ''
},
methods: {
test() {
console.warn('i am clicked');
this.props.onFunc();
}
},
})

`

@zhetengbiji
Copy link
Collaborator

npx @dcloudio/uvm 3.2.12.20211029

@zhetengbiji 我升级了uni包,本地提示事件信息不存在,改用了 #917 (comment) 的事件绑定方法,可以触发了

我也通过这个方法搞定了支付宝烽火feeds插件,不过我是在组件中展示,用的mounted生命周期,如果是页面中才用onLoad。解决这些问题太难了。我发现跟着 @zhetengbiji 的代码和思路走,怎么都是不对,要不是不执行,要不就是报:事件方法不存在。

版本多少?

指的是谁的版本?vue? uni?支付宝基础库版本?

uni-app 版本

你看看下面的版本不,不知道你要哪个~
"@dcloudio/uni-cli-shared": "2.0.0-29320201014001", "@dcloudio/uni-migration": "2.0.0-29320201014001", "@dcloudio/uni-template-compiler": "2.0.0-29320201014001", "@dcloudio/vue-cli-plugin-hbuilderx": "2.0.0-29320201014001", "@dcloudio/vue-cli-plugin-uni": "2.0.0-29320201014001", "@dcloudio/vue-cli-plugin-uni-optimize": "2.0.0-29320201014001", "@dcloudio/webpack-uni-mp-loader": "2.0.0-29320201014001", "@dcloudio/webpack-uni-pages-loader": "2.0.0-29320201014001", "@types/uni-app": "^1.4.3",

哦,你的版本比较老的原因,执行 npx @dcloudio/uvm 更新一下依赖

npx @dcloudio/uvm 3.2.12.20211029 可以吗?哪个版本以下,就不支持funtion传递了?

可以直接使用 3.4.7.20220422,如果一定要找版本可以看下更新日志:download1.dcloud.net.cn/hbuilderx/changelog/3.4.7.20220422.html

只能说一个坑接着一个坑,我升级依赖,启动后。现在报错这个:

支付宝小程序TypeError: Cannot set property 'stopPropagation' of undefined   支付宝原生组件如此,调用this.props.onFunc()就报上面错误。 ` Component({ props: { onFunc: function onFunc(args) {}, }, data: { isShow: 'none', imgsrc: '', placeholder: '', value: '', fp: '' }, methods: { test() { console.warn('i am clicked'); this.props.onFunc(); } }, })

`

示例工程提供一下

@tyust512
Copy link

请问事例工程如何提供给您 @zhetengbiji

@zhetengbiji
Copy link
Collaborator

请问事例工程如何提供给您 @zhetengbiji

可以直接去除业务代码后上传。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants