【问题标题】:vuejs - bind to component datavuejs - 绑定到组件数据
【发布时间】:2018-10-09 10:06:54
【问题描述】:

我创建了一个简单的组件:
https://jsfiddle.net/s08yhcda/1/

<div id="app">
  <button-counter>My counter: <span v-text="count"></span></button-counter>
</div>

// Define a new component called button-counter
Vue.component('button-counter', {
  data: function () {
    return {
      count: 0
    }
  },
  template: '<button v-on:click="count++"><slot></slot></button>'
})

// boot up the demo
var demo = new Vue({
  el: '#app'
})

但我无法绑定到内部组件数据(计数器)。组件如何将其数据暴露给&lt;slot&gt; 范围?我知道“事件向上,道具向下”的想法。但我仍然认为可以在其范围内(&lt;button-counter&gt; 元素内)绑定组件数据

我不喜欢将事件用于这么简单的事情。还有什么办法吗?

【问题讨论】:

  • 您尝试访问计数器变量的位置不在按钮计数器内,而是在#app

标签: javascript data-binding vue.js components


【解决方案1】:

有多种方法可以解决这个问题:

使用事件

这通常是最好的方法,正如其他 Vue 开发人员所期望的那样

// Define a new component called button-counter
Vue.component('button-counter', {
    data: function () {
        return {
            count: 0
        }
    },
    methods: {
        click() {
            this.count++;
            this.$emit('input', this.count);
        },
    },
    template: '<button v-on:click="click"><slot></slot></button>'
})

// boot up the demo
var demo = new Vue({
    data() {
        return {
            count: 0,
        };
    },
    el: '#app'
});
<!-- development version, includes helpful console warnings -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<div id="app">
  <button-counter @input="count = $event">My counter: <span v-text="count"></span></button-counter>
</div>

使用参考:

// Define a new component called button-counter
Vue.component('button-counter', {
    data: function () {
        return {
            count: 0
        }
    },
    methods: {
        click() {
            this.count++;
        },
    },
    template: '<button v-on:click="click"><slot></slot></button>'
})

// boot up the demo
var demo = new Vue({
    data() {
        return {
            mounted: false,
        };
    },
    mounted() {
        this.mounted = true;
    },
    computed: {
        count() {
            return this.mounted ? this.$refs.counter.count : 0;
        },
    },
    el: '#app'
});
<!-- development version, includes helpful console warnings -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<div id="app">
  <button-counter ref="counter">My counter: <span v-text="count"></span></button-counter>
</div>

使用slot-scope

使用槽作用域,您可以将多个参数传递给父槽:

// Define a new component called button-counter
Vue.component('button-counter', {
    data: function () {
        return {
            count: 0
        }
    },
    methods: {
        click() {
            this.count++;
        },
    },
    template: '<button v-on:click="click"><slot :count="count"></slot></button>'
})

// boot up the demo
var demo = new Vue({
    el: '#app'
});
<!-- development version, includes helpful console warnings -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<div id="app">
    <button-counter>
        <span slot-scope="prop">
            My counter:
            <span v-text="prop.count"></span>
        </span>
    </button-counter>
</div>

【讨论】:

  • 谢谢,不幸的是我不喜欢这些方式,我可能不得不找到一个黑客,或者求助于使用事件。我找到了一个库“vee-validate”,它实际上确实将数据推送到父组件,知道它是如何完成的吗?
  • @user3599803 他们可能通过查看$children 来从父母那里做这件事,或者通过走$parent 的链条从孩子那里去做
  • 我不知道怎么可能,vee-validate 实际上将反应属性注入到 vue 实例中,找不到它是如何完成的
【解决方案2】:

您可以将数据发送到插槽。看这个例子:

Vue.component('button-counter', {
  data: function () {
    return {
      count: 0
    }
  },
  template: '<button v-on:click="count++"><slot :count="count" /></button>'
})

<div id="app">
  <button-counter>
    <template scope="props">
      My counter: <span>{{ props.count }}</span>
    </template>
  </button-counter>
</div>

https://jsfiddle.net/s08yhcda/2/

【讨论】:

    猜你喜欢
    • 2019-04-17
    • 1970-01-01
    • 2018-06-08
    • 1970-01-01
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    • 2018-05-17
    • 2017-02-16
    相关资源
    最近更新 更多