首页 Vue组件化编程
文章
取消

Vue组件化编程

什么是组件

实现应用中局部功能代码和资源的集合

组件化编程的好处

  • 依赖关系更加清晰
  • 代码复用率更高(不仅仅是js和css,html结构也被复用了)

组件化模型

非单文件组件和单文件组件

什么是非单文件组件和单文件组件,看下图:
非单文件组件和单文件组件

简而言之,非单文件组件是一个html文件,里面使用到多个组件,单文件组件是一个vue文件,本身代表一个组件

非单文件组件的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>非单文件组件</title>
    <script src="./js/vue.js"></script>
    <style>
        /* 中间如果不加',',表示的是后代元素,加了才表示两个没有关系的class */
        .mytitle, .text {
            font-size: 50px;
        }
    </style>
</head>

<body>
    <div id="app">
        <!-- 3.使用组件 -->
        <list></list>
    </div>
</body>

<script>
    // 1.定义组件
    const myList = Vue.extend({
        // el:'#app',不需要挂载容器,毕竟组件作为复用对象是要被用在不同的地方,而且它是由Vue实例进行统一管理的
        // 1-1.组件结构,template结构必须有一个root element,即整个template需要用容器包裹,这个容器可以是任意的
        template: `
                <div>
                    <p class='mytitle' v-text='title'></p>
                    <ul>
                        <li class='text' v-for='food in foods'></li>
                    </ul>
                </div>
            `,
        // 1-2.数据对象必须用函数式,因为函数式每次返回不同的对象,那么就不存在改了值大家都变了的结果
        data() {
            return {
                title: '食谱',
                foods: ['青椒炒肉', '水煮鱼片', '宫保鸡丁']
            }
        }

    });

    // 2.注册组件
    new Vue({
        components: {
            // 左边的组件名中间不能有大写字母,如果左右名称相同,就可以省略冒号和右边
            list: myList
        },
    }).$mount('#app');
</script>

</html>

非单文件组件使用流程

非单文件组件使用流程:

非单文件组件需要注意的点

非单文件组件需要注意的点

组件嵌套与标准化开发

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>非单文件组件</title>
    <script src="./js/vue.js"></script>
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>
    
</head>

<body>
    <!-- 2-1.最终在html结构中,我们不需要写任何代码,这样非常的清晰 -->
    <div id="app">

    </div>
</body>

<script>
    // 1.定义组件
    const list = Vue.extend({
        // 1-1.列表组件
        template: `
                <div>
                    <p class='mytitle' v-text='title'></p>
                    <ul>
                        <li class='text' v-for='food in foods'></li>
                    </ul>
                </div>
            `,
        data() {
            return {
                title: '食谱',
                foods: ['青椒炒肉', '水煮鱼片', '宫保鸡丁']
            }
        }
    });

    
    const mybutton = {
        // 1-2.按钮组件
        template: `
            <Button type="submit">提交</Button>
        `
    }

    const myinput = {
        // 1-3.输入框组件
        template: `
            <input type='text' value='请输入值' />
        `
    }


    const app = {
        // 1-4.母组件
        template: `
            <div>
                <mylist></mylist>
                <myinput></myinput><br>
                <mybutton></mybutton>
            </div>
        `,
        // 1-5.app统一管理子组件
        components:{
            mybutton,
            myinput,
            mylist:list
        }
    }
    

    // 2.注册组件
    new Vue({
        template: `
            <app></app>
        `,
        // vm管理母组件
        components: {
            app
        },
    }).$mount('#app');
</script>

</html>

像下面的这种结构:
标准化开发结构

我们称其为标准化开发

VueComponent构造函数

深入理解组件
深入理解组件

一个重要的内置关系

在javascript中存在一种被称作原型链的关系,其中实例对象的属性__proto__会指向它的上级,它对应的构造函数的属性prototype也会指向实例对象的上级

而在Vue中,有这样一个重要的内置关系:VueComponenet.prototype.__proto__ == Vue.prototype,而这个关系的存在使得组件实例对象(vc)可以访问到Vue原型上的属性和方法

Vue与VueComponent的关系

单文件组件

单文件组件以.vue结尾,最终会被编译成.js,单文件的基本组成结构

1
2
3
4
5
6
7
8
9
10
11
<template>
    // 组件的结构,template最终会被消掉,留下里面的东西
</template>

<script>
    // 相关的资源和交互逻辑代码
</script>

<style>
    // 样式
</style>

非单文件组件与单文件组件相比他不能为每个组件分组独立的css,这是它的缺陷,也是单文件组件的优点

单文件组件示例
List.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<template>
    // 1.注意外面一定要用root元素包裹
    <div>
        <p class='mytitle' v-text='title'></p>
        <ul>
            <li class='text' v-for='food in foods'></li>
        </ul>
    </div>
</template>

<script>
    // 2.组件需要被暴露,才能被外界使用
    
    // 第一种写法,分别暴露
    // export const list = {
        
    //     data() {
    //         return {
    //             title: '食谱',
    //             foods: ['青椒炒肉', '水煮鱼片', '宫保鸡丁']
    //         }
    //     },

    //     methods: {

    //     }
    // }

    // 第二种写法,统一暴露
    // export {list}



    // 第三中方式,默认暴露
    // export default list
    // 或者下面这样
    export default {
        name: List,
        
        data() {
            return {
                title: '食谱',
                foods: ['青椒炒肉', '水煮鱼片', '宫保鸡丁']
            }
        },

        methods: {

        }
    }
</script>

<style>

</style>

App.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<template>
    <div>
        // 4.实例化组件
        <List></List>
    </div>
</template>

<script>
    // 1.引入子组件,.vue在脚手架中可以忽略
    import List from './List.vue'

    // 2.组件需要被暴露,才能被外界使用
    export default {
        name: App,
        // 3.注册组件
        components:{
            List
        }
    }
</script>

<style>

</style>

main.js

1
2
3
4
5
6
7
8
9
10
import App from './App.vue'

new Vue({
    el:'#root',
    // 在这里写了
    template:`<App></App>`
    components:{
        App
    }
})

index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>测试</title>
</head>
<body>
    <div id="root"></div>
    <!-- 1.main.js使用了Vue,所以在它之前需要引入vue.js -->
    <script src="./js/vue.js"></script>
    <!-- 2.由于main.js使用了root元素,因此必须在其后引入 -->
    <script src="./main.js"></script>
</body>
</html>

分别暴露和统一暴露被外界引用时格式:import {XXX} from YYY,而默认暴露是:import XXX from YYY,所以我们推荐使用默认暴露,因为它更加简洁

es6模块化

本文由作者按照 CC BY 4.0 进行授权