1. 程式人生 > >Vue.js的組件化思想--上

Vue.js的組件化思想--上

str 多個 文件 內容 生成 調用 單獨使用 只需要 one

Vue.js的組件化思想--上

一、Vue中的組件

Vue視圖層的靈魂 — 組件化

組件(Component)是 Vue.js 最強大的功能之一;

組件可以擴展 HTML 元素,封裝可重用的代碼;

在較高層面上,組件是自定義元素, Vue.js 的編譯器為它添加特殊功能。在有些情況下,組件也可以是原生 HTML 元素的形式,以 is 特性擴展。

二、全局組件的創建和註冊

全局組件-步驟:1.創建組件Vue.extend(),指定組件的名稱--2.註冊組件Vue.component()--3.掛載作用域下實例化

案例代碼:

<!DOCTYPE html
> <html lang="en"> <head> <meta charset="UTF-8"> <title>全局組件</title> </head> <body> <div id="app"> <my-date></my-date> <my-date></my-date> </div> <hr> <div id="app1"> <my-date></
my-date> <my-date></my-date> </div> <script_top src="js/vue.js"></script_top> <script_top> // 全局組件-步驟:1.創建組件Vue.extend(),指定組件的名稱--2.註冊組件Vue.component()--3.掛載作用域下實例化 // 1.創建組件 let Profile = Vue.extend({ template:` <div> <
input type=date> <p>今天已經是夏天了</p> </div>` }); // 2.註冊組件,指定組件的名稱 Vue.component(my-date,Profile); // 3.掛載作用域下實例化 new Vue({ el:#app, data:{ } }); new Vue({ el:#app1, data:{ } }) </script_top> </body> </html>

運行結果:技術分享圖片

調用Vue.extend()創建的是一個組件構造器,構造器有一個選項對象,選項對象的template屬性用於定義組件要渲染的HTML;

調用Vue.component()註冊組件時,需要提供2個參數:組件的標簽名 和 組件構造器;註冊的組件要掛載到某個Vue實例下,否則它不會生效;

Vue.extend() 和 Vue.component():由於 Vue 本身是一個構造函數,Vue.extend() 是一個類繼承方法,它用來創建一個 Vue 的子類並返回其構造函數;

而Vue.component() 的作用在於:建立指定的構造函數與 ID 字符串間的關系,從而讓 Vue.js 能在模板中使用它;直接向 Vue.component() 傳遞 options 時,它會在內部調用 Vue.extend()。

三、局部組件的創建和註冊

案例代碼:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
<div id="app">
    <my_date></my_date>
    <my_color></my_color>
</div>
<script_top src="js/vue.js"></script_top>
<script_top>
	// 1.創建組件
	let Profile = Vue.extend({
		template:`
			<div>
				<input	type=‘date‘>
				<p>今天已經是夏天了</p>
			</div>`
	});

	// 可以擁有多個局部組件
	let Profile2 = Vue.extend({
		template:`
			<div>
				<input	type=‘color‘>
				<p我是一個色板</p>
			</div>`
	});

	new Vue({
		el:‘#app‘,
		// 2.註冊組件,指定組件的名稱.
		// 註意:局部組件一定要加s
		components:{
			‘my_date‘:Profile,
			‘my_color‘:Profile2
		}
	})
</script_top>
</body>
</html>

  

運行結果:技術分享圖片

局部組件只能在局部作用域調用:否則會報錯!

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>局部組件只能在局部作用域調用</title>
</head>
<body>
<div id="app">
    <my_date></my_date>
    <my_color></my_color>
</div>
<hr>
<div id="app1">
    <my_date></my_date>
    <my_color></my_color>
</div>
<script_top src="js/vue.js"></script_top>
<script_top>
	// 1.創建組件
	let Profile = Vue.extend({
		template:`
			<div>
				<input	type=‘date‘>
				<p>今天已經是夏天了</p>
			</div>`
	});

	// 可以擁有多個局部組件
	let Profile2 = Vue.extend({
		template:`
			<div>
				<input	type=‘color‘>
				<p我是一個色板</p>
			</div>`
	});

	new Vue({
		el:‘#app‘,
		// 2.註冊組件,指定組件的名稱.
		// 註意:局部組件一定要加s
		components:{
			‘my_date‘:Profile,
			‘my_color‘:Profile2
		}
	})
	// 局部組件只能在局部作用域調用
	new Vue({
		el:‘#app1‘
	})
</script_top>
</body>
</html>

  

運行結果:技術分享圖片

四、另一種組件創建和註冊方式

直接通過Vue.component註冊或獲取全局組件,主要體現在以下幾種方式:

// 註冊組件,傳入一個擴展過的構造器

Vue.component(‘my-component‘, Vue.extend({ /* ... */ }))

// 註冊組件,傳入一個選項對象(自動調用 Vue.extend)

Vue.component(‘my-component‘, { /* ... */ })

// 獲取註冊的組件(始終返回構造器)

var MyComponent = Vue.component(‘my-component‘)

4.1 自定義全局組件

第二種寫法。(第一步、第二步寫在一起。)

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>全局組件</title>
</head>
<body>
<div id="app">
    <my-date></my-date>	
    <my-date></my-date>	
</div>
<hr>
<div id="app1">
    <my-date></my-date>	
    <my-date></my-date>	
</div>

<script_top src="js/vue.js"></script_top>
<script_top>
// 全局組件-步驟:1.創建組件Vue.extend(),指定組件的名稱--2.註冊組件Vue.component()--3.掛載作用域下實例化
	// 1.創建組件
	// 2.註冊組件,指定組件的名稱
	Vue.component(‘my-date‘,{
		// 模板選項
		template:`
			<div>
				<input	type=‘date‘>
				<p>今天已經是夏天了</p>
			</div>`
	});
	



	new Vue({
		el:‘#app‘,
		data:{
		}
	});
	new Vue({
		el:‘#app1‘,
		data:{
		}
	})
</script_top>
</body>
</html>

技術分享圖片

4.2 自定義局部組件

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>局部組件寫法2</title>
</head>
<body>
<div id="app">
    <my_date></my_date>
    <my_color></my_color>
</div>
<hr>
<div id="app1">
    <my_date></my_date>
    <my_color></my_color>
</div>
<script_top src="js/vue.js"></script_top>
<script_top>
	new Vue({
		el:‘#app‘,
		// 2.註冊組件,指定組件的名稱.
		// 註意:局部組件一定要加s
		components:{
			‘my_date‘:{
				template:`
					<div>
						<input	type=‘date‘>
						<p>今天已經是夏天了</p>
					</div>`
			},
			‘my_color‘:{
				template:`
					<div>
						<input	type=‘color‘>
						<p我是一個色板</p>
					</div>`
			}
		}
	})
</script_top>
</body>
</html>

  

技術分享圖片

五、父子組件

組件意味著協同工作,通常父子組件會是這樣的關系:組件 A 在它的模版中使用了組件 B 。

最簡單的父子組件:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
<div id="app">
    <parent></parent>

    <child></child>	
</div>
<script_top src="js/vue.js"></script_top>
<script_top>
	// 1.子組件構造器
	let Child1 = Vue.extend({
		template:`<img src="./img/1.jpg" width="200" />`,
	});

	let Child2 = Vue.extend({
		template:`<p>我是美女哦!</p>`,
	});
	// 全局組件component
	Vue.component(‘child‘,Child1);
	// 2.父組件構造器  
	Vue.component(‘parent‘,{
		//局部組件components
		components:{
			‘my_child1‘:Child1,
			‘my_child2‘:Child2
		},
		template:`
			<div>
				<my_child1></my_child1>
				<my_child2></my_child2>		
			</div>
		`
	});


	new Vue({
		el:‘#app‘,
	})
</script_top>
</body>
</html>

  運行結果:

技術分享圖片

在父子組件組合使用中要註意以下一些問題:
1.沒有實例化的子組件不能拿出來單獨使用!
2.在父標簽內部嵌套子標簽!
因為在父標簽一旦生成真實的DOM,其內部的子標簽就會被解析成為普通的HTML標簽來執行,而且<child-component>不是標準的HTML標簽,會被瀏覽器過濾掉。

六、在組件上綁定Class和Style

數據綁定一個常見需求是操作元素的 class 列表和它的內聯樣式。因為它們都是屬性 ,我們可以用v-bind 處理它們:只需要計算出表達式最終的字符串。

而且,把 v-bind 用於 class 和 style 時,表達式的結果類型除了字符串之外,還可以是對象或數組。

案例代碼:

技術分享圖片

七、template和script_top標簽

盡管在上面組件的組件註冊的方式已經很簡單,但是在template選項中拼接HTML的標簽還是不符合常規的編程習慣,而且HTML元素和js代碼混雜在一起造成了很大的耦合性。

那麽,template和script_top標簽可以幫助我們將定義在JS中的HTML模板分離出來。

註意: 兩種註冊方式效果一樣,官方建議用第一種。

(1)使用template標簽註冊組件:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
<div id="app">
    <my-div></my-div>
</div>

<hr> 

<template id="my_div">
		<div>我是貝貝</div>
</template>

<script_top src="js/vue.js"></script_top>
<script_top>

	// 1.實例化組件  全局組件component
	Vue.component(‘my-div‘,{
		template:‘#my_div‘
	})

	new Vue({
		el:‘#app‘,
	})
</script_top>
</body>
</html>

  

技術分享圖片

運行結果:

技術分享圖片

註意:必須只有一個出口文件,否則會報錯!

技術分享圖片

(2)使用script_top標簽註冊組件:

技術分享圖片

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
<div id="app">
    <my-div></my-div>
</div>
<script_top type="text/template" id="my_div">
	<!-- 註意必須只有一個出口文件,否則會報錯 -->
	<div>
		<img src="./img/1.jpg" width="200">
		<div>我是美女哦!</div>
	</div>
</script_top>

<script_top src="js/vue.js"></script_top>
<script_top>
	// 1.實例化組件  全局組件component
	Vue.component(‘my-div‘,{
		template:‘#my_div‘
	});
	new Vue({
		el:‘#app‘,
	})
</script_top>
</body>
</html>


註意:使用<script_top>標簽時,type指定為text/x-template,意在告訴瀏覽器這不是一段js腳本,瀏覽器在解析HTML文檔時會忽略<script_top>標簽內定義的內容。

八、掛載選項data必須是函數

使用組件時,大多數可以傳入到 Vue 構造器中的選項可以在 Vue.extend() 或Vue.component()中註冊組件時使用,但有一個重要前提: data 必須是函數

下面代碼會出現的問題:

技術分享圖片

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
<div id="app">
    <my-div></my-div>
</div>
<script_top type="text/template" id="my_div">
	<!-- 註意必須只有一個出口文件,否則會報錯 -->
	<div>
		<img src="./img/1.jpg" width="200">
		<p>我是美女哦!</p>
		<p>{{message}}</p>
	</div>
</script_top>

<script_top src="js/vue.js"></script_top>
<script_top>
	// 1.實例化組件  全局組件component
	Vue.component(‘my-div‘,{
		template:‘#my_div‘,
		data:{
			message:‘我的貝貝‘
		}
	});
	new Vue({
		el:‘#app‘,
	})
</script_top>
</body>
</html>

  

正確的寫法:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
<div id="app">
    <my-div></my-div>
</div>
<script_top type="text/template" id="my_div">
	<!-- 註意必須只有一個出口文件,否則會報錯 -->
	<div>
		<img src="./img/1.jpg" width="200">
		<p>我是美女哦!</p>
		<p>{{message}}</p>
	</div>
</script_top>

<script_top src="js/vue.js"></script_top>
<script_top>
	// 1.實例化組件  全局組件component
	Vue.component(‘my-div‘,{
		template:‘#my_div‘,
		/*data:{
			message:‘我的貝貝‘
		}*/
		// 掛載組件data必須是個函數。
		data(){
			return {message:‘我的貝貝‘}
		}
	});
	new Vue({
		el:‘#app‘,
	})
</script_top>
</body>
</html>

  技術分享圖片

運行結果:技術分享圖片

註意:如果data選項指向某個對象,這意味著所有的組件實例共用一個data。

我們應當使用一個函數作為 data 選項,讓這個函數返回一個新對象。

技術分享圖片

運行結果:這三個組件共享了同一個 data , 因此增加一個 counter 會影響所有組件!

技術分享圖片

解決辦法:為每個組件返回新的 data 對象來解決這個問題!

data: function () {

return {

counter: 0

}

}

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>驗證data必須是函數</title>
</head>
<body>
<div id="app">
	<!-- data必須是函數:內容不會共享,每次都是獨立的。 -->
    <my-btn></my-btn>
    <my-btn></my-btn>
    <my-btn></my-btn>
    <my-btn></my-btn>
</div>

<template id="my_btn">
	<!-- v-on @ -->
	<button @click="counter+=1">點擊次數:{{counter}}</button>
</template>

<script_top src="js/vue.js"></script_top>
<script_top>
	// 1.實例化組件
	Vue.component(‘my-btn‘,{
		template:‘#my_btn‘,
		data(){
			return {counter:0}
		}
	});

	new Vue({
		el:‘#app‘
	})
</script_top>
</body>
</html>

  

技術分享圖片

運行結果:

技術分享圖片

Vue.js的組件化思想--上