深入理解vue組件

使用組件的細(xì)節(jié)點(diǎn)

  1. is屬性:
    有些html標(biāo)簽如table,ul,ol,select對(duì)哪些標(biāo)簽可以出現(xiàn)在其內(nèi)部是有著嚴(yán)格的要求的。
    因此當(dāng)這些標(biāo)簽內(nèi)部出現(xiàn)了自定義組件,有可能會(huì)被作為無效的內(nèi)容提升到外部,導(dǎo)致頁面渲染出錯(cuò)。
    而是用is屬性則可以解決這個(gè)問題,在子級(jí)標(biāo)簽中用is屬性來使用自定義組件。
    <table>
    <tr is="模板名稱"></tr>
    </table>

  2. 子組件中的data必須是一個(gè)函數(shù),并且返回一個(gè)對(duì)象,當(dāng)一個(gè)組件被多次使用的時(shí)候,組件間的數(shù)據(jù)不會(huì)相互影響。

Vue.component('row', {
    data:function () {
          return{
              content:'this is row'
          }
    },
    template:"<tr><td>{{content}}</td></tr>"
})
  1. 通過ref 獲取dom節(jié)點(diǎn)
<div @click="handdle" ref="hello">
    hello world
</div>

handdle:function(){
    console.log(this.$refs.hello)
}

父子組件傳值

  1. 父組件向子組件傳值

父組件通過屬性綁定將值綁定到子組件上,子組件通過 props 屬性來接收,然后子組件就可以使用父組件中傳遞過來的數(shù)據(jù)了。props是一個(gè)數(shù)組。

  1. 子組件向父組件傳值:
  • 子組件通過this.$emit()方法向父組件傳值;
  • $emit("事件名",args)第一個(gè)參數(shù)是自定義事件名,第二個(gè)參數(shù)是需要傳遞的數(shù)據(jù)
  • 父組件使用v-on監(jiān)聽子組件
  1. 單向數(shù)據(jù)流

父組件可以隨意向子組件傳遞參數(shù),子組件不可以改變父組件的數(shù)據(jù),否則會(huì)報(bào)警告。
解決辦法:要想改變父組件的參數(shù),在子組件的data屬性中拷貝一份父組件的數(shù)據(jù),然后可以對(duì)數(shù)據(jù)進(jìn)行操作。

<div id="app">
    <counter :count="1" @change="handleAdd"></counter>
    <counter :count="2" @change="handleAdd"></counter>
    <div>{{total}}</div>
</div>
<script>
    var counter = {
        props:['count'],
        data:function(){
          return{
              number:this.count
          }
        },
        template:'<div @click="handdle">{{number}}</div>',
        methods:{
            handdle:function(){
                this.number++;
                this.$emit('change',1)
            }
        }
    }
    var app = new Vue({
        el:'#app',
        data:{
          total:3
        },
        components:{
            counter:counter
        },
        methods: {
            handleAdd:function(step){
                this.total+=step
            }
        }
    })
</script>

組件參數(shù)校驗(yàn)與非props特性

  1. 簡單校驗(yàn):限定傳入的值的類型,可以是單個(gè)類型,也可以是一個(gè)數(shù)組。
props:{
  content: [String,Number]
}
  1. 復(fù)雜校驗(yàn):
props:{
 content:{
  type: String,//數(shù)據(jù)類型
  required: false,//是否是必傳
  default: 'default content',//如果沒傳值,默認(rèn)值
  validator: function(val){//自定義校驗(yàn)器,數(shù)據(jù)必須>5
    return (val.length>5)
  }
 }
}

給組件綁定原生事件

  1. 在父組件上綁定事件(如:@click.native="handleClick")
  2. 在vue實(shí)例中的methods下定義事件函數(shù)。
<child @click.native="handleClick" ></child>

傳統(tǒng)方法綁定事件:

  1. 在子組件上綁定事件
  2. 在子組件中的methods中設(shè)置相應(yīng)的事件函數(shù),并在函數(shù)中定義自定義事件函數(shù),將自定義事件函數(shù)傳給父組件(如 this.$emit('click'))
  3. 在父組件上綁定子組件methods函數(shù)中傳來的自定義函數(shù)
  4. 在父組件methods中設(shè)置對(duì)應(yīng)的事件函數(shù)

非父子組件間的傳值

  1. vuex,
  2. 發(fā)布訂閱模式(總線模式)
  • 給 Vue 類加上原型屬性 bus, 這樣每個(gè) Vue 實(shí)例都能訪問到原型屬性 bus
 Vue.prototype.bus = new Vue()
  • 利用 bus 的實(shí)例方法 $emit 觸發(fā)事件
this.bus.$emit('觸發(fā)事件', this.selfContent)
  • 再利用生命周期方法(鉤子) mounted 給 bus 綁定監(jiān)聽函數(shù), 在事件觸發(fā)時(shí)執(zhí)行
 this.bus.$on('eventName', cellback)
  • 建議使用箭頭函數(shù)做為回調(diào)函數(shù),不會(huì)影響回調(diào)函數(shù)中this的指向問題
 this.bus.$on('eventName',(msg) => {
     this.selfContent = mag;
 })

完整代碼

<div id="app">
    <child  content="Dell"></child>
    <child  content="Lee"></child>
</div>
<script>
 Vue.prototype.bus = new Vue()
    Vue.component('child',{
        data:function(){
          return{
              selfContent:this.content
          }
        },
        props:{
            content:{
                type:String,
            }
        },
        template:'<div @click="handClick">{{selfContent}}</div>',
        methods: {
            handClick:function () {
                this.bus.$emit('change',this.selfContent)
            }
        },
        mounted:function(){
            var that = this;
           this.bus.$on('change',function(msg){
             that.selfContent = msg
           })
        }
    })
    var app = new Vue({
        el:'#app',
    })
</script>

vue中使用插槽

  1. 插槽:可以使父組件很容易向子組件傳遞DOM元素
  2. 匿名插槽:父組件內(nèi)部的DOM元素,可以通過子組件的<slot></slot>標(biāo)簽渲染,slot標(biāo)簽中可以寫默認(rèn)的內(nèi)容,如果父組件中不傳遞就顯示默認(rèn)內(nèi)容
Vue.component('child',{
        template:'<div>' +
            '<slot>默認(rèn)內(nèi)容</slot>' +
            '</div>',
    })
  1. 具名插槽:有名字的插槽,父組件中為slot屬性設(shè)置值,子組件slot中使用name屬性接收父組件slot的屬性值可以實(shí)現(xiàn)具名插槽。
<div id="app">
    <body-content>
       <div class="header" slot="header">header</div>
       <div class="footer" slot="footer">footer</div>
    </body-content>
</div>
<script>
Vue.component('body-content',{
    template:'<div>' +
        '<slot name="header">默認(rèn)</slot>' +
        '<div class="content">content</div>' +
        '<slot name = "footer"></slot>' +
        '</div>'
})
    var app = new Vue({
        el:'#app',
    })
</script>
  1. 作用域插槽
  • 使用場(chǎng)景:當(dāng)子組件做循環(huán)的數(shù)據(jù)和結(jié)構(gòu)需要外部傳入時(shí)
  • 父組件中必須以
<template slot-scope='自定義'></template>

作為包裹的標(biāo)簽,slot-scope接受子組件傳遞過來的值

  • 作用是:可以使父組件靈活的控制樣式
<div id="app">
    <child>
     <template slot-scope="props">
         <h1>{{props.item}}</h1>
     </template>

    </child>
</div>
<script>
Vue.component('child',{
    data:function(){
      return{
          list:[1,2,3,4]
      }
    },
    template:"<div><ul>" +
        "<slot v-for='item of list' :item = item></slot>" +
        "</ul></div>"
})
    var app = new Vue({
        el:'#app',
    })
</script>

動(dòng)態(tài)組件與v-once指令

  1. 使用is與使用:is的區(qū)別:
    • is:如果這里使用is,is=后面跟的是字符串,就是指將當(dāng)前使用is替換為名為type的組件,
    • :is:如果使用:is,其實(shí),就是v-bind:is,:is=后面跟的就是一個(gè)JS表達(dá)式,表達(dá)式為type指向了type這個(gè)對(duì)象
  2. vue自帶的動(dòng)態(tài)標(biāo)簽
<component></component>

根據(jù)type的值變換為相應(yīng)的組件
如果點(diǎn)擊按鈕前是type=“one”則會(huì)顯示vue.component(“one”,{})這個(gè)組件
如果點(diǎn)擊前按鈕是type=“two”則會(huì)顯示vue.component(“two”,{})這個(gè)組件

<div id="app">
    <component :is="type"></component>
    <button @click="handclick">點(diǎn)擊</button>
</div>
<script>
Vue.component('child-one',{
    template:'<div>one</div>'
})
Vue.component('child-two',{
    template:'<div>two</div>'
})
    var app = new Vue({
        el:'#app',
        data:{
            type:'child-one'
        },
        methods:{
            handclick:function(){
                this.type = this.type =='child-one'?'child-two':'child-one'
            }
        }
    })

  1. v-once只對(duì)內(nèi)部渲染一次,如果模板發(fā)生變化,也不會(huì)理會(huì)
?著作權(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ù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 摘要: 搞懂Vue組件! 作者:浪里行舟 原文:詳解vue組件三大核心概念 Fundebug經(jīng)授權(quán)轉(zhuǎn)載,版權(quán)歸原作...
    Fundebug閱讀 7,306評(píng)論 0 16
  • 4-1 使用組件細(xì)節(jié)點(diǎn) 1.is的使用當(dāng)我們寫循環(huán)組件的時(shí)候,經(jīng)常給table中的trselect中的option...
    讀書的魚閱讀 970評(píng)論 0 7
  • 一、使用組件的細(xì)節(jié)點(diǎn)當(dāng)使用table、select等標(biāo)簽時(shí),組件標(biāo)簽化可能會(huì)有bug,此時(shí)應(yīng)該使用 is 接受組件...
    i高安閱讀 333評(píng)論 0 0
  • 在 Vue 中,可以使用props向子組件傳遞數(shù)據(jù)。 子組件部分: 這是 header.vue 的 HTML 部分...
    相識(shí)菩提閱讀 6,367評(píng)論 0 3
  • 夜鶯2517閱讀 128,155評(píng)論 1 9

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