Vue 组件注册:基本使用和组件嵌套


除了前面介绍的基本语法之外,Vue.js 还支持通过组件构建复杂的功能模块,组件可以称得上是 Vue.js 的灵魂,是 Vue.js 框架提供的最强大的功能之一。

接下来,学院君就来给大家由浅入深地介绍如何在 Vue.js 中通过组件构建不同的功能模块。

我们在列表渲染这篇教程中实现过一个 Web 编程语言列表功能,这里我们通过组件功能对之前的代码进行重构。

vue_learning 目录下新建一个 component 子目录,然后新建一个 demo.html 文件存放本篇教程的代码。

Vue 组件的基本使用

在这个 HTML 文档中,基于组件功能实现 Web 编程语言列表渲染功能如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue 组件开发入门</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <p> Web 编程语言:</p>
        <languages></languages>
    </div>
    <script>
        Vue.component('languages', {
            data: function () {
                return {
                    languages: ['PHP', 'JavaScript', 'Golang']
                }
            },
            template: '<ul><li v-for="language in languages">{{ language }}</li></ul>'
        })
        var app = new Vue({
            el: '#app',
        });
    </script>
</body>
</html>

可以看到,在这段代码中,我们在初始化 Vue 实例之前通过 Vue.component 函数定义了一个名为 languages 的组件(通过第一个参数指定组件名):

Vue.component('languages', {
    data: function () {
        return {
            languages: ['PHP', 'JavaScript', 'Golang']
        }
    },
    template: '<ul><li v-for="language in languages">{{ language }}</li></ul>'
})

然后在第二个参数中定义这个组件的对象属性,它的基本结构和 Vue 全局对象实例类似,只是没有通过 el 映射对应的 HTML 视图容器。

我们通过 data 定义了这个组件的数据属性(和 Vue 对象不同的是这里的 data 属性返回的是函数而非对象),通过 template 定义了组件模板代码,组件模板中可以使用 Vue 的所有基本语法,还可以引用该组件的 data 数据属性。

最后我们要渲染这个组件模板,可以在 HTML 视图层中插入 <languages></languages>即可,插入的位置必须位于 Vue 全局对象作用的 HTML 容器内,否则不会生效。

在浏览器中预览上述 HTML 文档,渲染效果如下:

-w486

注:组件定义代码要放到 Vue 全局对象实例化之前,否则在对象容器初始化的时候无法识别 languages 元素。

如果用类比的方式来看,Vue 组件和全局 Vue 对象很相似,继承了它的几乎所有属性,除了 HTML 根元素,然后在全局对象作用的容器中通过组件名引入即可实现该组件的渲染,渲染时使用的是组件对象的 template 属性,这通常是一段 HTML 代码,我们可以在 template 字符串中通过调用组件的 datamethodscomputed 等属性/方法实现动态效果。

这样一来,如果把 Vue 组件名对应的 HTML 元素看作组件对应的根元素容器,那么 Vue 组件其实就是和 Vue 全局对象有着一致语法的「小生态」,这样一来就极大降低了 Vue 组件的学习成本,也方便了不同组件之间的组合、嵌套、架构。最终,Vue.js 框架可以在 Vue 全局对象容器作用域内通过这样的一个个语法结构一致、实现功能不同的组件(这些组件之间或并行、或嵌套)的相互协同下,构建出各种复杂的页面功能和模块。

接下来,我们就来逐一介绍 Vue 组件支持的语法、组件间的通信和嵌套,并基于这些功能特性构建复杂的功能模块。

组件嵌套和代码复用

我们首先来看下组件之间的嵌套调用。

为了提高组件代码的复用性,我们可以将上面列表中的列表项单独拆分出来构建一个粒度更细的组件 langugae

Vue.component('language', {
    template: '<li><slot></slot></li>'
})

这里我们使用了 <slot></slot> 表示从调用该组件的父作用域中传递文本来渲染,该功能称之为插槽,后面我们会详细介绍插槽的使用和语法,这里先了解即可。

接下来,我们定义一个调用 language 组件的父级组件 languages

Vue.component('languages', {
    data: function () {
        return {
            languages: ['PHP', 'JavaScript', 'Golang']
        }
    },
    template: '<ul><language v-for="language in languages">{{ language }}</language></ul>'
})

这样一来,我们就实现了在 languages 父组件中嵌套调用子组件 language 进行渲染的功能,相应的代码很简单,唯一需要注意的是就是我们在父组件的模板代码中调用 language 组件时,通过 {{ language }} 将对应的文本传递给了子组件,这样对应的语言字符串就会替换子组件中的 <slot></slot> 插槽渲染出来。

在浏览器中刷新这个 HTML 文档,渲染效果和之前完全一样:

-w486

如果我们打开开发者工具中的 Vue Devtools 扩展标签页,可以看到现在的 Components 中已经包含了 languageslanguage 组件:

-w993

除了插槽之外,还可以通过 props 在父组件和子组件之间传递数据,我们将在下篇教程给大家演示 Vue 组件之间的通信和事件处理。


Vote Vote Cancel Collect Collect Cancel

<< 上一篇: 在 Vue.js 中通过计算属性动态设置属性值

>> 下一篇: Vue 组件通信:父子组件之间的数据传递和事件监听