Vue 元件 一些細節點
阿新 • • 發佈:2018-11-05
細節點一、 元件定義的標籤名與html規範的衝突
vue 想給table 標籤中的 tr 標籤定義為一個元件,但下面這樣寫會不對:
<div id="root"> <table> <tbody> <row></row> <row></row> <row></row> </tbody> </table> </div> <script> // 全域性元件 Vue.component("row",{ template: "<tr><td>this is a row</td></tr>" }) var vm = new Vue({ el: "#root" }) </script>
哪裡不對呢?渲染的dom tr 與table 的順序變了。
這是因為 html5 規定, table 中得有 tbody, tbody 中必須有 tr. 而模版中標籤為row , 因此會出現這種問題。
解決:使用Vue 提供的 is 屬性
<div id="root"> <table> <tbody> <tr is="row"></row> <tr is="row"></row> <tr is="row"></row> </tbody> </table> </div> <script> // 全域性元件 Vue.component("row",{ template: "<tr><td>this is a row</td></tr>" }) var vm = new Vue({ el: "#root" }) </script>
同理,ul , ol, select .
細節點二、 子元件的data 與 根元件的data 是不同的
子元件data,想向根元件,屬性定義一樣,如下,是不行的。
<div id="root"> <table> <tbody> <tr is="row"></row> <tr is="row"></row> <tr is="row"></row> </tbody> </table> </div> <script> // 全域性元件 Vue.component("row",{ data: { content: "this is a row" } template: "<tr><td>{{content}}</td></tr>" }) var vm = new Vue({ el: "#root" }) </script>
在根元件中,data 才可以以物件方式定義。在非根元件中,data 只能以function 方式定義,且這個函式返回一個物件,該物件包含想要定義的資料,如下。
<div id="root">
<table>
<tbody>
<tr is="row"></row>
<tr is="row"></row>
<tr is="row"></row>
</tbody>
</table>
</div>
<script>
// 全域性元件
Vue.component("row",{
data: function(){
return {
content: "this is content"
}
},
template: "<tr><td>{{content}}</td></tr>"
})
var vm = new Vue({
el: "#root"
})
</script>
這樣設計的原因是,子元件不像根元件,子元件會被多次呼叫,因此不希望,多次呼叫的時候資料產生衝突。因此,每個子元件的資料,都是分開的,並不共享。每個子元件都有獨立的資料儲存。
細節點三、 vue 獲取dom 節點 ref
vue 不推薦操作dom,但必要的時候,需要操作獲取dom,可以使用ref
當在一個html 標籤中使用 ref 時,獲得的是這個dom 元素,可在控制檯打印出來看一下。
<div id="root">
<div ref="hhi" @click="handleClick">hello</div>
</div>
<script>
// 全域性元件
Vue.component("row",{
data: function(){
return {
content: "this is content"
}
},
template: "<tr><td>{{content}}</td></tr>"
})
var vm = new Vue({
el: "#root",
methods: {
handleClick: function(){
console.log(this.$refs.hhi);
console.log(this.$refs.hhi.innerHTML);
}
}
})
</script>
細節點四、 子元件向父元件傳值
在元件中使用 ref 獲得的將是該元件的引用,可以在控制檯打印出來看一下。
<div id="root">
<counter ref="one" @change="handleChange"></counter>
<counter ref="two" @change="handleChange"></counter>
<div>{{total}}</div>
</div>
<script>
// 全域性元件
Vue.component("counter",{
template: "<div @click='handleClick'>{{number}}</div>",
data: function(){
return {
number: 0,
nnn: 2
}
},
methods: {
handleClick: function(){
this.number ++ ;
this.$emit('change');
}
}
})
var vm = new Vue({
el: "#root",
data: {
total: 0
},
methods:{
handleChange: function(){
// 獲取的是該子元件的引用
this.total = this.$refs.one.number + this.$refs.two.number;
}
}
})
</script>