細節1:table(表格)中直接引用自定義組件出現的bug
如上圖,tr本應在tbody中面,現在卻是同級。造成的原因是h5規定table里必須有tbody,tbody中必須有tr,
當tbody中引入自定義組件,瀏覽器解析后就出現了上述問題
解決方法:依然在tbody中使用tr,同時使用vue的is屬性,
該屬性可理解為我想使用一個組件,但不能直接使用,雖然我這里寫的是tr,但實際使用的是自定義組件,
同時建議ul中的li, select里的option都使用is屬性,以防止上述問題的出現
DEMO
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="root"> <table> <tbody> <tr is="row"></tr> <tr is="row"></tr> <tr is="row"></tr> </tbody> </table> </div> <script> Vue.component("row", { template: "<tr><td>this is a row</td></tr>" }) var vm = new Vue({ el: '#root' }) </script> </body> </html>
細節2:子組件里面的data必須是一個函數
下面寫法data是一個對象,而不是函數,在vue根實例中(也就是父組件中)這種寫法沒有問題
若在子組件中,上述的寫法會報錯,提示data選項應該是一個函數,並且要返回一個對象
注:目的是為了讓每個實例可以維護一份被返回對象的獨立的拷貝
上面子組件data的寫法用es6如下
細節3:使用vue提供的ref屬性為元素或子組件注冊引用信息,從而操作DOM
ref為元素注冊引用操作dom
下面代碼中this指向vue根實例,$refs指根實例下所有引用,hello是設置的元素引用名字, innerHTML是獲取hello world文字信息
也可簡單理解為ref屬性幫我們獲取到某個dom節點,ref = 'dom節點的名字,可以自定義'
DEMO
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="root"> <div ref="hello" @click="handleClick">hello world</div> </div> <script> var vm = new Vue({ el: '#root', methods: { handleClick: function() { console.log(this.$refs.hello.innerHTML); } } }) </script> </body> </html>
ref為子組件注冊引用操作dom(下面示例為點擊后,計數求和)
DEMO
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <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 } }, 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> </body> </html>
細節4:子組件不能修改父組件傳遞過來的值
父組件通過屬性的形勢可以隨意給子組件傳遞值,但子組件不能修改父組件的數據,
否則會有一個警告,提示不要直接修改父組件傳遞過來的值
注:因為vue有單項數據流機制,這個機制不會讓子組件修改父組件的值
單項數據流是為了避免下面情況:
當子組件接收的不是一個基本類型(比如number,string, boolean),而是一個對象(引用類型)時,
在子組件中改變了父組件傳遞過來的值(比如下面示例代碼中子組件接收的count值),可能這個值還被其它子組件所使用,這樣其它子組件也會受影響
DEMO
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>父子組件間的數據傳遞-進階</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="root"> <counter :count='1'></counter> <counter :count='2'></counter> </div> <script> var counterTemplate = { props: ['count'], template: '<div @click="handleClick">{{count}}</div>', methods: { handleClick: function() { this.count++ } } } var vm = new Vue({ el: '#root', components: { 'counter': counterTemplate } }) </script> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>父子組件間的數據傳遞-進階</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="root"> <counter :count='1'></counter> <counter :count='2'></counter> </div> <script> var counterTemplate = { props: ['count'], data: function() { return { number: this.count } }, template: '<div @click="handleClick">{{number}}</div>', methods: { handleClick: function() { this.number++ } } } var vm = new Vue({ el: '#root', components: { 'counter': counterTemplate } }) </script> </body> </html>