vue3 里面使用 jsx 解构属性,响应式丢失了,怎么处理

2022-12-31 21:54:17 +08:00
 daiwenzh5

如:

const someprops = useAnyHooks();
// someprops 值
const getOne = computed(() => anyvalue);
someprops = {
	one: getOne.value,
}
// 因为存在多个属性,所以直接解构方便一点,但是 one 的响应式好像没了,anyvalue 不会触发更新
return () => (
	<component {...someprops} ></component>
)
// 这样是正常的
return () => (
	<component one={one.value} ></component>
)

这个属性 someprops 里面 one 属性,丢失了响应式,这个怎么处理优雅一点?

5547 次点击
所在节点    Vue.js
78 条回复
shakukansp
2023-01-03 00:05:41 +08:00
@johnkiller 为什么在函数里就能触发 getter 了?本质是什么,我真服了
johnkiller
2023-01-03 00:12:55 +08:00
@shakukansp 当 render 函数被调用的时候,才会访问 ref 的.value ,也就是触发 getter ,然后才收集到 render 函数作为依赖啊。要是在 setup 里就触发了 getter ,肯定收集不到 render 函数啊。

实在不明白加我 tg 咱慢慢聊,跟你在这堆楼真是和大妈吵架一样。

https://t.me/IIIlIIlllIIIlIIlIIIIIIlIlI
johnkiller
2023-01-03 00:18:33 +08:00
@shakukansp 你说传给 watchEffect 的函数为什么必须要马上被调用?为什么不能在变量被修改后再调用?

为什么用 watch 传两个函数就可以解决?它的第一个函数会被立即调用吗?第二个函数呢?

你能整的明白吗?
shakukansp
2023-01-03 00:20:42 +08:00
@johnkiller 你这又是把 setup 当渲染函数,又把东西放函数里了,要像 react 一样 setup 运行多次才能通过 getter 读取到新值。

我就问你,假如 setup 返回一个对象而不是渲染函数 那你这 { count: count.value, inc: () => count.value++ } 还能行吗
shakukansp
2023-01-03 00:25:07 +08:00
@johnkiller 嘿,回你 43 楼,那你讲讲,const a = ref(1), 为什么 watch 要传 () => a.value 或者 a, 而不能传 a.value?
johnkiller
2023-01-03 00:25:23 +08:00
@shakukansp 当然不行,如果行楼主就不会在这里了,你再好好消化一下吧。你除了把楼主的问题再抛一遍,能解决什么问题?无知。
johnkiller
2023-01-03 00:26:53 +08:00
@shakukansp #45 ,因为在 watch 调用前 a.value 就访问了 getter ,仅仅传入了一个数字,watch 没法正常收集依赖啊。是不是又回到了这个问题,放到函数内不就可以了?
shakukansp
2023-01-03 00:29:16 +08:00
@shakukansp 接 45 楼,这才是为什么 setup 要返回一个函数才能让里面的 count.value 能被触发 getter

watchEffect 也是传了函数才能收集到依赖
shakukansp
2023-01-03 00:35:45 +08:00
@johnkiller 我就是在和楼主讲这个问题,你再看看主楼代码,我回楼主的时候他还没回后面的代码呢。

仅仅传入一个数字,也是我说的值传递,这也是 vue 为什么要用 ref 包装一下基础类型的原因
和 setup 要返回一个函数和 options api 里面 data 要返回一个函数是一样的原因

你只说解决方法而不说下为什么像主楼这么写,改 getOne.value 没法触发视图更新吗
shakukansp
2023-01-03 00:37:22 +08:00
我 21 楼也写的很清楚了,什么情况下 vue 会有什么表现我特么都写出来了

怎么就没想解决楼主问题了,嗯?
johnkiller
2023-01-03 00:39:59 +08:00
@shakukansp 最后还是回到了最初 #10 #11 所说的依赖问题,毫无意义的交流。

vue 内部完全可以通过类似 watchEffect(() => { instance.setup() }) 直接收集到 setup 作为依赖,和你所说的“返回函数”逻辑毫无关联,而是 #42 。

早点睡吧,减少无意义的倔强。
我一直同意你的 js 逻辑,但没说清楚 Vue ,你到底急在哪呢?
johnkiller
2023-01-03 00:41:20 +08:00
@shakukansp “你只说解决方法而不说下为什么像主楼这么写”

我都说了多少遍,是让 ref 正常收集依赖。你上下文丢失这么快吗?
johnkiller
2023-01-03 00:43:00 +08:00
明天楼主上线估计都 tm 要傻眼了,就跟你在这无意义交流。
shakukansp
2023-01-03 00:51:19 +08:00
@johnkiller 当然急啊,怕你误导楼主,为什么主楼这代码会有这种问题我还是得告诉楼主啊,你再看看我 21 楼回了什么

“原段代码就算把 someprops 改成 reactive ,依然无法通过修改 getOne.value 的值来触发视图更新,就算 getOne.value 里面的值是个对象也一样,具体会表现为修改 getOne.value 中对象的子属性可以触发更新,但是给 getOne.value 赋值一个不同引用的对象就会没法更新视图。”

此处原代码指主楼代码

重点在这里 “就算 getOne.value 里面的值是个对象也一样,具体会表现为修改 getOne.value 中对象的子属性可以触发更新,但是给 getOne.value 赋值一个不同引用的对象就会没法更新视图”

我就说死了,这就是引用链断了,引用问题引用问题引用问题,vue 虽然收集了依赖,但是 someprops 中的 one 已经和 getOne.value 引用的是不同的对象了
shakukansp
2023-01-03 01:02:26 +08:00
22 楼结论必没有错

我也没倔强什么,因为这就是预期内行为,就算不懂 vue 响应式原理也能通过 js 基础特性得出会丢失响应式的结论
johnkiller
2023-01-03 01:09:18 +08:00
@shakukansp 你上面这些基础不用一直重复,我家的猫学两天 js 都能明白,我也说了一直同意你的 js 逻辑。只是你的回复并没有说到 vue 点子上,也没有解决任何问题。

我给出了最简单的答案,以及为什么。
重复一遍,没有否认你的 js ,不用急,就这么简单。
shakukansp
2023-01-03 01:18:17 +08:00
@johnkiller 哦,你 35 楼说我暴露水平什么意思,讲的有问题吗,我看你是后面反应过来才改口

你家猫学两天能明白你还要这么多楼才能反应过来,讲话恶心人谁不会啊
shakukansp
2023-01-03 01:20:46 +08:00
抽象层面,get 就是对一个变量取值的行为,你说况且它也没有 getter ,你确实暴露水平
johnkiller
2023-01-03 01:52:33 +08:00
@shakukansp
第一,35 确实暴露了你的水平,没有问题。
第二,你我都明白,我们聊天上下文所指的 getter 是指 vue 赋予响应式变量的一个触发回调,普通对象没有被 vue 代理,所以没有。

只能说拿着放大镜扣几个字眼,是你最后的倔强🤣
shakukansp
2023-01-03 01:56:55 +08:00
@johnkiller 呵呵,你的解决方法楼主遇到我说的情况咋办,不是又要迷惑一次

单就这一点你已经跪了

我楼里讲的话可没有一点犹豫

你还要搬出诸如给什么项目提过什么 pr ,属实不行

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/905838

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX