vue.js 組件知識總結

組件局部注冊

<div id="app">
        hello vue
        <my-component></my-component>   
    </div>
    <script>
        var Child = {
            template:'<div>局部注冊組件</div>'
        };
        new Vue({
            el:'#app',
            components:{
                'my-component':Child
            }
        })
    </script>

is 屬性掛載組件

常見:ul、select、table
(字符串模板除外:.vue文件)

例:在table里使用組件無效,添加一個is屬性。在is下往下寫無效。

<div id="app">
        <table border="1">
            <tbody is="my-com"></tbody>
        </table>
    </div>
    <script>
       Vue.component('my-com',{
         template:'<tr><td>1</td><td>2</td></tr>'
       });

        new Vue({
            el:'#app'
        })
    </script>

props

數(shù)組和對象是引用類型,指向同一片內存空間,所以props是數(shù)組和對象時,修改子組件內容會影響到父組件。默認雙向綁定。

數(shù)據(jù)驗證

Vue.component('my-component',{
        props:{
            propA:Number, //必須是數(shù)字類型
            propB:[String,Number],
            propC:{//布爾值,如果沒定義,默認是true
                type:Boolean,
                default:true
            },
            propD:{//數(shù)字,而且是必傳
                type:Number,
                required:true
            },
            propE:{//如果是數(shù)組或對象,默認值必須是一個函數(shù)來返回
                type:Array,
                default:function (){
                    return [];
                }
            },
            propF:{//自定義一個驗證函數(shù)
                validator:function(value){
                    return value > 10;
                }
            }
        } 
    })

自定義事件

v-on 監(jiān)聽自定義事件外,也監(jiān)聽DOM事件。用.native 修飾符表示監(jiān)聽的是一個原生事件,監(jiān)聽的是該組件的根元素。

<my-component v-on:click.native="handleClick"></my-component>

使用 v-model

  • 接受一個value屬性;
  • 在有新的value時觸發(fā)input事件
  <div id="app">
        {{ value }}
        <my-com v-model="value" @click="minus"></my-com>
        <!-- 父向子:執(zhí)行減操作 -->
        <button @click="minus">-1</button>
    </div>
    <script>
    // 點擊add加一 把const++通過input事件把const傳遞出去
    Vue.component('my-com', {
        props: {
            // 這個必須叫value,并與input一一對應。不懂為啥?
            value: {
                type: Number
            }
        },
        template: '<div> {{ const1 }} <button @click="add">+1</button></div>',
        data() {
            return {
                const1: this.value
            }
        },
        methods: {
            add() {
                this.const1++;
                this.$emit('input', this.const1);   //必須為input
            }
        },
        watch:{
            value(val){
                this.const1 = val;
            }
        }
    });
    new Vue({
        el: '#app',

        data: {
            value: 1
        },
        methods: {
            minus() {
                this.value--;
            },
        }

    })
    </script>

非父子組件通信

推薦使用一個空 Vue 實例作為中央事件總線(bus),也就是一個中介。

<div id="app">
        {{ message }}
        <my-coma></my-coma> 
    </div>
    <script>
     // 創(chuàng)建空的bus實例 
    const bus = new Vue({
        //可以繼續(xù)擴展bus
        //data,methods...
    });
     // 注冊一個組件
    Vue.component('my-coma',{
        template:'<button @click="passEvent">click</button>',
        methods:{
            passEvent(){
                bus.$emit('msgInfo','come from children ');
            }
        }
    });
    new Vue({
        el:'#app',
        data:{
            message:''
        },
        mounted(){
            bus.$on('msgInfo',(msg)=>{
                this.message = msg;
            })
        }
    })
    </script>
非父子組件通信--父鏈、子鏈

this.$parent 可以在子組件中取到父組件的東西

this.$children 可以拿到app 實例里的所有子組件,如果有很多子組件,可以得到一個數(shù)組。

修改父(子)組件內容,最好不這么做!

非父子組件通--子組件索引

子組件索引只在組件渲染完成后填充,非響應式的,僅作為直接訪問子組件的應急方案,應當避免在模板、計算屬性中使用自定義子組件索引。

加載兩個相同的組件,用ref 區(qū)分,如果需要for循環(huán),可以動態(tài)綁定:ref="a"

<my-coma ref='a'></my-coma> 
<my-coma ref='b'></my-coma> 

取值:

this.$refs.a

slot 內容分發(fā)

當需要讓組件組合使用時,要內容分發(fā),混合父組件內容和子組件模板就叫內容分發(fā)。

<div id="app">
       <my-com>
           <!-- message生命周期由父組件或父實例來決定的,包括作用域,和my-com本身沒關系。 -->
           {{ message }}
       </my-com>
   </div>
   <script>
       //hello world:
       // hello來自‘my-com’組件本身的內容,
       // world:父組件通過<slot>來充當?shù)倪@部分內容
       Vue.component( 'my-com',{
           //slot 標簽掛載內容,
           template:'<div>hello <slot></slot></div>',

       });

       new Vue({
           el:'#app',
           data:{
               message:'world'
           }
       })
   </script>

具名slot
在一個組件里,設置多個slot來區(qū)分顯示的內容。(按照slot順序展示:你好 朋友)

<my-com>
    <div slot="a">
        你好
    </div>
    <div slot="b">
        朋友
    </div>
</my-com>

script

<script>
        Vue.component( 'my-com',{
            template:'<div>hello <slot name="a"></slot><slot name="b"></slot></div>',

        });
        new Vue({
            el:'#app',
        })
    </script>

slot展示默認內容
如果組件里沒有內容,就會顯示slot里的默認內容。內容作用域只與當前組件(my-com)相關,與父組件無關。

<div id="app">
        <my-com></my-com>
    </div>

script

Vue.component( 'my-com',{
            template:'<div>hello <slot>這里是默認</slot></div>',
        });

訪問slot
rander函數(shù)用的多

mounted(){
    this.$slots.default   //取默認內容
    this.$slots.a         //取a的內容
}

組件的高級用法

遞歸組件

滿足條件:

  1. 必須給組件設置一個name。
  2. 在一個合適的時間結束組件的遞歸,否則報超棧的錯誤。
<div id="app">
        <my-com :count="1"></my-com>
    </div>
    <script>
        Vue.component('my-com',{
            name:'myCon',
            props:{
                count:{
                    type:Number,
                    default:1
                }
            },
            template:'<div><my-com :count="count +1" v-if="count<3"></my-com>{{ count }}</div>',
        });
        new Vue({
            el:'#app',
        })
    </script>

內聯(lián)模板(少用)

給組件標簽使用inline-template特性,組件就會把它的內容當做模板,而不是當做內容分發(fā)。會替代子組件的template來顯示。

<div id="app">
    <my-com inline-template>
        <div>
            {{message}}
        </div>
    </my-com>
</div>

script

結果為:你好

<script>
        Vue.component( 'my-com',{
            // template:'<div>hello <slot>這里是默認內容</slot></div>',
            data(){
                return{
                    message:'你好'
                }
            }
        });
        new Vue({
            el:'#app',
            data:{
                message:'world'
            },
        })
    </script>

{{message}}作用域為組件內的data,有些難理解,少用吧~

異步組件

組件比較龐大時,使用異步組件

  1. 按需加載,可以節(jié)省首次加載的時間,提高速度,也算是一個性能優(yōu)化。
  2. 那么一個組件可能會被使用多次,按需加載的話也不會加載多次,第一次加載完成就會緩存下來,和webpack是一樣的,所以不用擔心
    <div id="app">
        <my-com :count="1"></my-com>
    </div>
    <script>
        Vue.component('my-com',function(resolve,reject){
            window.setTimeout(function(){
                resolve({
                    template:'<div>from 異步加載組件</div>'
                })
            },3000)
        });
        new Vue({
            el:'#app',
        })
    </script>

$nextTick

等組件渲染完后使用

  this.$nextTick( () => {
      
  });

vue 如何觀察數(shù)據(jù)變化?
并不是直接更新DOM,而是開啟一個檢查隊列,緩存在一次事件循環(huán)中,緩存中會排除重復數(shù)據(jù)來避免不必要計算或DOM的操作,在下一次循環(huán)tick中,vue才會刷新隊列,執(zhí)行實際的操作。如果使用for循環(huán)動態(tài)改變100次數(shù)據(jù),實際上只觸發(fā)1次

檢測:

vue 優(yōu)先使用promise檢測,不支持會使用HTML5新特性 Mutation Observer 的方法,都不支持采用setTimeout

x-template

前提是你沒有使用webpack

 <div id="app">
    <my-com></my-com>
    <script type="text/x-template" id="my">
        <div>...</div>
    </script>  
</div>

手動掛載實例

一般使用 new vue 創(chuàng)建實例

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

在特殊情況下也可以動態(tài)創(chuàng)建 vue 實例。

vue提供兩個API:

extend : 基礎vue 構造器,創(chuàng)建了一個子類。參數(shù)包含組件選項的對象

$mount :掛載 (有很多參數(shù),參見官網(wǎng))

    <div id="app">
        hello Vue
    </div>
    <script>
    // 用extend 定義組件內容
        const myComponent = Vue.extend({
            template:'<div> from extend </div>' 
        });
    //通過 $mount 手動掛載在指定DOM里(通過工廠函數(shù)方法),支持class和id選擇器
        new myComponent().$mount('#app');
    </script>

結果:from extend 覆蓋 hello vue

問答模塊

1.watch 與 computed 區(qū)別

watch:單純監(jiān)聽某些東西變化,執(zhí)行一些操作。

computed:根據(jù)已有的 data 或 props 的改變,來動態(tài)輸出一個內容.常見的:排序、過濾、千位運算符等計算屬性。

2.bus 怎么避免全局污染?

在 webpack 中,bus是一個bus.js文件,通過模塊化就不會全局污染。

import bus from './bus.js'
3.mixins混合

把部分vue的配置merge到實例里,如:data、methods、props、計算屬性、生命周期等內容,形成復用。

mixins:[]

組件解決UI的復用,mixins混合解決組件內部配置的復用

4.遠程搜索(需要補充)

數(shù)據(jù)過多不建議使用select數(shù)據(jù)下拉。

5.keep-alive (需要補充)

讓組件做緩存

文章內容參考:
Vue.js 實戰(zhàn)之組件篇:https://segmentfault.com/l/1500000009448056/play
說說Vue的異步組件:https://juejin.im/entry/599562f36fb9a0249716d299
vue.js官網(wǎng):https://cn.vuejs.org/v2/guide/components.html

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,565評論 6 539
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,115評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,577評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,514評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,234評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,621評論 1 326
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,641評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,822評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,380評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,128評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,319評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,879評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,548評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,970評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,229評論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,048評論 3 397
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,285評論 2 376

推薦閱讀更多精彩內容