Skip to content

about

基于vue2.6.14,https://github.com/vuejs/vue/releases/tag/v2.6.14

Vue快速入门篇,我们学习Vue的基本用法,但说白了,我们是将Vue当成jQuery一样使用,就是在写Vue版的JavaScript代码。

接下来,我们学习Vue的组件化开发模式,这也是开发中最常用的模式。

什么是组件?

组件(Component)就像外置网卡、外置蓝牙一样,插到主机上,就能提供的相关的功能,组件可以是一段代码、一个完整功能、一个模块的封装。

组件有两个明显的特点:

  • 内聚性:高内聚。
  • 耦合性:低耦合。

Vue中,也推荐使用组件化开发模式,将一个完整的功能封装成组件,然后,就是哪里需要直接使用即可。

组件的分类

Vue的组件分为普通组件和单文件组件,二者都有各自的应用场景。而普通组件又可以分为局部组件和全局组件。

这里我们先来通过学习普通组件,而单文件组件通常结合脚手架使用,我们后面再聊。

我们可以在组件内部使用watch、computed、filter等等功能,也可以在组件中嵌套组件。

局部组件

局部组件的使用,分为3步:创建组件、挂在组件、使用组件。

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>局部组件</title>
</head>
<body>
<div id="app">
    <!--  3. 使用组件  -->
    <!--  如果组件的命名是Comp这样的驼峰体,你在dom中可以如下使用组件  -->
    <compa></compa>
    <Compa></Compa>
    <!--  如果组件的命名是CompB这样的驼峰体,你在dom中可以如下使用组件,但不推荐  -->
    <comp-b></comp-b>
</div>
<script src="./vue.min.js"></script>
<script>
    // 局部组件的使用
    // 1. 创建组件
    const Compa = {

        // 注意:在组件中这个data必须是一个函数,而且必须返回一个对象
        data() {
            return {
                msg: "我是局部组件A"
            }
        },
        // 模板最外层必须是一个闭合标签,所以通常在模板中定义一个div来包裹所有的子标签
        template: `
            <div>
                {{msg}}
            </div>
        `
        // 你也可以在组件中使用的数据、监听、构建方法等
    }

    const CompB = {
        // 在局部组件内想要嵌套另一个子组件,先要挂载
        components: {
            Compa
        },
        template: `
            <div>
                我是局部组件B
                <Compa></Compa>
            </div>
        `
    }
    new Vue({
        el: "#app",
        data: {},
        components: {
            // 2. 挂载组件,注意组件名必须字母全小写且必须包含一个连接符,或者使用驼峰体
            Compa,
            CompB
        }
    })
</script>
</body>
</html>

注意,为了避免组件和未来HTML页面元素相冲突,组件名命名:强烈建议使用字母全小写且必须包含一个连接符,或者使用驼峰体也行,更多规范参考:

PS:局部组件用的不多。

全局组件

全局组件的使用只需要两步就可以了,创建组件,使用组件。

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>全局组件</title>
</head>
<body>
<div id="app">
    <!--  2. 使用组件  -->
    <comp-a></comp-a>
    <Compb></Compb>
    <compb></compb>
    <compc></compc>
</div>
<script src="./vue.min.js"></script>
<script>
    // 全局组件的使用
    // 1. 创建组件
    Vue.component('comp-a', {
        // 注意:在组件中这个data必须是一个函数,而且必须返回一个对象
        data() {
            return {
                msg: "我是全局组件A"
            }
        },
        // 模板最外层必须是一个闭合标签,所以通常在模板中定义一个div来包裹所有的子标签
        template: `
            <div>
                {{msg}}
            </div>
        `
    })
    Vue.component('Compb', {
        // 模板最外层必须是一个闭合标签,所以通常在模板中定义一个div来包裹所有的子标签
        template: `
            <div>
                <h2>我是全局组件B,我嵌套了组件A</h2>
                <comp-a></comp-a>
            </div>
        `
    })
    Vue.component('Compc', {
        // 模板最外层必须是一个闭合标签,所以通常在模板中定义一个div来包裹所有的子标签
        template: `
            <div>
                <h2>我是全局组件C,我嵌套了组件B</h2>
                <Compb></Compb>
                <compb></compb>
            </div>
        `
    })
    new Vue({
        el: "#app",
        data: {}
    })
</script>
</body>
</html>

组件中虽然可以嵌套组件,但不允许循环嵌套,即组件a中嵌套b,b中再嵌套a,这是不允许的。

如果你仔细的研究了Vue官网的命名规则,那么:

  • 如果组件命名遵循kebab-case格式即Vue.component('my-component-name', { /* ... */ }),那么你使用时也要<my-component-name></my-component-name>
  • 如果组件命名遵循PascalCase。
  • 如果是Vue.component('MyComponentName', { /* ... */ }),那么在组件的模板中,<MyComponentName></MyComponentName>或者<my-component-name></my-component-name>都可以,但是在dom中,只有<my-component-name></my-component-name>
  • 如果是Vue.component('Mycomponentname', { /* ... */ }),那么在组件的模板和dom中,<Mycomponentname></Mycomponentname>或者<mycomponentname></mycomponentname>都可以。

所以,组件命名推荐遵循kebab-case,如果是PascalCase,推荐使用首字母大写的驼峰体。

你也可以将全局组件单独封装成js文件,然后哪里需要就在哪里引入了。

comp-b.js

javascript
Vue.component('comp-b', {
    // 注意:在组件中这个data必须是一个函数,而且必须返回一个对象
    data() {
        return {
            msg: "我是全局组件A"
        }
    },
    // 模板最外层必须是一个闭合标签,所以通常在模板中定义一个div来包裹所有的子标签
    template: `
        <div>
            {{msg}}
            <CompA></CompA>
        </div>
    `
})

在HTML文件中引入:

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>全局组件</title>
</head>
<body>
<div id="app">
    <h3>组件可以多次使用,且相互隔离</h3>
    <comp-b></comp-b>
    <comp-b></comp-b>
    <comp-b></comp-b>
    <comp-b></comp-b>
</div>
<script src="./vue.min.js"></script>
<script src="comp-b.js"></script>
<script>
    new Vue({
        el: "#app",
        data: {},
    })
</script>
</body>
</html>

但很明显,这种操作不太符合Vue的相关规范,对于这种使用模式,我们通常是以插件的形式引入,当然,我们后面再学习插件的相关用法。

组件通信

组件间的通信可以分为父传子、子传父、兄弟之间的通信。

父传子:pro