英文:
How can I trigger effect on sibling component in vue3 in an idiomatic way?
问题
我有两个组件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来实现这个目的。它非常轻量级,并且能够完全满足你的需求。
只需记得也要关闭emit监听器。
英文:
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
触发变量的必要性表明这是一个回调的情况。Sibling2
应该暴露它,Sibling1
应该调用它:
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>
英文:
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>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论