vue.js - Vue组件通信
问题描述
我正在寻找两个 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 组件自包含该值并发出统计信息,即字符计数的值,然后由文本统计组件观察。
解决方案
我编写了一个包含四个示例的片段:您的原始应用程序,一个执行相同操作的简单 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>
推荐阅读
- amazon-web-services - 来自“单点登录”的 AWS 凭证过于频繁地过期 - 如何获得使用寿命更长的凭证?
- c# - 我如何使用日期时间运算符?
- firebase - SwiftUI 和 Firestore - 启动时从不同集合中读取多个文档的逻辑
- elasticsearch - 新集群中的重新索引数据应使用最新的时间戳更新
- ios - 将 VNFeaturePrintObservation 持久化到核心数据
- sql-server - 以 YYYYMM 格式获取一年前的日期
- qt - 部署的视频应用程序无法播放 avi 文件
- python - Python 中的 itertools.count 使用什么类型?
- c# - 2D Unity 项目中的 3D 对象
- python - 是否可以将包含许多工作表的多个 excel 文件加载到一个主文件中