Vue组件通讯:单个组件
单个组件相对而言简单一点。在我看来,有些事情你需要知道才能让你开始。关于Vue组件的模板和脚本部分如何协同工作的。模板和脚本组成一个单元,并共享相同的数据。最好的学习就是通过一些实例来阐述,这样更易于交流。
模板到脚本:事件
在UI中用户事件之后用户可以使用一些用户事件。在模板中@click="handleClick"
将会调用handleClick
方法。
<template>
<button @click="handleClick">
Tacos?
</button>
</template>
<script>
export default {
name: 'SingleComponent',
methods: {
handleClick () {
alert('Tacos!')
}
}
}
</script>
效果如下:
点击示例中的button
会有一个alert
弹出来。如下所示:
上面示例中,采用的是x-template定义组件模板的方式。如果你对创建组件模板方式了解不多,建议阅读《Vue.js 定义组件模板的七种方式》一文。至于在示例中采用哪一种方式,根据自己的喜好或项目需求来做。
再次回到我们示例中来,在上面的示例中,我们稍做调整,你就可以传参数到handleClick()
方法中:
<template>
<button @click="handleClick('Tacos')"> Tacos? </button>
</template>
<script>
export default {
name: 'SingleComponent',
methods: {
handleClick (value) {
alert(`${value}!`)
}
}
}
</script>
上面这个示例,在handleClick()
方法中传了一个value
参数。在@click
调用handleClick()
方法时传了一个Hello, W3cplus.com
值。当点击按钮时,弹框会弹出我们传的值Hello, W3cplus.com
。如下所示:
方法也可以接受事件。
<template>
<button @click="handleClick('Tacos', $event)" @mouseenter="handleMouseEnter">
Tacos?
</button>
</template>
<script>
export default {
name: 'SingleComponent',
methods: {
handleClick (value, event) {
console.log(`${value}!`)
console.log('Click', event)
},
handleMouseEnter (event) {
console.log('Mouse Enter', event)
}
}
}
</script>
效果如下:
当你在v-for
指令中使用事件时,参数也是有用的。当你单击其中的一个菜单项时,事件处理程序知道你已经选择了哪个项目。
<template>
<div>
<button v-for="(entry, index) in menu" :key="index" @click="selectEntry(entry)"> {{entry}} </button>
</div>
</template>
<script>
export default {
name: 'SingleComponent',
data () {
return {
menu: ['tacos', 'hot dogs', 'ice cream']
}
},
methods: {
selectEntry (value) {
alert(`${value} it is!`)
}
}
}
</script>
效果如下:
这是一些示例。你可以通过事件和处理程序做更多的事情。Vue指南对这个问题做出很好的解释:
脚本到模板:反应性
在大多数情况下,使用反应系统已经足够了。因为你需要在组件的脚本部分更改数据,并且根据数据更改重新渲染模板。
比如下面这个示例,脚本每5s
会更改一次交通灯。该模板将每次显示isGreen
更改的值。甚至不需要以任何方式访问模板。请注意,我们可以更改数据,尽管现在组件可能无法呈现。该间隔将在created()
方法中设置。可以独立于组件的模板中进行更改。
对我来说,当你从jQuery的世界中走出来的时候,你就会感到非常兴奋。使用jQuery,你需要选择节点,然后更改文本。而使用Vue你不需要担心这些事项。
<template>
<div class="traffic-light">
isGreen: {{ isGreen }}
</div>
</template>
<script>
export default {
name: 'TrafficLight',
data () {
return {
isGreen: false,
interval: null
}
},
created () {
this.interval = setInterval(() => {
this.isGreen = !this.isGreen
}, 5 * 1000)
},
beforeDestroy () {
clearInterval(this.interval)
}
}
</script>
效果如下:
我在想是不是可以使用Vue做一个红绿灯的组件出来。当然做一个红绿灯出来,我还得去学习一些其他的知识,如果你和我一样感兴趣,建议阅读这篇文章《红绿灯大战中的火星生命-Promise》。
脚本到模板:refs
在某些情况下,就算是单个组件中,你也可能会需要一个ref
。
我想到了两个示例:
- 你希望访问DOM Node的属性,比如
canvas
图像数据或者复选框的选中值 - 你需要使用另一个库并将其传递给DOM Node
这是一个Canvas的示例:
<template>
<div id="canvas-example">
<canvas ref="canvas" height="200" width="200" />
</div>
</template>
<script>
export default {
name: 'CanvasExample',
mounted () {
const ctx = this.$refs.canvas.getContext('2d')
ctx.fillStyle = 'rgb(200,0,0)'
ctx.fillRect(10, 10, 55, 50)
ctx.fillStyle = 'rgba(0, 0, 200, 0.5)'
ctx.fillRect(30, 30, 55, 50)
}
}
</script>
效果如下:
我意识到这一点已经太迟了,我感到很尴尬。ref
将像其他属性一样对待。这意味着,你还可以传递动态值。
如果你运用的是循环,那就很方便了。
<template>
<ul id="dynamic-refs">
<li
v-for="entry in entries"
:key="entry.id"
:ref="`entry${entry.id}`"
>
{{ entry.title }}
</li>
</ul>
</template>
<script>
export default {
name: 'DynamicRefs',
data () {
return {
entries: [
{ id: 1, title: 'Uno' },
{ id: 2, title: 'Due' }
]
}
},
mounted () {
console.log(this.$refs.entry1)
}
}
</script>
有关于refs
更多的教程,可以阅读下面的文章:
- Accessing the DOM in Vue.js with
$refs
- Vue.js explained through Pokemon #2 $refs, Promises & event bus
v-model
当构建表单时,你将希望在input
输入的数据能让用户立马看到。很多时候,也称之为双向数据绑定。
他们有一定的约定规则:
- 将当前数据作为值传递给模板
- 为用户输入发送输入事件
当你看到在组件中使用value
和input
时应该立马想到v-model
。
下面两个版本的组件,实现的功能是一样的:
<template>
<input
:value="name"
@input="handleNameInput"
>
</template>
<script>
export default {
name: 'ValueAndInput',
data () {
return {
name: ''
}
},
methods: {
handleNameInput (name) {
this.name = name
}
}
}
</script>
<template>
<input v-model="name">
</template>
<script>
export default {
name: 'ValueAndInput',
data () {
return {
name: ''
}
}
}
</script>
有关于
v-model
更多的介绍,可以阅读前面的学习笔记。
总结
组件通讯是创建组件无法避免的一个问题,不管是哪一个JavaScript框架都要面对这样的问题。这篇文章我们先介绍了Vue中单个组件的通讯的方式。在接下来的文章中,将会介绍父-子组件(Parent-Child)通讯方式。这可能会变得复杂也会变得更有趣。我们可以把学到的东西应用到子组件上。
另外需要声明的一点时,这篇文章的学习思路是根据@Christian Gambardella的系列文章第一篇进行学习的。由于自己是Vue的初学者,很多地方可能没有领会到作者的阐述观点,或者说理解有误的地方。还请大婶拍正。如果你在这方面有更好的经验或资料推荐,欢迎在下面的评论中与我们一起分享。
如需转载,烦请注明出处:https://www.fedev.cn/vue/vue-js-communication-single-component.htmlAir Max 95 Invigor Print