1. 程式人生 > >Vue封裝元件的過程

Vue封裝元件的過程

vue元件的定義

元件(Component)是Vue.js最強大的功能之一

● 元件可以擴充套件HTML元素,封裝可重用程式碼

● 在較高層面上,元件是自定義元素,Vue.js的編譯器為他新增特殊功能

有些情況下,元件也可以表現用 is 特性進行了擴充套件的原生的HTML元素

所有的Vue元件同時也都是Vue例項,所以可以接受相同的選項物件(除了一些根級特有的選項),並提供相同的生命週期鉤子

vue元件的功能

1)能夠把頁面抽象成多個相對獨立的模組

2)實現程式碼重用,提高開發效率和程式碼質量,使得程式碼易於維護

Vue元件封裝過程

● 首先,使用Vue.extend()建立一個元件

● 然後,使用Vue.component()方法註冊元件

● 接著,如果子元件需要資料,可以在props中接受定義

● 最後,子元件修改好資料之後,想把資料傳遞給父元件,可以使用emit()方法

元件使用流程詳細介紹

1、元件建立---有3中方法,extend()      <template id=''>      <script type='text/x-template'  id=''>

A、呼叫Vue.extend(),建立名為myCom的元件,template定義模板的標籤,模板的內容需寫在該標籤下

var myCom = Vue.extend({
    template: '<div>這是我的元件</div>'
})

B、<template id='myCom'>標籤建立,需要加上id屬性

<template id="myCom">
    <div>這是template標籤構建的元件</div>
</template>

C、<script type='text/x-template' id='myCom'>,需加id屬性,同時還得加type="text/x-template",加這個是為了告訴瀏覽器不執行編譯裡面的程式碼

<script type="text/x-template" id="myCom1">
    <div>這是script標籤構建的元件</div>
</script>

2、註冊元件----有2中方法,全域性註冊,區域性註冊

A1、全域性註冊:一次註冊( 呼叫Vue.component( 元件名稱,為元件建立時定義的變數 ) ),可在多個Vue例項中使用。

我們先用全域性註冊,註冊上面例子中建立的myCom元件

Vue.component('my-com',myCom)

A2、全域性註冊語法糖:不需要建立直接註冊的寫法

Vue.component('my-com',{
    'template':'<div>這是我的元件</div>'
})

'my-com'為給元件自定義的名字,在使用時會用到,後面myCom對應的就是上面構建的元件變數。

A3、如果是用template及script標籤構建的元件,第二個引數就改為它們標籤上的id值

Vue.component('my-com',{
    template: '#myCom'
})

B1、區域性註冊:只能在註冊該元件的例項中使用,一處註冊,一處使用

var app = new Vue({
    el: '#app',
    components: {
        'my-com': myCom
    }
})

B2、區域性註冊語法糖:

var app = new Vue({
    el: '#app',
    components: {
        'my-com': {
           template: '<div>這是我的元件</div>'
        }
    }
})

B3、<template>及<script>建立的元件,區域性註冊

var app = new Vue({
    el: '#app',
    components: {
        'my-com': {
           template: '#myCom'
        }
    }
})

3、呼叫元件

只需要在呼叫元件的地方,寫上元件名字的標籤即可

<div>
    /*呼叫元件*/
    <my-com></my-com>
</div>

4、栗子

A、全域性註冊:新建一個html檔案,引入vue.js,並且定義2個vue例項app1和app2

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue元件</title>
    <script src="vue.js"></script>
</head>
<body>
    <div id="app1">
        <my-com></my-com>
    </div>
    <div id="app2">
        <my-com></my-com>
    </div>

    <script>
        /*建立元件*/
        var myCom = Vue.extend({
            template: '<div>這是我的元件</div>'
        });
        /*全域性註冊元件*/
        Vue.component('my-com',myCom);

        /*定義vue例項app1*/
        var app1 = new Vue({
            el: '#app1'
        });

        /*定義vue例項app2*/
        var app2 = new Vue({
            el: '#app2'
        });
    </script>
</body>
</html>

顯示效果:

可以看到,全域性註冊的元件在例項app1和例項app2中都可以被呼叫。

B、區域性註冊:將建立的元件註冊到例項app1下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue元件</title>
    <script src="vue.js"></script>
</head>
<body>
    <div id="app1">
        <my-com></my-com>
    </div>
    <div id="app2">
        <my-com></my-com>
    </div>

    <script>
        var myCom = Vue.extend({
            template: '<div>這是我的元件</div>'
        });

        // Vue.component('my-com',myCom);
        /*區域性註冊元件*/
        var app1 = new Vue({
            el: '#app1',
            components:{
                'my-com':myCom
            }
        });

        var app2 = new Vue({
            el: '#app2'
        });
    </script>
</body>
</html>

可以看到只渲染了app1例項下的元件,app2例項雖然呼叫了該元件,但是因為這個元件沒有在其內部註冊,也沒有全域性註冊,所以報錯說找不到該元件。

C、template 和script標籤建立元件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue元件</title>
    <script src="vue.js"></script>
</head>
<body>
    <div id="app1">
        <my-com></my-com>
        <my-com1></my-com1>
    </div>

    <template id="myCom">
        <div>這是template標籤構建的元件</div>
    </template>

    <script type="text/x-template" id="myCom1">
        <div>這是script標籤構建的元件</div>
    </script>

    <script>
        Vue.component('my-com1',{ //全域性註冊
            template: '#myCom1'
        });

        var app1 = new Vue({
            el: '#app1',
            components:{
                'my-com':{
                    template: '#myCom'  //區域性註冊
                }
            }
        });
    </script>
</body>
</html>

顯示效果:

5、非同步元件

vue作為一個輕量級前端框架,其核心就是元件化開發。我們一般常用的是用腳手架vue-cli來進行開發和管理,一個個元件即為一個個vue頁面,這種叫單檔案元件。我們在引用元件之時只需將元件頁面引入,再註冊即可使用。

當專案比較大型,結構比較複雜時,我們一般選用vue-cli腳手架去構建專案。因為vue-cli集成了webpack環境,使用單檔案元件,開發更簡單,易上手,尤其是在對元件的處理上。對於原生vue.js,我們就得將元件構建在同一個html的script標籤下或者html的外部js中,所有元件集中在一塊,不容易管理,這也是原生vue,js的一點不便之處

vue.js可以將非同步元件定義為一個工廠函式。

使用$.get獲取本地檔案會跨域,所以要將專案部署到伺服器中

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue元件</title>
    <script src="vue.js"></script>
    <script type="text/javascript" src='jquery-3.1.1.min.js'></script>
</head>
<body>
    <div id="app1">
        <head-com></head-com>
    </div>
    <script>
        Vue.component('head-com', function (resolve, reject) {
            $.get("a.html").then(function (res) {
                resolve({
                    template: res
                })
            });
        });

        var app1 = new Vue({
            el: '#app1'
        });

    </script>
</body>
</html>

顯示效果如下:

6、Vue中的props資料流

通過在註冊元件中申明需要使用的props,然後通過props中與模板中傳入的對應的屬性名,去取用這些值

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue元件</title>
    <script src="vue.js"></script>
    <script type="text/javascript" src='jquery-3.1.1.min.js'></script>
</head>
<body>
    <div id='app'>
       <my-component name="jiangjiang" come-from="guilin"></my-component>
       <!-- 然後在模板中通過屬性傳值的方式進行資料的注入 -->
    </div>
    <script>
        Vue.component('my-component', {
          props: ['name', 'comeFrom'],    //在註冊元件的時候通過props選項聲明瞭要取用的多個prop
          // 在註冊元件的模板中使用到props選項中宣告的值
          template: '<p>我叫:{{name}}, 我來自:{{comeFrom}}</p>',
          created: function () {
            console.log('在created鉤子函式中被呼叫')
            console.log('我叫:', this.name)
            console.log('我來自:', this.comeFrom)
          }
        })


        new Vue({
          el: '#app'
        })


    </script>
</body>
</html>

注意

A、props取值的方式

在註冊元件的模板內部template,直接通過prop的名稱取值就Ok

template: '<p>我叫:{{name}}, 我來自:{{comeFrom}}</p>'

不在註冊元件的模板內部template,用this.prop的方式

 console.log('我來自:', this.comeFrom)

B、在template選項屬性中,可以寫駝峰命名法,也可以寫短橫線命名法

      在HTML(模板)中,只能寫短橫線命名法

原因:vue元件的模板可以放在兩個地方

a、Vue元件的template選項屬性中,作為模板字串

b、放在.html中[  用script  template標籤建立的元件 ],作為HTML

問題在於HTML不區分大小寫,所以在vue註冊元件中通用的駝峰命名法,不適用於HTML中的Vue模板,在HTML中寫入props屬性,必須寫短橫線命名法(把原來props屬性中的每個prop大寫換成小寫,並且在前面加“-”)

6中的

    <div id='app'>
       <my-component name="jiangjiang" come-from="guilin"></my-component>
       <!-- 然後在模板中通過屬性傳值的方式進行資料的注入 -->
    </div>

改成

    <div id='app'>
       <my-component name="jiangjiang" comeFrom="guilin"></my-component>
       <!-- 然後在模板中通過屬性傳值的方式進行資料的注入 -->
    </div>

顯示效果,第二個沒有顯示

非同步元件的實現原理;非同步元件的3種實現方式---工廠函式、Promise、高階函式

非同步元件實現的本質2次渲染,先渲染成註釋節點,當元件載入成功後,在通過forceRender重新渲染

高階非同步元件可以通過簡單的配置實現loading   resolve   reject   timeout  4種狀態