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
標籤還可以用在ul
、ol
、select
標籤中。
組件中的數據存儲
在根組件裏面,我直接要定義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.名字
時獲取到的是對應子組件的引用。