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更多的教程,可以阅读下面的文章:

v-model

当构建表单时,你将希望在input输入的数据能让用户立马看到。很多时候,也称之为双向数据绑定。

他们有一定的约定规则:

  • 将当前数据作为值传递给模板
  • 为用户输入发送输入事件

当你看到在组件中使用valueinput时应该立马想到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的初学者,很多地方可能没有领会到作者的阐述观点,或者说理解有误的地方。还请大婶拍正。如果你在这方面有更好的经验或资料推荐,欢迎在下面的评论中与我们一起分享。

大漠

常用昵称“大漠”,W3CPlus创始人,目前就职于手淘。对HTML5、CSS3和Sass等前端脚本语言有非常深入的认识和丰富的实践经验,尤其专注对CSS3的研究,是国内最早研究和使用CSS3技术的一批人。CSS3、Sass和Drupal中国布道者。2014年出版《图解CSS3:核心技术与案例实战》。

如需转载,烦请注明出处:https://www.fedev.cn/vue/vue-js-communication-single-component.htmlAir Max 95 Invigor Print