2020 vuejs 中組件實(shí)現(xiàn)

vuejs-logo.png

組件化

組件化是任何一個(gè)框架必須實(shí)現(xiàn),如何將定義組件(js 對(duì)象)轉(zhuǎn)化為 dom 對(duì)象,以及組件的屬性轉(zhuǎn)換為 dom 屬性,這是每一個(gè)前端框架在設(shè)計(jì)時(shí)需要認(rèn)真思考和設(shè)計(jì)的問題。

const vm= new Vue({
    el:'#root',
    data:{},
    props:{},
    methods:{},
    watch:{},
    computed:{},
    template:"...",
    components:{},
});
屬性名 說明
el 用來加載 Vue 對(duì)象的元素
data 綁定的數(shù)據(jù)
props 用來接收外部數(shù)據(jù)的屬性
methods 定義 Vue 對(duì)象內(nèi)部使用的方法
watch 用于觀察 Vue 對(duì)象內(nèi)部資料的更新
computed 自動(dòng)為內(nèi)部數(shù)據(jù)計(jì)算過的屬性
template 存放 Vue 對(duì)象編譯后生成的模板
components 定義子元素

昨天寫 react,今天朋友讓我來談?wù)?vue,個(gè)人對(duì)于 vue 了解并不多。先接觸的 angular 隨后是 react ,vue 是這兩年市場推動(dòng)不得不也看一看 vue。最近聽了 Evan 關(guān)于 vue3 介紹,vue3 還是很吸引人,一堆提高性能的優(yōu)化。

按作用域范圍

  • 區(qū)域性(具有作用域)注冊(cè)組件


    register_scope

    其實(shí)渲染出來并不是 javascript 提供自定義組件而是一個(gè) div


    render_div_for_register_scope

所謂區(qū)域(作用域)注冊(cè)中區(qū)域指的就是這些元素父級(jí)元素<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 作用域內(nèi)是無法識(shí)別到在 app 作用域注冊(cè)的組件 zi-comp

global_register_comp

關(guān)于組件中 data 的屬性

這里有一個(gè)我們需要注意的,也是我們對(duì) vue 設(shè)計(jì)理念有點(diǎn) confusing 的。data 屬性值是一個(gè)函數(shù)返回一個(gè)對(duì)象,而不是直接接收一個(gè)對(duì)象作為 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>

在組件中對(duì) data 屬性

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

為什么會(huì)這樣,可以簡單思考一下,因?yàn)樵?javascript 語言中沒有大括號(hào)的作用域,最小作用域范圍就是函數(shù),如果沒有通過 function 來限制數(shù)據(jù) data 作用范圍,data 就會(huì)把全局 data 覆蓋掉,就這么簡單。

大家可以通過運(yùn)行下面的代碼來觀察問題,以及我們?yōu)槭裁匆?data 屬性通過一個(gè)函數(shù)返回值來給 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 屬性,返回一個(gè)對(duì)象,這樣 count 屬性就不會(huì)覆蓋外面屬性,這時(shí)的 count 只屬于該 zi-comp 組件實(shí)例化對(duì)象的 count。通過這個(gè)示例我想大家可能對(duì)為什么在 vue 的組件定義數(shù)據(jù) data 屬性時(shí),需要提供函數(shù)然后在其中將數(shù)據(jù)對(duì)象返回原因了吧。

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

模板文件

在 vue 中,避免大家在 vue 對(duì)象中的 template 寫一些復(fù)雜 html 結(jié)構(gòu),vue 和其他框架一樣提供在 vue 外部寫 html 模板,然后在 vue 對(duì)象通過模板 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>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容