【问题标题】:Vue.js - Composition API - Toggle ButtonVue.js - 组合 API - 切换按钮
【发布时间】:2021-01-01 05:19:17
【问题描述】:

我正在开发一个 Vue.js 应用程序。我决心了解 Composition API。但是,语法让我有点失望。我觉得我在闭包内部创建了闭包,这让我相信我做错了。我正在尝试设置在我的组件加载时是否启用/禁用按钮。为了演示,我创建了这个fiddle,其中包括以下内容:

示例

myApp.component("banner", 
  { 
    template: '<button :disabled="isDisabled">generate</button>',
    setup(props) {
      let isDisabled = true;
      function initializeButton() {
        fetch('<some-url>')
          .then(res => { isDisabled = !res.ok; } )
        ;
      }
      initializeButton();
      
      return {
        isDisabled
      };
    }
  }
);

但是,这不起作用。我已将其范围缩小到isDisabled 在承诺的then 部分中不可“访问”这一事实。但是,我不确定如何在then 中实际设置isDisabled。另外,我喜欢initializeButton 放在setup 方法之外,即便如此,我也做不到。我感谢任何可以帮助我的人。

谢谢。

【问题讨论】:

  • 使用箭头函数捕获当前上下文。 const initializeButton = () =&gt; { ... }
  • @PierreSaid 感谢您的回复。然而,这并没有奏效。使用箭头函数,thisundefined。如果我在回调中执行console.log(this);,我会看到undefinedconsole.log(isDisabled); 根据需要打印 true。但是,即使我手动输入isDisabled = false; in 回调,按钮状态也不会改变。值得注意的是,如果我在fetch 调用之外手动将isDisabled 设置为false,则该按钮将根据需要启用。因此,我知道 a) 我的模板中的数据绑定是正确的。 b) 我没有在fetch 中正确设置它。我错过了什么?

标签: javascript vue.js


【解决方案1】:

要使用异步设置方法,您需要使用suspense

@vue-composition / How can I use asynchronous methods in setup()

例子:

Vue.productionTip = false;

const Todo = {
  async setup(props) {
    const todo = await fetch('https://jsonplaceholder.typicode.com/todos/1')
      .then(r => r.json());
    return {
      todo
    }
  },
  template: `
    <div>
      Todo : {{ todo.title }}
    </div>
  `
};

const vm = Vue.createApp({
  components: {
    Todo
  }
}).mount('#app')
<script src="https://unpkg.com/vue@next"></script>
<div id="app">
  <Suspense>
    <template #default>
      <Todo />
    </template>
    <template #fallback>
      <div>Loading...</div>
    </template>
  </Suspense>
</div>

另外isDisabled 也没有反应。你需要使用ref 来使这个变量反应。

与 ref 反应的基本示例:

Vue.productionTip = false;

const vm = Vue.createApp({
  setup(props) {
    const count = Vue.ref(0);
    const inc = () => {
      count.value += 1;
    }
    return {
      count,
      inc
    }
  }
}).mount('#app')
<script src="https://unpkg.com/vue@next"></script>
<div id="app">
  Count : {{ count }}
  <button @click="inc">+1</button>
</div>

【讨论】:

    【解决方案2】:

    由于initializeButton 是一个异步操作,您应该使用await 语法(https://javascript.info/async-await

    async setup() {
      function async initializeButton() {
        return fetch('<some-url>').then(res => { isDisabled = !res.ok; } );
      }
      await initializeButton();
    }
    
    

    【讨论】:

      猜你喜欢
      • 2023-04-02
      • 2019-02-17
      • 2018-03-30
      • 1970-01-01
      • 1970-01-01
      • 2014-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多