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>

 

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