Vue学习笔记——基础语法之组件化开发

Vue学习笔记——基础语法之组件(Component)

目标:

  • 能够知道组件化开发思想
  • 能够知道组件的注册方式
  • 能够说出组件间的数据交互方式 ▲
  • 能够说出组件插槽的用法
  • 能够说出Vue调试工具的用法
  • 能够基于组件的方式实现业务功能

1. 组件化开发思想——自定义标签

  • Web Components 通过创建 封装好功能的定制元素(自定义标签)解决问题
  • 组件可以扩展 HTML 元素,封装可重用的代码

2. 组件注册

2.1 全局注册

语法:

Vue.component( ‘组件名称’,{
data:组件数据,——是一个函数 function(){ return { } }
template:组件模板内容——是字符串,字符串当中可以写vue所支持的模板语法
})

例子:

<body>
<div id="app">
	<button-counter></button-counter>
	<button-counter></button-counter>
	<button-counter></button-counter>
	<button-counter></button-counter>
	
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
//注册组件
Vue.component('button-counter',{
	data: function(){
		return {
			count:0
		}
	},
	//template:'<button @click="count++">点击了{{count}}次</button>', 这种也可以
	template:'<button @click="handle">点击了{{count}}次</button>',
	//这里也是可以有methods的
	methods:{
		handle:function(){
			this.count+=2;
		}
	}
})
var vm = new Vue({
	el:'#app',
	data:{

	},
})
</script>
2.2 组件注册注意事项
  1. data必须是一个函数, 同时这个函数要求返回一个对象
  2. 组件模板内容必须是单个根元素(很多内容的时候你一开始先用个div包一下就好了其实)

template:’<button @click=“handle”>点击了{{count}}次< /button>< button>测试< /button> ’
这样会报错,它们两个是兄弟关系,得在外层加个div才不会报错

  1. 组件模板内容可以是模板字符串的形式(可读性)
  2. 命名格式
    如果使用驼峰式命名组件,那么使用组件的时候,只能在字符串模板中用驼峰的方式使用组件,在普通的标签模板中,必须使用短横线的方式使用组件(所有单词都小写,每个单词之间用短横线连接)
2.3 局部组件注册
  • 只能在当前注册它的vue实例中使用
  • 组件的内容可以抽取到一个对象当中

例子:

<body>
<div id="app">
	<component-tom></component-tom>
	<component-a></component-a>
	<component-lili></component-lili>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
//组件的内容可以抽取到一个对象当中
var componentA = {
	data:function(){
		return {
			msg:'HelloWorld'
		}
	},
	template:'<div>{{msg}}</div>',
}
var componenttom = {
	data:function(){
		return {
			msg:'i am tom'
		}
	},
	template:'<div>{{msg}}</div>',
}

var vm = new Vue({
	el:'#app',
	data:{

	},
	components:{
		'component-a':componentA, //组件的内容可以抽取到一个对象当中
		'component-tom':componenttom,
	}
})
</script>

组件名还是有加 ’ ’ 的

3. 组件间数据交互

3.1 父组件向子组件传值

在父组件中,直接通过属性的静态方式动态绑定的属性值的方式传递给子组件,然后子组件通过props接收属性名来接收

  1. 父组件通过属性将值传递给子组件

< component-test title=‘来自父组件的值’>< /component-test>
< component-test :title=‘trans’ multi=‘nihao’>< /component-test>

  1. 子组件内部通过props接收传递过来的值

Vue.component(‘component-test’,{
props:[‘title’,‘multi’],
data:function(){
return { zmsg:‘子组件本身的数据’ }
},
template:’< div>{{zmsg + “----------”+ title + “--------”+multi}}< /div>’
})

props属性命名规则:

  • 在props中使用驼峰形式,普通模板中需要使用短横线的形式,而在字符串形式的模板中没有这个限制
3.2 子组件向父组件传值 ▲只能多悟几遍

子组件触发一个自定义事件,父组件去监听这个自定义事件

  1. 子组件通过自定义事件向父组件传递信息
    $emit(‘自定义事件的名称’,需要传递的数据)触发事件
  2. 父组件用v-on 监听子组件的事件,接收子组件传递过来的内容($event)
<cart-list :list='list' @cart-del='delCart($event)'></cart-list>

看回放叭

3.3 兄弟之间的传递
  1. 需要借助事件中心管理组件间的通信

var hub = new Vue( );

  1. 监听事件与销毁事件

hub.$on(‘监听的事件名称’,()=>{});

hub.$off(‘监听的事件名称’);

  1. 触发事件

hub.$emit( '方法名‘,传递的数据)

  • 组件内部什么时候去监听事件呢?
    mounted钩子函数
  • 什么时候触发?
    点击按钮的时候触发对应的事件
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title></title>
</head>
<body>
<div id="app">
<div>{{fmsg}}</div>
<test-tom></test-tom>
<test-jerry></test-jerry>
<button @click='handle'>销毁事件</button>
</div>
 <script type="text/javascript" src="js/vue.js"></script>	
<script type="text/javascript">
//事件中心
var hub = new Vue();
Vue.component('test-tom',{
	data:function(){
		return {
			num:0
		}
	},
	template:`
		<div>
		<div>TOM:{{num}}</div>
		<div>
		<button @click='handle'>点击</button>
		</div>
		</div>
	`,
	methods:{
		handle:function(){
			// 触发兄弟组件的事件
			hub.$emit('jerry-event',2);
		}
	},
	mounted:function(){
		hub.$on('tom-event',(val)=>{
			this.num+=val;
		})
	}
});
Vue.component('test-jerry',{
	data:function(){
		return {
			num:0
		}
	},
	template:`
		<div>
		<div>JERRY:{{num}}</div>
		<div>
		<button @click='handle'>点击</button>
		</div>
		</div>
	`,
	methods:{
		handle:function(){
			// 触发兄弟组件的事件
			hub.$emit('tom-event',1)
		}
	},
	mounted:function(){
		hub.$on('jerry-event',(val)=>{
			this.num += val;
		})
	}
});
var vm = new Vue({
	el:'#app',
	data:{
		fmsg:'父组件',
	},
	methods:{
		handle:function(){
			hub.$off('tom-event');
			hub.$off('jerry-event');

		}
	}
})
</script>
</body>
</html>

4. 组件插槽

  • 组件的最大特性就是复用性,而用好插槽能大大提高组件的可复用能力
  • 插槽内可以包含任何模板代码,包括HTML
  • 组件标签中的内容会传递给slot
    (如果没有slot,在组件标签中写了内容也不会显示)
4.1 匿名插槽
<div id="app">
<alert-box>你好哇</alert-box>
<alert-box></alert-box>

</div>
<script type="text/javascript" src="js/vue.js"></script>	
<script type="text/javascript">
Vue.component('alert-box',{
	// ① 当组件渲染的时候,这个slot元素将会被替换为组件标签中嵌套的内容
	// ② 插槽内可以包含任何模板代码,包括 HTML
	template:`
	<div>
		<strong>ERROR:</strong>
		<slot>默认内容</slot>
	</div>
	`,
})
var vm = new Vue({
	el:'#app',
	data:{

	}
})
</script>
4.2 具名插槽
  • 具名插槽的渲染顺序,完全取决于模板,而不是取决于父组件中元素的顺序。
    (下面代码就不是按顺序写的,但是渲染的时候是按模板顺序渲染)
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title></title>
</head>
<body>
<div id="app">
<alert-box>
	<div>主要内容1</div>
	<div>主要内容2</div>
	<h1 slot="header">标题内容</h1>
	<p slot="footer">底部内容</p>
</alert-box>

</div>
<script type="text/javascript" src="js/vue.js"></script>	
<script type="text/javascript">
Vue.component('alert-box',{

	template:`
	<div>
		<header>
			<slot name='header'></slot>
		</header>
		<main>
			<slot>
		</main>
		<footer>
			<slot name='footer'></slot>
		</footer>
	</div>
	`,
})
var vm = new Vue({
	el:'#app',
	data:{

	}
})
</script>
</body>
</html>
4.3 作用域插槽
  • 父组件对子组件加工处理
    (从父组件中获取到一些子组件的数据,获取数据的方式就是通过slot-scope=‘slotProps’来得到,它当中得到的值就是在子组件slot属性中所绑定的,它对应的值会被父组件获取到)

例子:
父组件动态控制哪一种水果高亮
(因为子组件一旦封装好后,后期就很少在动了,所以最好有一种办法,从父组件可以直接去决定,这就是作用域插槽所解决的问题)
在这里插入图片描述
这个列表数据是通过动态遍历的方式生成的
所以我们需要提供对应数据。
对于数据来说,我们一般是通过父组件传递过来的,所以 在父组件中要提供一份水果列表的数据。父组件通过属性绑定的方式传递给子组件 子组件通过props接收,然后遍历

<div id="app">
	<fruit-list :list='list'>
	<!-- 通过插槽传递过来的属性 子组件通过属性名传递过来数据-->
		<template slot-scope='slotProps'>
			<strong v-if='slotProps.info.id==3' class="current">{{slotProps.info.name}}</strong>
			<span v-else>{{slotProps.info.name}}</span>
		</template>
	</fruit-list>
</div>
<script type="text/javascript" src="js/vue.js"></script>	
<script type="text/javascript">
Vue.component('fruit-list',{
	props:['list'],
	template:`
		<div>
			<li :key='item.id' v-for='item in list'>
				<slot :info='item'>
					{{item.name}}
				</slot>
			</li>
		</div>
	`,
})
var vm = new Vue({
	el:'#app',
	data:{
		list:[{
			id:1,
			name:'pear',
		},{
			id:2,
			name:'orange',
		},{
			id:3,
			name:'strawberry'
		}]
	}
})
</script>

首先,在子组件的模板当中要提供一个插槽,slot中间填充我们要显示的数据,并且slot标签当中要绑定一个属性,(属性名字自定义,用来提供给父组件。属性值是你要操作的数据)
然后,从父组件的角度:要填充slot。
填充规则:在组件标签的中间提供内容,这个内容用< template>标签进行包裹,并且通过template的一个属性:slot-scope来得到子组件中传递过来的数据,数据得到后就可以进行一些控制了

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值