VUE—從入門到飛起(四)

目錄

 

組件

組件創建方式

組件中的data和methods

組件切換方式

父組件向子組件傳值

父組件把方法傳遞給子組件

案例:評論添加及列表顯示

ref獲取dom和組件


組件

組件創建方式

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>創建組件1</title>
		<script src="../../../thirdlib/vue/vue.min.js"></script>
	</head>
	<body>
		<div id="app">
			<!--如果要使用組件,直接把組件的名稱以HTML標籤的形式引入到頁面中即可-->
			<!--駝峯樣式需要將字母小寫,然後用-分隔-->
			<my-com1></my-com1>
		</div>
		<script>
			//1.1使用Vue.extend來創建全局Vue組件
			/*var com1 = Vue.extend({
				//通過template屬性,指定了組件要展示的html結構
				template: '<h3>這是用Vue.extend創建的組件</h3>'
			})*/
			//1.2使用Vue.component('組建的名稱', 創建出來的組件模板對象)
			//Vue.component('myCom1', com1);
			
			//這裏也可以不用分開
			Vue.component('myCom1', Vue.extend({
				template: '<h3>這是用Vue.extend創建的組件</h3>'
			}));
			var vm = new Vue({
				el:"#app",
				data:{
					
				},
				methods:{
					
				}
			})
		</script>
	</body>
</html>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>創建組件2</title>
		<script src="../../../thirdlib/vue/vue.min.js"></script>
	</head>
	<body>
		<div id="app">
			<my-com1></my-com1>
		</div>
		<script>
			
			Vue.component('myCom1', {
				template:'<div><h3>這是直接使用Vue.component創建的組件</h3><span>123</span></div>'
			});
			
			var vm = new Vue({
				el:"#app",
				data:{
					
				},
				methods:{
					
				}
			})
		</script>
	</body>
</html>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>用template創建組件</title>
		<script src="../../../thirdlib/vue/vue.min.js"></script>
	</head>
	<body>
		<div id="app">
			<my-com1></my-com1>
		</div>
		
		<div id="app2">
			<my-com2></my-com2>
		</div>
		
		<!--在被控制的#app外面 使用template元素,定義組件的模板元素-->
		<template id="tmpl">
			<div>
				<h1>這是通過template在外部定義的組件結構,這個方式有代碼的提示</h1>
				<h4>好用</h4>
			</div>
		</template>
		<script>
			
			Vue.component('myCom1', {
				template:'#tmpl'
			});
			
			var vm = new Vue({
				el:"#app",
				data:{
				},
				methods:{
				}
			});
			var vm2 = new Vue({
				el:"#app2",
				data:{
				},
				methods:{
				},
				components:{
					//定義實例內部私有組件
					myCom2:{
						template:'#tmpl'
					}
				}
			})
		</script>
	</body>
</html>

組件中的data和methods

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>組件中data和methods</title>
		<script src="../../../thirdlib/vue/vue.min.js"></script>
	</head>
	<body>
		<div id="app">
			
			<mycom1></mycom1>
			<hr />
			<mycom1></mycom1>
			<hr />
			<mycom1></mycom1>
			<hr />
		</div>
		
		<template id="temp">
			<div>
				<input type="button" value="+1" @click="add" />
				<h3>{{ count }}</h3>
			</div>
		</template>
		<script>
			//1.組件可以有自己的data數據,
			//2.組件的data和實例的data不一樣。實例 的data是一個對象;組件中的data是一個function,並且return一個對象。
			//3.組件中的data和實例中的data使用方式完全一樣
			Vue.component('mycom1', {
				template:'#temp',
				data:function(){
					return {
						count:0
					}
				},
				methods:{
					add(){
						this.count ++;
					}
				}
			});
			
			var vm = new Vue({
				el:"#app",
				data:{
				},
				methods:{
				}
			})
		</script>
	</body>
</html>

組件切換方式

<div id="app">
	
	<a @click.prevent="flag = true" href="">登錄</a>
	<a @click.prevent="flag = false" href="">註冊</a>
	<login v-if="flag"></login>
	<regest v-else></regest>
</div>

<script>
	Vue.component('login', {
		template:'<h3>登錄組件</h3>'
	});
	Vue.component('regest', {
		template:'<h3>註冊組件</h3>'
	});
	
	var vm = new Vue({
		el:"#app",
		data:{
			flag:false
		},
		methods:{
		}
	})
</script>
<div id="app">
	<a @click.prevent="flag = 'login'" href="">登錄</a>
	<a @click.prevent="flag = 'regest'" href="">註冊</a>
	<!--Vue提供了component, 來展示對應名稱的組件-->
	<!--component是一個 佔位符 ,:is屬性 , 可以用來指定要展示的組件名稱-->
	<component :is="flag"></component>
</div>

<script>
	//組件名稱是字符串
	Vue.component('login', {
		template:'<h3>登錄組件</h3>'
	});
	Vue.component('regest', {
		template:'<h3>註冊組件</h3>'
	});
	
	var vm = new Vue({
		el:"#app",
		data:{
			flag:'login'
		},
		methods:{
		}
	})
</script>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>組件切換動畫</title>
		<script src="../../../thirdlib/vue/vue.min.js"></script>
		<style>
			.v-enter,
			.v-leave-to {
				opacity: 0;
				transform: translateX(150px);
			}
			.v-enter-active,
			.v-leave-active {
				transition: all 0.5s ease;
			}
			
		</style>
	</head>
	<body>
		<div id="app">
			<a @click.prevent="flag = 'login'" href="">登錄</a>
			<a @click.prevent="flag = 'regest'" href="">註冊</a>
			<!--Vue提供了component, 來展示對應名稱的組件-->
			<!--component是一個 佔位符 ,:is屬性 , 可以用來指定要展示的組件名稱-->
			<!--通過mode屬性設置組件切換時候的 方式-->
			<transition mode="out-in">
				<component :is="flag"></component>
			</transition>
		</div>
		
		<script>
			//組件名稱是字符串
			Vue.component('login', {
				template:'<h3>登錄組件</h3>'
			});
			Vue.component('regest', {
				template:'<h3>註冊組件</h3>'
			});
			
			var vm = new Vue({
				el:"#app",
				data:{
					flag:'login'
				},
				methods:{
				}
			})
		</script>
	</body>
</html>

父組件向子組件傳值

<div id="app">
	<!--父組件可以在引用子組件的時候,通過自定義屬性綁定的形式v-bind將數據傳遞到子組件-->
	<com1 v-bind:parentmsg="msg"></com1>
</div>

<script>
	var vm = new Vue({
		el:"#app",
		data:{
			msg:"123 父組件中的數據"
		},
		methods:{},
		components:{
			com1:{
				//結論:子組件中默認無法訪問到父組件中data中的數據和methods中的方法
				template:"<h1 @click='change'>處理這是子組件---{{ parentmsg }}</h1>",
				//data數據並不是父組件傳遞過來的,而是自身私有的
				//比如,組件通過ajax請求的數據,都可以放在data身上
				//data中的數據,都是可讀可寫的,props中的數據都是隻讀的
				data:function(){
					return {
						title:"123",
						content:"111"
					}
				},
				//組件中的所有props中的數據,都是通過父組件傳遞給子組件的
				props : [//把父組件傳遞過來的parentmsg,在props中定義一下,這樣才能使用這個數據
					'parentmsg'
				],
				methods:{
					change(){
					}
				}
			}
		}
	})
</script>

父組件把方法傳遞給子組件

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>父組件把方法傳遞給子組件</title>
		<script src="../../../thirdlib/vue/vue.js"></script>
	</head>
	<body>
		<div id="app">
			{{ msg }}
			<!--父組件向子組件傳遞方法使用的是 事件綁定機制v-on-->
			<!--這裏不用帶括號,直接將方法的引用傳給子組件-->
			<com2 v-on:func="show"></com2>
		</div>
		<template id="temp">
			<div>
				<h1>這是子組件</h1>
				<input type="button" @click="myclick" value="父組件傳遞的func方法"/>
			</div>
		</template>
		
		<script>
			var com2 = {
				template:'#temp',
				data(){
					return {
						sonmsg:{name:'小頭兒子', age:6}
					}
				},
				methods:{
					myclick(){
						//如何拿到父組件的show方法,拿到func方法
						//emit 英文原意 : 是觸發、調用的意思
						//參數依次寫在後面
						this.$emit('func', this.sonmsg, 321);
					}
				}
			}
			
			var vm = new Vue({
				el:"#app",
				data:{
					msg : null
				},
				methods:{
					show(data, data2){
						this.msg = data;
						console.log('調用了父組件身上的show方法:' + data + data2);
					}
				},
				components:{
					com2:com2
				}
			})
		</script>
	</body>
</html>

案例:評論添加及列表顯示

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>評論列表</title>
		<script src="../../../thirdlib/vue/vue.js"></script>
		<link rel="stylesheet" href="../../../thirdlib/css/bootstrap.min.css" />
	</head>
	<body>
		<div id="app">
			<cmtbox @fresh="loadComments" @test="test"></cmtbox>
			
			<ul class="list-group">
				<li v-for="item in list" :key="item.id" class="list-group-item">
					<span class="badge">{{ item.user }}</span>
					{{ item.content}}
				</li>
			</ul>
		</div>
		
		
		<template id="tmpl">
			<div>
				<div class="form-group">
					<label>評論人:</label>
					<input v-model="user" type="text" class="form-control" />
				</div>
				<div class="form-group">
					<label>評論內容:</label>
					<textarea v-model="content" class="form-control"></textarea>
				</div>
				<div class="form-group">
					<input @click="add" type="button" value="發表評論" class="btn btn-primary" />
				</div>
			</div>
		</template>
		<script>
			var commentBox = {
				template : "#tmpl",
				data(){
					return {
						user:"",
						content:""
					}
				},
				methods:{
					add(){
						var comment = {id:Date.now(), user : this.user, content:this.content};
						//從localstorage獲取所有評論
						var list = JSON.parse(localStorage.getItem('cmts') || '[]');
						list.push(comment);
						//保存最新的評論數據
						localStorage.setItem('cmts', JSON.stringify(list));
						this.user = this.content = "";
						
						//觸發父組件的刷新數據方法
						//可以同時綁定多個父組件方法
						this.$emit('fresh');
						this.$emit('test');
					}
				}
			}
			
			
			var vm = new Vue({
				el:"#app",
				data:{
					list:[
						{id:Date.now(), user:'李白', content:'天生我材必有用'},
						{id:Date.now(), user:'白居易', content:'蜀道之難'},
						{id:Date.now(), user:'江小白', content:'勸君更盡一杯酒'}
					]
				},
				methods:{
					loadComments(){
						//從本地localStorage中加載評論
						var locallist = JSON.parse(localStorage.getItem('cmts') || '[]');
						this.list = locallist;
					},
					test(){
						console.log("ok");
					}
				},
				components:{//組件
					cmtbox:commentBox
				},
				created(){
					this.loadComments();
				}
			})
		</script>
	</body>
</html>

ref獲取dom和組件

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>ref獲取dom和組件</title>
		<script src="../../../thirdlib/vue/vue.js"></script>
	</head>
	<body>
		<div id="app">
			<input type="button" ref="btn" value="獲取元素" @click="getele" />
			<h3 ref="myh3">哈哈哈</h3>
			<hr />
			<login ref="mylogin"></login>
		</div>
		
		<script>
			var login = {
				template:'<h1>登錄組件</h1>',
				data(){
					return {
						msg:"組件msg"
					}
				},
				methods:{
					show(){
						console.log("調用子組件的方法");
					}
				}
			}
			
			var vm = new Vue({
				el:"#app",
				data:{
					
				},
				methods:{
					getele(){
						//ref 是 reference 引用
						//console.log(this.$refs.myh3.innerText);
						console.log(this.$refs.mylogin.msg);
						this.$refs.mylogin.show();
					}
				},
				components:{
					login : login
				}
			})
		</script>
	</body>
</html>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章