Наблюдайте за дочерними свойствами родительского компонента в vue 3

Мне интересно, как я могу наблюдать дочерние свойства из родительского компонента в Vue 3, используя api композиции (я работаю с экспериментальным настройка скрипта).

<template>//Child.vue
  <button 
    @click="count++" 
    v-text="'count: ' + count" 
  />
</template>

<script setup>
import { ref } from 'vue'

let count = ref(1)
</script>
<template>//Parent.vue
  <p>parent: {{ count }}</p> //update me with a watcher
  <Child ref="childComponent" />
</template>


<script setup>
import Child from './Child.vue'
import { onMounted, ref, watch } from 'vue'

const childComponent = ref(null)
let count = ref(0)

onMounted(() => {
  watch(childComponent.count.value, (newVal, oldVal) => {
    console.log(newVal, oldVal);
    count.value = newVal
  })
}) 
</script>

Я хочу понять, как я могу отслеживать изменения в дочернем компоненте из родительского компонента. Мое неработающее решение основано на решении Vue.js 2. здесь. Поэтому я не хочу выдавать count.value, а просто наблюдаю за изменениями.

Спасибо!


person wittgenstein    schedule 21.02.2021    source источник
comment
Почему вы не хотите выпускать событие?   -  person Dan    schedule 21.02.2021
comment
Потому что я хочу понять, как отслеживать измененные данные по компонентам. Подсчет - это только пример. Это не экзотический случай, но, к сожалению, я никуда не денусь, поэтому и спрашиваю.   -  person wittgenstein    schedule 21.02.2021


Ответы (1)


Привязки внутри <script setup> по умолчанию закрыты, как вы можете видеть здесь.

Однако вы можете явно предоставить определенные ссылки. Для этого вы используете useContext().expose({ ref1,ref2,ref3 })

Так что просто добавьте это в Child.vue:

import { useContext } from 'vue'
useContext().expose({ count })

а затем измените Watcher в Parent.vue на:

watch(() => childComponent.value.count, (newVal, oldVal) => {
    console.log(newVal, oldVal);
    count.value = newVal
  })

И это работает!

person Tom    schedule 21.02.2021
comment
Оба ваших предложения не действуют. childComponent.value.count не определено. Я знаю, что это решается через emit и props. Как я уже сказал, мне интересен пример. - person wittgenstein; 21.02.2021
comment
Вы изменили свой Код в Child.vue? с <script setup> import { ref } from 'vue' let count = ref(1) </script> на <script> import { ref } from 'vue'; export default { setup(){ const count = ref(1) return { count } } } </script>? Меня устраивает. - person Tom; 21.02.2021
comment
Привет, Том, извини. Я хочу работать с методом script setup. Я могу попробовать с ним, если хочешь. Возможно, это поможет мне применить основы к экспериментальной версии. - person wittgenstein; 21.02.2021
comment
Похоже, что то, что вы пытаетесь сделать, еще невозможно с помощью метода script setup. Взгляните на эту тему (по умолчанию закрыта) в RFC github.com/vuejs/rfcs/blob/script-setup-2/active-rfcs/. Предполагается, что привязки не отображаются в родительском компоненте. Примечание. Как явно предоставить императивный общедоступный интерфейс будет окончательно определено в github.com/vuejs/rfcs/pull / 210. - person Tom; 21.02.2021
comment
Я отредактировал свой ответ, уже есть способ выставить ссылки с синтаксисом <script setup>! - person Tom; 22.02.2021
comment
Отлично работает, спасибо. Надеюсь, вы тоже воспользуетесь настройкой скрипта (когда он, наконец, будет одобрен) - person wittgenstein; 22.02.2021