組件使用中的細節點

is標籤

如何使用is標籤解決渲染中可能會出現的小bug

<div id="root">
    <table>
        <tbody>
            <row></row>
            <row></row>
            <row></row>
        </tbody>
    </table>
</div>
Vue.component('row',{
    template:'<tr><td>this is a row</td></tr>'
})
let vm = new Vue({
    el: '#root'
})

正常渲染一個組件這樣寫沒有啥問題,但是在table中會有點小bug,如下圖

正常來說3個tr應該在tbody裏面,而現在和table同級了,這是怎麼回事呢?

html5規範中,tbody裏面必須是tr標籤,否則會出錯。該怎麼解決呢?看下面代碼

<div id="root">
    <table>
        <tbody>
            <tr is="row"></tr>
            <tr is="row"></tr>
            <tr is="row"></tr>
        </tbody>
    </table>
</div>
Vue.component('row',{
    template:'<tr><td>this is a row</td></tr>'
})
let vm = new Vue({
    el: '#root'
})

這段代碼是什麼意思呢?,意思是:tbody裏面我要用一個組件,但我不能直接使用組件,所以我就寫了一個tr,我用is表示,雖然這裏寫的是tr,但實際上它是名爲row的組件。這樣寫,既能保證tr裏面顯示的使我們的組件,又能保證它符合html5的規範,程序就不會有bug了。如下圖所示:

is標籤就變成了我們想要展示的效果了。is標籤還可以用在ulolselect標籤中。

組件中的數據存儲

在根組件裏面,我直接要定義data,可以直接定義成對象的形式,不會有任何的問題。

但是當你在非根組件中子組件裏去定義data,就不能直接定義成對象了,data的定義就必須要求,後面的值必須是一個函數。同時這個函數要求返回一個對象,這個對象裏面要包含你所要的數據。

data(){
    return {
        content: 'this is content'
    }
}

在子組件裏面定義data的時候,data必須是個函數,而不能是個對象,之所有這麼設計是因爲一個子組件不像根組件只會被調用一次,每一個子組件,它的數據我不希望和其他子組件的數據產生衝突,或者說每一個子組件都應該有自己的數據,而不是和其他組件共享數據。通過一個函數來返回一個對像的目的,就讓每一個子組件都擁有一個獨立的數據存儲,這樣就不會出現多個子組件之間互相影響的情況。

ref引用

我們說 Vue 不建議我們直接在代碼中操作dom,但是在處理一些極其複雜的動畫效果時,你不操作dom,剛靠 Vue 這種數據綁定。有些時候處理不了這樣的情況,所以在某些必要的情況下,還真就得操作dom,那麼在 Vue 之中如何處理dom呢?

<div id="root">
    <div ref="hello" @click="handleClick"></div>    // ref="hello"
</div>
<script>
    let vm = new Vue({
        el: '#root',
        methods: {
            handleClick(){
                console.log('hello world')
               this.refs.hello              //點擊時獲取 
            }
        }
    })

我給這個div起一個名字ref的名字叫做hello,然後在handleClick上就可以獲取到它了。

那要是ref寫在組件上,獲取到的應該是什麼呢?

<div id="root">
    <counter ref="one" @change="handleChange"></counter>    //組件中監聽事件
    <counter ref="two" @change="handleChange"></counter>
    <div>{{total}}</div>
</div>
Vue.component('counter', {
    template: '<div @click="handleClick">{{number}}</div>',
    data() {
        return {
            number: 0
        }
    },
    methods: {
        handleClick(){
            this.number ++
            this.$emit('change')        //number 改變時,觸發 change 事件
        }
    }
})
let vm = new Vue({
    el: '#root',
    data:{
        total: 0
    },
    methods: {
        handleChange() {
            this.total = this.$refs.one.number + this.$refs.two.number
        }
    }
})

當我點擊組件時,handleClick會被觸發,number會被改變,number改變時,用this.$emit觸發change事件,counter組件中監聽change事件,this.$refs.名字獲取對應的組件,並相加,就能得到最後的total

當它寫在div這樣一個標籤上的時候,this.$refs.名字時獲取到的是標籤對應的dom元素,而當你在一個組件上去寫ref然後通過this.$refs.名字時獲取到的是對應子組件的引用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章