【问题标题】:Vue component communicationVue组件通信
【发布时间】:2019-05-10 14:46:20
【问题描述】:

我正在寻找两个 Vue 组件的简洁示例。第一个组件应该包含一个文本输入或文本区域。第二个组件显示一个字符计数器。我希望第一个组件发出更改事件,第二个组件应该监听这些事件并显示其计算值(字符数)。我是 Vue 的新手,并试图围绕实现此功能的最佳方法。在纯 JavaScript 中看起来相当简单,但是用 Vue 的方式来做这件事对我来说不是很清楚。谢谢。

这是我在 JavaScript 中的做法:

这是文本区域:

<textarea id="pagetext" name="pagetext"
                          onChange="characterCount();"
                          onKeyup="characterCount();">Type here</textarea>

这是 JavaScript:

function characterCount()
{ 
        var characters=document.myForm.pagetext.value.length;
        document.getElementById('charcounter').innerHTML=characters+"";
}

我对 Vue 的担忧是传递整个价值……出于性能原因,这似乎不太理想。我可能希望我的文本编辑 Vue 组件自包含值并发出统计信息,即字符计数的值,然后由文本统计组件观察。

【问题讨论】:

  • 非常简单,您使用事件和道具将值从一个组件传播到另一个组件。在这种情况下,您可能希望将输入值发送到其父级。在那里,您可以直接计算输入长度或通过 prop 将值推送到另一个子组件。
  • 用纯JavaScript写一个demo sn-p,我们可以教你如何修改成Vue的方式。
  • 添加了一个普通的旧 JavaScript sn-p 和一个性能问题。

标签: vue.js


【解决方案1】:

我编写了一个带有四个示例的 sn-p:您的原始应用程序,一个执行相同操作的简单 Vue 应用程序(无组件),以及两个由父级协调的具有两个组件的应用程序。

简单的 Vue 应用程序实际上比纯 JavaScript 应用程序更简洁,我认为它展示了拥有框架的原因:您的视图不充当程序数据的存储,您必须从中提取数据出来吧。

在最后一个示例中,父级仍然拥有pageText,但将其传递给my-textarea 组件。我喜欢将发射隐藏在可设置计算的抽象后面,以便元素可以使用v-model。任何更改都会发送到父级,父级会更改pageText,然后向下传播回组件。

我认为您的性能问题属于过早优化的领域,但是可以根本不将文本内容用作数据,而只关心长度。第四个例子就是这样做的。 emitLength 可以使用event.target.value.length,但我想在mounted 中使用它来正确初始化长度,所以我使用了ref

function characterCount() {
  var characters = document.myForm.pagetext.value.length;
  document.getElementById('charcounter').innerHTML = characters + "";
}
new Vue({
  el: '#app',
  data: {
    pageText: 'Type here'
  }
});

new Vue({
  el: '#app2',
  data: {
    pageText: 'Type here'
  },
  components: {
    myTextarea: {
      props: ['value'],
      template: '<textarea name="pagetext" v-model="proxyValue"></textarea>',
      computed: {
        proxyValue: {
          get() {
            return this.value;
          },
          set(newValue) {
            this.$emit('input', newValue);
          }
        }
      }
    },
    textLength: {
      props: ['value'],
      template: '<div>{{value}}</div>'
    }
  }
});

new Vue({
  el: '#app3',
  data: {
    textLength: null
  },
  components: {
    myTextarea: {
      template: '<textarea ref="ta" name="pagetext" @input="emitLength">Type here</textarea>',
      methods: {
        emitLength() {
          this.$emit('change', this.$refs.ta.value.length);
        }
      },
      mounted() {
        this.emitLength();
      }
    },
    textLength: {
      props: ['value'],
      template: '<div>{{value}}</div>'
    }
  }
});
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<form name="myForm">
  <textarea id="pagetext" name="pagetext" onChange="characterCount();" onKeyup="characterCount();">Type here</textarea>
</form>
<div id="charcounter"></div>

<div id="app">
  <h1>Vue (simple)</h1>
  <form>
    <textarea name="pagetext" v-model="pageText"></textarea>
  </form>
  <div>{{pageText.length}}</div>
</div>

<div id="app2">
  <h1>Vue (with components)</h1>
  <form>
    <my-textarea v-model="pageText"></my-textarea>
  </form>
  <text-length :value="pageText.length"></text-length>
</div>

<div id="app3">
  <h1>Vue emitting stats</h1>
  <form>
    <my-textarea @change="(v) => textLength=v"></my-textarea>
  </form>
  <text-length :value="textLength"></text-length>
</div>

【讨论】:

    【解决方案2】:

    您可以为textarea 的值创建一个“模型”,并使用以下方式https://vuejs.org/v2/guide/components-props.html 将此模型提供给第二个component

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-13
      • 2017-03-25
      • 2019-09-18
      • 2021-02-07
      • 1970-01-01
      • 2016-11-05
      • 2018-09-06
      • 1970-01-01
      相关资源
      最近更新 更多