【问题标题】:Vue.js 3.0 - Two-Way Data Binding with Composition APIVue.js 3.0 - 使用组合 API 的双向数据绑定
【发布时间】:2020-12-27 23:10:26
【问题描述】:

我正在使用 Vue.js 3.0 编写一个 Vue.js 应用程序。我使用它作为学习组合 API 的一种方式。我喜欢 Vue.js 2.0 的一个特性是双向数据绑定的易用性。但是,对于 Composition API,我不清楚如何使用它。尤其是在使用全局状态时。例如,我的应用程序有两个组件,如this Fiddle 所示。代码如下所示:

HTML

<div id="my-vue" class="demo">
  <banner :class="{ 'even-banner': isEven, 'odd-banner': !isEven }"></banner>
  <hr />
  <content :class="{ 'even-content': isEven, 'odd-content': !isEven }"></content>
  <pre>value={{value}} isEven={{isEven}}</pre>
</div>

JavaScript

const store = {
  state: Vue.reactive({
    result: null
  }),
  generateNewValue() {
    this.state.result = Math.floor(Math.random() * 10);
  }
};

const MyApp = {
  setup() {
    const isEven = Vue.computed(() => store.state.result % 2 === 0)
    const value = Vue.toRef(store.state, 'result')
    return {
      isEven,
      value
    }
  }
}
const myApp = Vue.createApp(MyApp)

myApp.component("banner", 
  { 
    template: '<button @click="onGenerateClick">generate</button>',
    setup(props) {
      console.log('setting up...');
    },
    methods: {
      onGenerateClick() {
        store.generateNewValue();
      }
    }
  }
);

myApp.component("content", {
  template: '<div style="padding:2rem;">' +
    '<div>Enter Value: <input type="text" v-model="result" /></div>' +
    '<br /><div>or</div><br />' +
    '<div><button @click="onGenerateClick">generate</button></div>' +
    '</div>',
  methods: {
    onGenerateClick() {
      store.generateNewValue();
    }
  }  
});

myApp.mount('#my-vue')

CSS

.even-banner {
  background-color:navy;
  color: #fff;
}

.even-content {
  background-color:blue;
  color: #fff;
}

.odd-banner {
  background-color:maroon;
  color:#fff;
}

.odd-content {
  background-color:red;
  color:#fff;
} 

这个想法很简单:如果一个数字是偶数,则使用蓝色背景。如果数字是奇数,请使用红色背景。我有一个按需要工作的生成按钮。但是,这个小应用程序有一个文本字段,您可以在其中手动输入一个值。该值当前根据需要更改背景。这就像双向绑定不起作用。

在使用 Composition API 的 Vue.js 应用中,如何让双向数据绑定与全局状态一起工作?

【问题讨论】:

    标签: javascript vue.js


    【解决方案1】:

    您的文本输入没有绑定到存储值,它只是引用了一个不存在的名为 result 的数据属性。 尝试将 store 注入到组件中,然后将 getter/setter 添加到绑定属性

    myApp.component("content", {
    store,
      template: '<div style="padding:2rem;">' +
        '<div>Enter Value: <input type="text" v-model="myAmount" /></div>' +
        '<br /><div>or</div><br />' +
        '<div><button @click="onGenerateClick">generate</button></div>' +
        '</div>',
        computed:{
            myAmount:{
          get: function(){return store.state.result},
          set: function(val){store.state.result = val}
          }
        },
      methods: {
        onGenerateClick() {
          store.generateNewValue();
        }
      }  
    });
    

    顺便说一句,我的 setter 是一个快速的 hack,你通常不会直接更新 store.state 属性,但它应该让你开始

    【讨论】:

    • 谢谢。不过,您的回答证实了我的假设。一旦你引入一个全局状态,双向绑定就消失了。相反,您总是必须编写一些中间代码。推荐的“正常”方法是在 store 本身中使用一些 setter 方法。
    猜你喜欢
    • 1970-01-01
    • 2018-02-13
    • 1970-01-01
    • 1970-01-01
    • 2018-05-01
    • 2011-05-17
    • 2017-07-03
    • 2023-03-14
    • 1970-01-01
    相关资源
    最近更新 更多