Vue.js_组件_认识和理解

组件(Component)是Vue.js最强大的功能之一。

组件可以扩展HTML元素,封装可重用的代码。学会了组件的使用,才能更好地将前面学习的知识运行起来,组件的使用使我们的项目更具有解耦性。更加符合MVVM的设计思想。

(1)基础语法

             注册一个全局组件语法:

             Vue.component(tagName,option)             其中tagName为组件名,options为配置项。

             组件是一个可以复用的Vue实例,且带有名字,所以它们和new Vue() 接收相同的选项,例如data,computed,methods等等。需要注意的是,一个组件的data选项必须是一个函数。

(2)全局组件

             定义一个名为<button-counter>的全局新组件

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>vue组件</title>
		<script type="text/javascript" src="../vue/vue.min.js" ></script>
	</head>
	<body>
		<div id="app">
			<div id="counter-event-example">
				<button-counter v-on:increment="incrementTotal"></button-counter>
				+
				<button-counter v-on:increment="incrementTotal"></button-counter>
				<p>{{total}}</p>
			</div>
		</div>
		
		<script>
			//注册全局组件
			Vue.component('button-counter',{
				template:'<button v-on:click="incrementHandler">{{counter}}</button>',
				data:function(){
					return{
						counter:0
					}
				},
				methods:{
					incrementHandler:function(){
						this.counter+=1;
						this.$emit('increment')
					}
				}
			});
			new Vue({
				el:'#counter-event-example',
				data:{
					total:0
				},
				methods:{
					incrementTotal:function(){
						this.total+=1
					}
				}
			});
			
		</script>
	</body>
	
</html>

(3)局部组件

             定义一个名为<button-counter>的局部新组件

             创建的局部组件只能在父组件内使用

<div id="app">
    <button-counter></button-counter>
</div>
 
<script>
var Child = {
  template: '<h1>自定义组件!</h1>'
}
 
// 创建根实例
new Vue({
  el: '#app',
  components: {
    // <button-counter> 将只在父模板可用
    'button-counter': Child
  }
})
</script>

(4)通过Prop向子组件传递数据

             prop是子组件用来接收父组件传递过来的数据的一个自定义属性。

             父组件的数据需要通过props把数据传给子组件,子组件需要显示的用props选项声明“prop”。

             当一个值传递给一个prop特性的时候,它就变成了那个组件实例的一个属性,能够在组件实例中访问这个值,就像是访问data中的值一样。

             一个组件默认可以拥有任意数量的prop,任何值都可以传递给任何的prop。

(5)子组件通过自定义事件向父组件发送消息

             a:子组件监听一个@click事件,<button @cilck="changeSize">改变字体大小</button>

             b:子组件声明方法

                          methods:{

                                  changeSize(){

                                               //通过$emit()方法传入事件名字,来触发自定义事件,传递父级组件

                                               this.$emit('postChangeSize')

                                   }

                          }

             c:父组件通过子组件传递来的事件名   @postChangeSize='bigChange'

                          bigChange方法在父级methods中声明

                          methods:{

                                  bigChange(){

                                       this.fontsize += 1

                                   }

                          }

组件复杂实例:(先声明子组件,再挂载子组件,最后使用子组件)

<!DOCTYPE html>
<!-- 笔记:
	1.在每一个自定义组件中  
		通过Prop向子组件传递数据时  
		每一个props属性 如title
		都是本组件可以直接调用的
	2.在v-bind:title2='title'中 
		title2是要传给下一层的属性
		title是接收本组件的属性(如:props['title'])
		
	3.通过自定义事件向父级组件发送消息
		(1)子级组件监听一个@click事件   <button @click="changeSize">改变字体大小</button>
		(2)子级组件声明方法 
			methods:{
				changeSize(){
					//通过$emit()方法传入事件名字,来触发自定义事件,传给父级组件
					this.$emit('postChangeSize')
				}
			}
		(3)父级组件通过子级组件传来的事件名  @postChangeBigSize="bigChange"  
			bigChange方法在父级methods中声明
				methods:{
					bigChange(){
						this.fontsize += 1
					}
				}
			在style中直接使用
			v-bind:style="{fontSize:fontsize+'px'}"
		(4)
 -->
<html>
	<head>
		<meta charset="utf-8">
		<title>vue组件练习</title>
		<script src="../vue/vue.min.js" type="text/javascript" charset="utf-8"></script>
		<style type="text/css">
			* {
				padding: 0;
				margin: 0;
			}

			.main {
				width: 100%;
			}

			body {
				color: #fff;
			}

			.head {
				width: 100%;
				height: 70px;
				background-color: purple;
				text-align: center;
				font-size: 20px;
				line-height: 70px;
			}

			.wrap {
				width: 100%;
				height: 600px;
			}

			.wrap .aside {
				width: 30%;
				height: 600px;
				background-color: green;
				float: left;
				/*侧边栏浮动*/
			}

			.wrap .content {
				width: 70%;
				height: 600px;
				background-color: saddlebrown;
				float: left;
				/*内容区浮动*/
			}
		</style>
	</head>
	<body>
		<div id="app">

		</div>
		<script type="text/javascript">
			/* 声明局部组件 */
			var Vheader = {
				template: `<header class="head">
				<h3>{{title2}}</h3>		<!--模板语法渲染 -->
				<span>{{count}}</span>
				<button @click='count +=1'>点击</button>
				</header>
				`,
				data() {
					return {
						count: 0
					}
				},
				props: ['title2'], <!-- props接收title -->
				methdos: {

				}
			};
			var Vaside = {
				template: `<div class="aside">侧边栏</div>`
			};
			var Vcontent = {
				template: `<div class="content">
					<ul>
						<li v-for="post in posts" v-bind:key="post.id">
							<h2>我的博客ID:{{post.id}}</h2>
							<h3>我的博客标题:{{post.title}}</h3>
							<p>我的博客内容:{{post.content}}</p>
							<hr>
						</li>	
					</ul>
					<button @click="changeBigSize">字体大小+1</button>
					<button @click="changeSmallSize">字体大小-1</button>
				</div>
				`,
				props: ['posts'],
				methods: { //声明方法
					changeBigSize() {
						//通过$emit()方法传入事件名字,来触发自定义事件
						this.$emit('postChangeBigSize', 1, 3)
					},
					changeSmallSize() {
						//通过$emit()方法传入事件名字,来触发自定义事件
						this.$emit('postChangeSmallSize')
					}
				}
			};
			/* 把组件分别挂载到入口组件中 */
			var Vmain = {
				template: `
					<div class="main" v-bind:style="{fontSize:fontsize+'px'}">
						<Vheader v-bind:title2 = 'title'></Vheader>
						<div class="wrap">
							<Vaside/>
							<!-- 绑定自定义属性和自定义事件-->
							<Vcontent v-bind:posts="appPosts" @postChangeBigSize="bigChange" @postChangeSmallSize="smallChange"/>
						</div>
					</div>
				`,
				data() {
					return {
						fontsize: 16 //默认字体大小为16
					}
				},
				components: {
					Vheader, //等价于Vheader:Vheader  可以简写
					Vaside,
					Vcontent
				},
				//自定义的属性
				props: ['title', 'appPosts'], //props中的title接收<Vmain v-bind:title = 'text'></Vmain>中的title
				methods: {
					//字体变大的方法
					bigChange(value, item) {
						this.fontsize += 1
						console.log(this.fontsize)
						console.log(value + "--" + item) //value=1  item=3
					},
					//字体变小的方法
					smallChange() {
						this.fontsize -= 1
					}
				}
			};
			new Vue({
				el: "#app",
				//第三步:使用子组件
				template: `<Vmain v-bind:title = 'text' v-bind:appPosts="posts"></Vmain>`,
				//title是属性名 text是数据属性的名字
				data: {
					//text指的是数据
					text: '就这吧',
					posts: [{
							id: 1,
							title: '标题1',
							content: '内容1'
						},
						{
							id: 2,
							title: '标题2',
							content: '内容2'
						},
						{
							id: 3,
							title: '标题3',
							content: '内容3'
						}
					]
				},
				components: {
					//第二步:声明变量,挂载子组件 可以表示组件名,value表示组件对象
					Vmain: Vmain
				}
			})
		</script>
	</body>
</html>

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值