英文:
How can I trigger effect on sibling component in vue3 in an idiomatic way?
问题
我有2个组件Sibling1
和Sibling2
,它们并排放置。我想在Sibling1
上按下按钮,触发Sibling2
上的效果。
- 这个逻辑只存在于父组件内部,所以不需要将其设置为全局
- 将此效果从组件中取出并放置在父组件上并不容易
我考虑的一种方法如下:
// App.vue(父组件)
const trigger = ref(null)
function setTrigger() {
trigger.value = Symbol('new trigger')
}
</script>
<template>
<SiblingOne @on-click="setTrigger" />
<SiblingTwo :trigger="trigger" />
</template>
// Sibling1.vue
<script setup>
const emit = defineEmits(['on-click'])
</script>
<template>
<button @click="emit('on-click')">update</button>
</template>
// Sibling2.vue
<script setup>
import { watch } from 'vue'
const props = defineProps({ trigger: null })
watch(
() => props.trigger,
() => console.log(new Date())
)
</script>
<template>Nothing to see here, check console</template>
我曾经看到过上面的模式,但也许有更好的替代方法。在Vue 3中,有什么好的方法可以做到这一点呢?
英文:
I have 2 components Sibling1
and Sibling2
that are placed side by side. I want to press a button on Sibling1
and trigger an effect on Sibling2
.
- This logic lives only inside the parent component, so no need to make it global
- It's not easy to take out this effect outside of the component and put it for instance on the parent
One way I thought of doing it is like this:
// App.vue (parent)
const trigger = ref(null)
function setTrigger() {
trigger.value = Symbol('new trigger')
}
</script>
<template>
<SiblingOne @on-click="setTrigger" />
<SiblingTwo :trigger="trigger" />
</template>
// Sibling1.vue
<script setup>
const emit = defineEmits(['on-click'])
</script>
<template>
<button @click="emit('on-click')">update</button>
</template>
// Sibling2.vue
<script setup>
import { watch } from 'vue'
const props = defineProps({ trigger: null })
watch(
() => props.trigger,
() => console.log(new Date())
)
</script>
<template>Nothing to see here, check console</template>
I've seen the pattern above some times but maybe there are better alternatives. What would be a good way of doing this in vue3?
答案1
得分: 1
希望我推荐使用一个包是可以的。
我使用tiny-emitter来实现这个目的。它非常轻量级,并且正好可以满足你的需求。
只需记住也要关闭发射监听器。
英文:
I hope it's okay that I recommend a package to use.
I use tiny-emitter for this purpose. It's lightweight and does exactly what you need it to do.
Just remember to turn the emit listener off as well.
答案2
得分: 1
以下是翻译好的部分:
"trigger" 变量的必要性表明这是回调函数的情况。Sibling2
应该公开它,Sibling1
应该调用它:
App.vue
<script setup>
const siblingTwo = ref(null);
</script>
<template>
<SiblingOne @click="siblingTwo?.trigger" />
<!-- 或者 -->
<SiblingOne @click="siblingTwo.trigger()" />
<SiblingTwo ref="siblingTwo" />
</template>
Sibling2.vue
<script setup>
import { defineExpose } from 'vue'
defineExpose({
trigger() {
console.log(new Date())
}
})
</script>
英文:
The necessity for trigger variable suggests this is the case for a callback. Sibling2
is supposed to expose it, Sibling1
is supposed to call it:
App.vue
<script setup>
const siblingTwo = ref(null);
</script>
<template>
<SiblingOne @click="siblingTwo?.trigger" />
<!-- or -->
<SiblingOne @click="siblingTwo.trigger()" />
<SiblingTwo ref="siblingTwo" />
</template>
Sibling2.vue
<script setup>
import { defineExpose } from 'vue'
defineExpose({
trigger() {
console.log(new Date())
}
})
</script>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论