【问题标题】:How to watch ref and reactive object with a single watcher in Vue3如何在 Vue3 中使用单个观察者观察 ref 和反应对象
【发布时间】:2021-07-08 08:40:58
【问题描述】:

Vue v3 docs 展示了一个使用单个观察者通过将数组作为参数传递来观察多个引用的示例

我可以(以及如何)使用类似的方法通过单个观察者同时观察 refreactive 对象吗?

const state = reactive({
  postPerPage: 10,
  currentPage: 1,
});

const posts = ref([]);

const currentPosts = ref([]);

watch(
  () => posts.value, // store value in currentPosts when the posts.value is updated (get data from api)
  () => {
    currentPosts.value = getCurrentPost(); 
  }
)

watch(
 () => {
  return { ...state };
 }
 () => {
  currentPosts.value = getCurrentPost();
 }
)

【问题讨论】:

    标签: vue.js watch vuejs3


    【解决方案1】:

    docs 中的示例不是很清楚,但是当您将数组作为第一个参数传递(以查看多个源)时,该数组可以包含函数和裸引用的混合。请参见下面的示例。

    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>

    其他方法当然是继续使用两个观察者并将回调功能重构为单独的函数......

    const callback = () => {
      currentPosts.value = getCurrentPost();
    }
    
    watch(() => ({ ...state }), callback)
    

    【讨论】:

    • 感谢您的信息。它帮助我更好地了解 VueJs。
    猜你喜欢
    • 2011-06-17
    • 1970-01-01
    • 1970-01-01
    • 2021-04-13
    • 2017-05-23
    • 2018-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多