[Vuejs]-Can I watch() the elements within a v-for separately?

0👍

this is a very common problem, the core team is solving in front of you can only use my way:

// </script><script type="module">
import { ref, watch } from "https://esm.run/vue@3"

const pills = ref([0])

function onChangeItem(i, newVal, oldVal) {
  console.log("index %i changed value %s -> %s", i, oldVal, newVal)
}

const watchers = new Map()
watch(() => pills.value.length, (newLength, $oldLength, onCleanup) => {
  const oldLength = $oldLength ?? 0
  if (newLength > oldLength) {
    for (let i = oldLength; i < newLength; i++) {
      watchers.set(i, watch(() => pills.value[i], (n, o) => {
        onChangeItem(i, n, o)
      }, { immediate: $oldLength !== undefined }))
    }
    return
  }
  if (newLength < oldLength) {
    for (let i = newLength; i < oldLength; i++) {
      watchers.get(i)?.()
      watchers.delete(i)
    }
  }
}, { immediate: true })

async function main() {
pills.value[0] += 10

await Promise.resolve()
pills.value.push(20)

await Promise.resolve()
pills.value.pop()
pills.value.pop()
}

main()

Note: that this is an unoptimized version of the cleanup you have to add onBeforeUnmount(() => watchers.forEach(item => item())) or something to cancel if the Effect listener end of life

-3👍

eg 1

<template>
    <div></div>
</template>
<script>
    export default {
        data(){
            obj:{
                a:''
            },
        },
        watch:{
            /
            'obj.a'(item1,item2){
                
            },
            deep:true
        }
    }
</script>

eg 2

<template>
    <div></div>
</template>
<script>
    export default {
        data(){
            newArr:[
                {
                    list:[
                        {
                            label:null
                        }
                    ]
                }
            ]
        },
        methods:{
            show(){
                this.newArr[0].list[0].label = "2020年11月10日10:36:58";
            }
        },
        watch:{
            newArr:{
                handler(val){
                    // ...
                },
                deep:true
            },
        }
    }
</script>



Leave a comment