为什么不反应 属性 在我的模板中是反应性的?

Why not reactive property are reactive in my template?

我目前正在使用 Vue.js 中引入的新反应性 API 3. 我已按照 documentation 上的说明进行操作,并且根据我在使用 [= 设置变量时的理解13=] 我把它变成一个反应值。如果我不使用 ref 变量不是反应性的,并且在我更新它时不应在模板中更新它。

我对我的测试结果感到惊讶:

<script src="https://unpkg.com/vue@next"></script>
<div id="app">
  <my-component></my-component>
</div>
<script>
  const app = Vue.createApp({});
  app.component("my-component", {
    template: `
      <div>
        <ul>
          <li>Data not reactive : {{ countNotReactive }}</li>
          <li>Data reactive : {{ countReactive }}</li>
        </ul>
        <button @click="inc">+1</button>
      </div>
    `,
    setup() {
      const countNotReactive = 1;
      const countReactive = Vue.ref(1);

      return {
        countNotReactive,
        countReactive
      };
    },
    methods: {
      inc() {
        this.countNotReactive++;
        this.countReactive++;
      }
    }
  });
  app.mount("#app");
</script>

当我点击 +1 按钮时,我模板中的所有计数器都会递增。这是渲染图:

<!-- Initial -->
<div>
  <ul>
    <li>Data not reactive : 1</li>
    <li>Data reactive : 1</li>
  </ul>
  <button>+1</button>
</div>

<!-- After click on +1 -->
<div>
  <ul>
    <li>Data not reactive : 2</li>
    <li>Data reactive : 2</li>
  </ul>
  <button>+1</button>
</div>

我的期望是只看到要增加的反应计数器。谁能给我解释一下为什么不是这样?

我不明白为什么我应该在这种情况下使用 ref。有没有人能给我一个例子,我可以看到 ref 和非 ref 变量之间的区别?

您可以在同一个组件中同时使用组合和选项 api,但您不应在两者之间共享方法和属性 API,您的逻辑应该类似于:

const {
  createApp
} = Vue;
const App = {


}
const app = createApp(App)
app.component("my-component", {
  template: `
      <div>
        <ul>
          <li>Data not reactive : {{ countNotReactive }}</li>
          <li>Data reactive : {{ countReactive }}</li>
         
        </ul>
        <button @click="inc">+1</button>
     
      </div>
    `,
  setup() {
    const countNotReactive = 1;
    const countReactive = Vue.ref(1);

    function inc() {
      countNotReactive++;
      countReactive.value++;
    }
    return {
      inc,
      countNotReactive,
      countReactive
    };
  },

});
app.mount('#app')
<script src="https://unpkg.com/vue@3.0.0-rc.11/dist/vue.global.prod.js"></script>

<div id="app">
  Vue 3 app

  <my-component></my-component>
</div>

实际上 countNotReactive 并没有改变,如手表挂钩所示:

const {
  createApp
} = Vue;
const App = {


}
const app = createApp(App)
app.component("my-component", {
  template: `
      <div>
        <ul>
          <li>Data not reactive : {{ countNotReactive }}</li>
          <li>Data reactive : {{ countReactive }}</li>
         
        </ul>
        <button @click="inc">+1</button>
     
      </div>
    `,
  setup() {
    const countNotReactive = 1;
    const countReactive = Vue.ref(1);

  Vue.watch(countReactive,()=>{
  console.log("countReactive",countReactive.value)
   console.log("countNotReactive",countNotReactive)
  
   })
  
    return {
    
      countNotReactive,
      countReactive
    };
  },
  methods: {
      inc() {
        this.countNotReactive++;
        this.countReactive++;
      }
    }
});
app.mount('#app')
<script src="https://unpkg.com/vue@3.0.0-rc.11/dist/vue.global.prod.js"></script>

<div id="app">
  Vue 3 app

  <my-component></my-component>
</div>

您获得的行为由以下代码解释:

const myConst="I'm a constant"
console.log(myConst)
let obj={myConst} //adding myConst as property in obj which in our case is the `this` (vue instance)

console.log(obj.myConst)
obj.myConst="updated value"

console.log(obj.myConst)//this prints the updated value

//but if we try myConst="new value" this raises an error

console.log(myConst)//still the same as we declared

//conclusion : this.myConst is not the same as myConst

您正在混合使用选项 API 和组合 API。使用 Option API 的 method 对象,以及您内部的 inc 方法创建两个变量

this.countNotReactive
this.countReactive

这些变量在您的模板中获取,并覆盖从您的组合 API 的设置方法返回的变量。

只是不要将两者混用并像这样尝试:

<script src="https://unpkg.com/vue@next"></script>
<div id="app">
  <my-component></my-component>
</div>
<script>
  const app = Vue.createApp({});
  app.component("my-component", {
    template: `
      <div>
        <ul>
          <li>Data not reactive : {{ countNotReactive }}</li>
          <li>Data reactive : {{ countReactive }}</li>
        </ul>
        <button @click="inc">+1</button>
      </div>
    `,
    setup() {
      const countNotReactive = 1;
      const countReactive = Vue.ref(1);
      
      const inc = () => {
        countNotReactive++;
        countReactive.value++;
      }

      return {
        inc,
        countNotReactive,
        countReactive
      };
    },
  });
  app.mount("#app");
</script>

这就是不同之处。 refs 值保存在其 value 属性 中,而可以直接访问普通的非反应性变量。看这里:https://v3.vuejs.org/api/refs-api.html#ref