const app = Vue.createApp({
setup() {
const state = Vue.reactive({
postPerPage: 10,
currentPage: 1,
});
const posts = Vue.ref([]);
const normalRef = Vue.ref(0)
const watchCounter = Vue.ref(0)
Vue.watch([
//() => posts.value, // <-- this will not trigger watch callback on array push (only on array replace). Can be fixed by deep watch (uncomment last argument of watch)
//posts, // <-- same result as above
() => [ ...posts.value],
// () => state, // similar to array, this does not trigger on property change
() => ({ ...state }),
normalRef
],
(newValues, prevValues) => {
watchCounter.value++
console.log(`prev (${watchCounter.value}):`, prevValues);
console.log(`new (${watchCounter.value}):`, newValues);
},
// { deep: true }
)
return {
state,
posts,
normalRef,
watchCounter
}
},
mounted() {
const interval = 1000
setTimeout( () => this.state.currentPage = 2, interval)
setTimeout( () => this.posts.push({ a: 1 }), interval*2)
setTimeout( () => this.normalRef = 10, interval*3)
}
})
app.mount("#app")
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.11/vue.global.js" integrity="sha512-1gHWIGJfX0pBsPJHfyoAV4NiZ0wjjE1regXVSwglTejjna0/x/XG8tg+i3ZAsDtuci24LLxW8azhp1+VYE5daw==" crossorigin="anonymous"></script>
<div id="app">
<div>Watch counter {{ watchCounter }}</div>
<div>{{ state }}</div>
<div>{{ posts }}</div>
<div>{{ normalRef }}</div>
</div>