2020 vuejs 中组件实现

vuejs-logo.png

组件化

组件化是任何一个框架必须实现,如何将定义组件(js 对象)转化为 dom 对象,以及组件的属性转换为 dom 属性,这是每一个前端框架在设计时需要认真思考和设计的问题。

const vm= new Vue({
    el:'#root',
    data:{},
    props:{},
    methods:{},
    watch:{},
    computed:{},
    template:"...",
    components:{},
});
属性名 说明
el 用来加载 Vue 对象的元素
data 绑定的数据
props 用来接收外部数据的属性
methods 定义 Vue 对象内部使用的方法
watch 用于观察 Vue 对象内部资料的更新
computed 自动为内部数据计算过的属性
template 存放 Vue 对象编译后生成的模板
components 定义子元素

昨天写 react,今天朋友让我来谈谈 vue,个人对于 vue 了解并不多。先接触的 angular 随后是 react ,vue 是这两年市场推动不得不也看一看 vue。最近听了 Evan 关于 vue3 介绍,vue3 还是很吸引人,一堆提高性能的优化。

按作用域范围

  • 区域性(具有作用域)注册组件


    register_scope

    其实渲染出来并不是 javascript 提供自定义组件而是一个 div


    render_div_for_register_scope

所谓区域(作用域)注册中区域指的就是这些元素父级元素<div id="app">

    <div id="app">
        <zi-comp></zi-comp>
        <zi-comp></zi-comp>
        <zi-comp></zi-comp>
    </div>
    <div id="app2">
        <zi-comp></zi-comp>
    </div>

这样在 app2 作用域内是无法识别到在 app 作用域注册的组件 zi-comp

global_register_comp

关于组件中 data 的属性

这里有一个我们需要注意的,也是我们对 vue 设计理念有点 confusing 的。data 属性值是一个函数返回一个对象,而不是直接接收一个对象作为 data 的属性值。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

    <title>Document</title>
</head>

<body>
    <div id="app">{{msg}}<zi-comp></zi-comp>
    </div>
    <script>
        Vue.component('zi-comp', {
            template: '<div class="comp">{{msg}}</div>',
            data: function () {
                return {
                    msg: "A custom component of Vue"
                }
            }
        });
        new Vue({
            el: "#app",
            data: {
                msg: 'A root msg of Vue'
            }
        });
    </script>
</body>

</html>

在组件中对 data 属性

            data: function () {
                return {
                    msg: "A custom component of Vue"
                }
            }

为什么会这样,可以简单思考一下,因为在 javascript 语言中没有大括号的作用域,最小作用域范围就是函数,如果没有通过 function 来限制数据 data 作用范围,data 就会把全局 data 覆盖掉,就这么简单。

大家可以通过运行下面的代码来观察问题,以及我们为什么要在 data 属性通过一个函数返回值来给 data 属性赋值的原因。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <title>Document</title>
    <style>
        .container {
            width: 100vw;
            height: 50vh;
            display: flex;
            justify-content: center;
            align-items: center;
            flex-direction: column;
        }

        .comp {
            height: 48px;
            background: dodgerblue;
            padding: 12px 24px;
            display: flex;
            color: white;
            font-size: 1.2em;
            margin-bottom: 6px;
            justify-content: center;
            align-items: center;
        }
    </style>
</head>

<body>
    <div id="app" class="container">
        <zi-comp></zi-comp>
        <zi-comp></zi-comp>
        <zi-comp></zi-comp>
        <zi-comp></zi-comp>
        <zi-comp></zi-comp>
    </div>
    <script>
        var data = {
            count: 0
        }
        Vue.component('zi-comp', {
            template: '<div class="comp"><span>{{count}}</span> <button @click="count++">add</button> </div>',
            data: function () {
                return data;
            }
        });

        new Vue({
            el: "#app"
        });
    </script>
</body>

</html>

通过修改 zi-comp 的 data 属性,返回一个对象,这样 count 属性就不会覆盖外面属性,这时的 count 只属于该 zi-comp 组件实例化对象的 count。通过这个示例我想大家可能对为什么在 vue 的组件定义数据 data 属性时,需要提供函数然后在其中将数据对象返回原因了吧。

Vue.component('zi-comp', {
            template: '<div class="comp"><span>{{count}}</span> <button @click="count++">add</button> </div>',
            data: function () {
                return {
                    count:0
                };
            }
        });

模板文件

在 vue 中,避免大家在 vue 对象中的 template 写一些复杂 html 结构,vue 和其他框架一样提供在 vue 外部写 html 模板,然后在 vue 对象通过模板 id 来引用模板的方式来写模板。

<body>
    <div id="app">
        <zi-comp></zi-comp>
    </div>
    <script type="text/x-template" id="zi-comp">
        <div class="comp">A custom component of Vue!</div>
    </script>
    <script>
        //register
        Vue.component('zi-comp', {
            template: "#zi-comp"
        });
        new Vue({
            el: "#app"
        });
    </script>
</body>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343