首页 > 解决方案 > Vue 状态未使用默认注入值更新

问题描述

如果单击该按钮,您可以state在控制台中看到 updated 的值,但在页面输出中没有更新。如何使其与默认注入值一起使用?

const Component = {
  inject: {
    state: {
      default: () => ({
        example: 1
      })
    }
  },
  template: `<div>
    <div>{{ state }}</div>
    <button @click="click">click</button>
  </div>`,
  methods: {
    click() {
      this.state.example += 1
      console.log(this.state)
    }
  }
}

new Vue({
  el: "#app",
  components: {
    Component
  },
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <component></component>
</div>

它是否与 Vue 文档所说的“注意:提供和注入绑定不是反应性的。这是故意的。但是,如果您传递一个观察到的对象,该对象上的属性确实保持反应性。”?我对 BINDINGS 不是反应性但 OBSERVED OBJECT 反应性之间的区别感到困惑。你能举一个例子来演示差异吗?

标签: javascriptvue.jsvuejs2vue-component

解决方案


对不起,但不清楚你想要什么 - “注射”的提供者在哪里?为什么在使用值本身的同一组件中使用注入?

这是你的代码,没有注入

1.使用数据属性

const Component = {
  data() {
    return {
      state: {
        example: 1
      }
    }
  },
  template: `<div>
    <div>{{ state }}</div>
    <button @click="click">click</button>
  </div>`,
  methods: {
    click() {
      this.state.example += 1
      console.log(this.state)
    }
  }
}

new Vue({
  el: "#app",
  components: {
    Component
  },
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <component></component>
</div>

只需使用data属性 - 您可以为example.

2.使用注入离子

注入是完全不同的东西——它是一种将值从提供者传递给消费者的方法:

const Component = {
  inject: ['state1'],
  data() {
    return {
      state: {
        example: 1
      }
    }
  },
  template: `<div>
    <div>injected: {{ state1 }}</div>
    <div>{{ state }}</div>
    <button @click="click">click</button>
  </div>`,
  methods: {
    click() {
      this.state.example += 1
      console.log(this.state)
    }
  }
}

new Vue({
  el: "#app",
  provide: {
    state1: {
      example1: 1
    }
  },
  components: {
    Component
  },
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <component></component>
</div>

您可以“跳过”组件级别并在注入它的组件中使用提供的值 - 您不必一直将其作为props向下传递。

3. 创建反应性感染

如果你想要反应式注入,那么你需要传递一些更复杂的东西:

const Component1 = {
  inject: ['state2'],
  data() {
    return {
      state: {
        example: 1
      }
    }
  },
  template: `<div>
    <div>injected: {{ state2.state2P }}</div>
    <div>{{ state }}</div>
    <button @click="click">click</button>
  </div>`,
  methods: {
    click() {
      this.state.example += 1
      console.log(this.state)
    }
  }
}

new Vue({
  el: "#app",
  data() {
    return {
      state2: {
        example2: 1
      }
    }
  },
  provide() {
    // create an object (state2)
    const state2 = {}
    // define a property on the object (state2P), that
    // has a get() function that always gets the provider's
    // value you want to inject
    Object.defineProperty(state2, 'state2P', {
      enumerable: true,
      get: () => this.state2,
    })
    // return the created object (with a property that always
    // gets the value in the parent)
    return {
      state2
    }
  },
  components: {
    Component1
  },
  methods: {
    parentClick() {
      this.state2.example2 += 1
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <component1></component1>
  <button @click="parentClick">PARENT CLICK</button>
</div>

我在模板中添加了一个按钮,因此您可以看到method提供者组件范围中定义的 a 更改了消费者组件范围中显示的值。(还必须更改组件的名称,因为 Vue 开始“抱怨”使用受限词。)


推荐阅读