vuejs - 绑定到组件数据

Posted

技术标签:

【中文标题】vuejs - 绑定到组件数据【英文标题】:vuejs - bind to component data 【发布时间】: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 【参考方案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/

【讨论】:

以上是关于vuejs - 绑定到组件数据的主要内容,如果未能解决你的问题,请参考以下文章

Vuejs 2,VUEX,编辑数据时的数据绑定

VueJS v-model 和组件之间的数据绑定

vuejs 从子组件更新父数据

vuejs 从子组件更新父数据

Vuejs 动态 div 文本

Vuejs 子组件中的道具值无法绑定到元素属性