1. 程式人生 > >Vue 元件 一些細節點

Vue 元件 一些細節點

細節點一、 元件定義的標籤名與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>