javascript - Vue 3 - Watching prop stops working after emitting to parent - Stack Overflow

I have an issue trying to watch a prop in a child ponent. Here's a playground link with a a little

I have an issue trying to watch a prop in a child ponent. Here's a playground link with a a little code to reproduce the issue:

Vue SFC Playground

The child ponent (in orange) inherits the data from the parent (just an array). The child ponent copies the data from the parent whenever it changes, and you can then modify (append) to the child data, and when you click save, the data should be emitted into the parent (and is then subsequently passed into the child as a prop).

The problem is, as soon as you click save in the child ponent, the child is no longer able to watch for changes to the prop. It never sees the future changes from the parent. Vue devtools correctly sees the data though. What am i missing here?

I have an issue trying to watch a prop in a child ponent. Here's a playground link with a a little code to reproduce the issue:

Vue SFC Playground

The child ponent (in orange) inherits the data from the parent (just an array). The child ponent copies the data from the parent whenever it changes, and you can then modify (append) to the child data, and when you click save, the data should be emitted into the parent (and is then subsequently passed into the child as a prop).

The problem is, as soon as you click save in the child ponent, the child is no longer able to watch for changes to the prop. It never sees the future changes from the parent. Vue devtools correctly sees the data though. What am i missing here?

Share Improve this question edited Jan 11, 2023 at 12:10 Tolbxela 5,2113 gold badges22 silver badges50 bronze badges asked Jan 11, 2023 at 11:32 qwertyqwerty 5,26617 gold badges59 silver badges79 bronze badges
Add a ment  | 

5 Answers 5

Reset to default 5

The watch posable accepts either a 'ref', 'reactive' object, or a getter function.

But as stated in the documentation, it doesn't accept inner property of a reactive object:

Do note that you can't watch a property of a reactive object like this:

const obj = reactive({ count: 0 })
// this won't work because we are passing a number to watch()
watch(obj.count, (count) => {
 console.log(`count is: ${count}`)
})

So to listen to props.list changes, you need to use a getter function:

watch(() => props.list, () => {
  // ...
})

See this working playground

Try to set your watcher like:

  watch(
    () => props.list,
      (newValue, oldValue) => {
        console.log('updated!');
        internalCopy.value = JSON.parse(JSON.stringify(props.list));
     }, {
    immediate: true,
   deep: true,
 }

Issue is not in a puted property, Issue is in your onAdd method. As this is an array, It should be update by reference not a value.

  const onAdd = (val) => {
    // data.value.list = val; ❌ 
    val.forEach((d, index) => {
      data.value.list[index] = d ✅
    })
  }

Working Vue SFC Playground

It is also working well with deep watch on props object, like so:

watch(props, () => {
  console.log('updated!');
  internalCopy.value = props.list;
}, {
  immediate: true,
  deep: true,
})

Since the ref (reference) to the props object keeps unchanged.

This is a very interesting question to deeply understand the Vue reactivity. That's why I wanted to clarify it pletely .

The previous answers are correct, but they don't explain the problem fully enough for me.

Since the props.list is a ref (reference) to the the array, when you define your watcher with it, then the watcher is bound to this ref (a Proxy object) and it will stay bounded to this ref even if you replace the props.list with a new ref to an new array. This is what you do with your add event.

To check it I have added the refBackup with the original ref to see it the watcher still updates, it we update the original list array through refBackup. Like this:

const refBackup = ref(props.list);

const addToBack = () => {
  refBackup.value.push('addToBack');
}

Notice that updating the refBackup triggers the watcher(), even after the save was clicked and the props.list points now to another ref with a new Array.

Here is the link to my playground

In case when you define your watcher() with the function () => props.list, this function always returns the actual ref to the last updated array. The watcher is bound to the function and not to the ref of props.list array.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744222877a4563868.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信