Vue 学习笔记 —— 组件化开发 (三)

Vue 组件化开发

  • 一、组件注册
      • 1.1 全局组件
      • 1.2 局部组件
      • 1.3 组件注册基本注意事项
      • 1.4 props 属性值类型
  • 二、组件之间数据交互
      • 2.1 父组件向子组件传递数据
      • 2.2 子组件向父组件传递数据
      • 2.3 子组件通过自定义事件向父组件传递信息
      • 2.4 非父子组件间传值 (兄弟组件之间数据交互)
      • 2.5 组件插槽
      • 2.6 具名插槽
      • 2.7 作用域插槽

案例式驱动,每个案例一个小例子,带领大家领略

一、组件注册

1.1 全局组件

基本语法:

	<script>
		 Vue.component('组件名称', {
		 	data: '组件数据',
		 	template: '组件模板内容(HTML 标签)'
		 })
	script>

示例:

我们以一个点击按钮数据累加计算来演示组件的使用


<html>
	<head>
		<meta charset="utf-8">
		<title>组件化开发title>
	head>
	<body>
		<div id="app">
			
			<button-counter>button-counter>
			<button-counter>button-counter>
			<button-counter>button-counter>
		div>

		<script src="../vue.js">script>
		<script>
			// Vue.component('button-counter'  两种方式
			Vue.component('ButtonCounter', { 
				// 使用函数,形成一个闭包的环境,保证每个数据都是独立的。
				data() {
					return {
						count: 0
					}
				},
				// template: '',
				template: '',
				methods: {
					handle: function() {
						this.count++;
					},
				}
			})
			var app = new Vue({
				el: "#app",
				data: {

				}
			})
		script>
	body>
html>

Vue 学习笔记 —— 组件化开发 (三)_第1张图片

1.2 局部组件

我们在 Vue 实例中添加 components 属性,在这里我们就可以自定义自己的局部组件,使用方式和全局组件的差别不大


<html>
	<head>
		<meta charset="utf-8">
		<title>局部组件化开发title>
	head>
	<body>
		<div id="app">
			<component-a>component-a>
		div>
		
		<script src="../vue.js">script>
		<script>
			let ComponetA = {
				data() {
					return {
						msg: 'Hello World'
					}
				},
				template: '
{{msg}}
'
, methods: { } } var app = new Vue({ el:"#app", data:{ }, components: { 'component-a': ComponetA } })
script> body> html>

演示效果
Vue 学习笔记 —— 组件化开发 (三)_第2张图片

1.3 组件注册基本注意事项

注册基本事项:

  1. data 必须是一个函数
  2. 组件模板内容必须是单个根元素
  3. 组件模板内容可以是模板字符串 ES6语法
  4. 如果使用驼峰式命名组件,要么在使用组件得时候,只能在字符串模板中用驼峰得方式使用组件

但是在普通得模板标签中,必须使用横线的方式使用组件

1.4 props 属性值类型

  • 字符串 String
  • 数值 Number
  • 布尔值 Boolean
  • 数组 Array
  • 对象 Object

二、组件之间数据交互

2.1 父组件向子组件传递数据

  • 父组件向子组件传递数据,分为静态数据 和 动态数据(属性绑定实现)
  • 子组件接收父组件传递过来的内容,要通过 props 来接收父组件的数据

<html>
	<head>
		<meta charset="utf-8">
		<title>组件数据传递title>
	head>
	<body>
		<div id="app">
			
			<h3>父组件向子组件传递数据h3>
			<div>
				{{pmsg}}
			div>
			
			
			<h3>二、静态数据传递h3>
			
			<menu-item title="来自父组件的值">menu-item>
			
			<h3>三、动态数据传递h3>
			
			<menu-item :title="ptitle">menu-item>
			
			<menu-item :title="pmsg" content="hello">menu-item>
			
			<h3>四、短横线绑定h3>
			
			<my-menu menu-title="Hello">my-menu>
			
			
			<h3>五、数组传递h3>
			<my-array :arr="parray">my-array>
			
			<h3>六、对象传递h3>
			<my-obj :person="person">my-obj>
		div>
		
		<script src="../vue.js">script>
		<script type="text/javascript">
			Vue.component('menu-item', {
				// props 接收父组件传过来的内容
				props: ['title', 'content'],
				data() {
					return {
						msg: '子组件本身的数据'
					}
				},
				template: '
{{msg + "----" + title + "------" + content}}
'
}); Vue.component('my-menu', { props: ['menuTitle'], template: '
{{menuTitle}}
'
}); // 遍历数组 Vue.component('my-array', { props: ['arr'], template: '
  • {{item}}
'
}); Vue.component('my-obj', { props: ['person'], template: '
{{person.name}} {{person.age}}
'
}) var app = new Vue({ el:"#app", data:{ pmsg: '父组件的内容', ptitle: '动态绑定属性', parray: ['apple','orange','banana'], person: { name: 'coco', age: 18 } } })
script> body> html>

Vue 学习笔记 —— 组件化开发 (三)_第3张图片

2.2 子组件向父组件传递数据

子组件向父组件传值

props 传递数据原则,单向数据流

  1. 子组件通过自定义事件向父组件传递信息 $emit 向父组件传递数据
  2. 父组件监听子组件的事件

接下来我们以一个改变字体大小 以及 传递数组的实例来给给大家演示子组件向父最贱传递数据的流程

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>子组件向父组件传递数据</title>
	</head>
	<body>

		<div id="app">
			<!-- style 属性绑定 -->
			<div :style="{fontSize: fontSize + 'px'}">{{pmsg}}</div>
			<!-- 这个监听事件的名称必须和子组件的事件完全一致 -->
			<menu-item :parr="parr" @enlarge-text="handle"></menu-item>
		</div>

		<script src="../vue.js"></script>
		<script>
			// 子组件向父组件传值 —— 基本用法
			 Vue.component('menu-item', {
				 props: ['parr'],
				 template:`
					<div>
						<ul>
							<li :key="index" v-for="(item, index) of parr">{{item}}</li>
						</ul>
					<button @click="parr.push('lemon')">点击</button>
					<button @click="$emit('enlarge-text')">扩大父组件中字体大小</button>
					</div>
				 `
			 })
			 
			var app = new Vue({
				el: "#app",
				data: {
					pmsg: '我是父组件的信息',
					parr: ['orange','apple','banana','watermelen'],
					fontSize: 10
				},
				methods: {
					handle: function() {
						// 扩大字体大小
						this.fontSize += 5;
					}
				}
			})
		</script>
	</body>
</html>

Vue 学习笔记 —— 组件化开发 (三)_第4张图片
Vue 学习笔记 —— 组件化开发 (三)_第5张图片

2.3 子组件通过自定义事件向父组件传递信息

基本和上面一致

子组件传递的数据,在父组件中要通过 $event 来接收数据


<html>
	<head>
		<meta charset="utf-8">
		<title>子组件向父组件传递数据title>
	head>
	<body>

		<div id="app">
			<div :style="{fontSize: fontSize + 'px'}">{{pmsg}}div>
			<menu-item :parr="parr" @enlarge-text="handle($event)">menu-item>
		div>

		<script src="../vue.js">script>
		<script>
			// 子组件自定义向父组件传值 —— 基本用法
			/**
			 * props 传递数据原则,单向数据流
			 * 1. 子组件通过自定义事件向父组件传递信息  $emit
			 * 2. 父组件监听子组件的事件
			 * 3. 父组件通过 $event 获取值
			 * */
			 Vue.component('menu-item', {
				 props: ['parr'],
				 template:`
					
  • {{item}}
`
}) var app = new Vue({ el: "#app", data: { pmsg: '我是父组件的信息', parr: ['orange','apple','banana','watermelen'], fontSize: 10 }, methods: { handle: function(val) { // 扩大字体大小 this.fontSize += val; } } })
script> body> html>

Vue 学习笔记 —— 组件化开发 (三)_第6张图片

2.4 非父子组件间传值 (兄弟组件之间数据交互)

通过事件中心完成交互

Vue 学习笔记 —— 组件化开发 (三)_第7张图片
使用方式:

  1. 单独创建一个 Vue 实例
  2. 然后处理事件的监听 和 销毁
// 单独创建时间中心管理组件间的通信
var eventHub = new Vue();

// 监听事件和销毁事件
eventHub.$on('add-todo',addTodo); // 自定义事件名称  事件函数
eventHub.$off('add-tod');

// 触发事件
eventHub.$emit('add-todo',id);

示例


<html>
	<head>
		<meta charset="utf-8">
		<title>组件化开发title>
	head>
	<body>
		<div id="app">
			<div>事件销毁div>
			<div>
				<button @click="handle">点击button>
			div>
			
			<test-tom>test-tom>
			<test-jerry>test-jerry>
		div>

		<script src="../vue.js">script>
		<script>
			/**
			 * 兄弟组件传值
			 * */
			 // 提供事件中心
			var eventHub = new Vue();
			 
			Vue.component('test-tom', {
				data() {
					return {
						num: 0
					}
				},
				template: `
					
TOM:{{num}}
`
, methods: { handle: function() { // 触发兄弟组件的事件 eventHub.$emit('jerry-event',2); } }, mounted() { // 监听事件, 使用箭头函数,使用 this eventHub.$on('tom-event', (val)=> { this.num+=val; }) } }) Vue.component('test-jerry', { data() { return { num: 0 } }, template: `
JERRY:{{num}}
`
, methods: { handle: function() { // 触发兄弟组件的事件 eventHub.$emit('tom-event',1); } }, mounted() { // 监听事件, 使用箭头函数,使用 this eventHub.$on('jerry-event', (val)=> { this.num+=val; }) } }) var app = new Vue({ el: "#app", data: { }, methods: { // 事件销毁 handle: function() { eventHub.$off('tom-event'); eventHub.$off('jerry-event'); } } })
script> body> html>

Vue 学习笔记 —— 组件化开发 (三)_第8张图片

2.5 组件插槽

  • 父组件向子组件传递模板内容
  • 子组件通过插槽 slot 显示父组件中模板的数据

slot 是 vue 提供的 API,使用 slot 在子组件,我们可以在模板中插入我们想要的数据,我们还可以在 slot 中添加默认的数据


<html>
	<head>
		<meta charset="utf-8">
		<title>组件化开发title>
	head>
	<body>
		<div id="app">
			<test-box>
				<h3>我没有通过 slot,我进不来h3>
			test-box>
			<hr>
			<alert-box>
				<h3>我通过 slot 插入进来了h3>
			alert-box>
		div>

		<script src="../vue.js">script>
		<script>
			Vue.component('test-box',{
				template: `
					
没插槽的时候
`, }) Vue.component('alert-box', { template: `
有插槽的时候
`, }) var app = new Vue({ el: "#app", data: { } }) script> body> html>

Vue 学习笔记 —— 组件化开发 (三)_第9张图片

2.6 具名插槽

在一个组件中,我们可以指定多个插槽插入数据,但是为了区分这些数据,我们会设置一个 name 值来标识唯一的插槽


<html>
	<head>
		<meta charset="utf-8">
		<title>组件化开发title>
	head>
	<body>
		<div id="app">
			
			<base-layout>
				<p slot="header">标题信息p>
				<p>我是主要内容p>
				<p>我是主要内容p>
				<p slot="footer">底部信息p>
			base-layout>
				<hr />
					
			<base-layout>
				<template slot="header">
					<p>标题信息1p>
					<p>标题信息2p>
				template>
				<p>我是主要内容p>
				<p>我是主要内容p>
				<template slot="footer">
					<p>底部信息1p>
					<p>底部信息2p>
				template>
			base-layout>
		div>

		<script src="../vue.js">script>
		<script>
			Vue.component('base-layout', { 
				template: `
					
`
}) var app = new Vue({ el: "#app" })
script> body> html>

Vue 学习笔记 —— 组件化开发 (三)_第10张图片

2.7 作用域插槽

应用场景: 父组件对子组件的内容进行加工处理。

使用方式:

  1. 在子组件中设置 slot,并自定义一个属性,接收父组件的内容
  2. 父组件创建 template,通过设置 slot-scope 就可以接收到子组件的内容
  3. 然后得到数据,就可以对数据进行显示了。

<html>
	<head>
		<meta charset="utf-8">
		<title>作用域插槽title>
	head>
	<style>
		.current {
			color: orange;
		}
	style>
	<body>
		
		<div id="app">
			<first-fruit :list="list">
				
				<template slot-scope="slotProps">
					<strong v-if="slotProps.info.id == 2" class="current">
						{{slotProps.info.name}}
					strong>
					<span v-else> 
						{{slotProps.info.name}}
					span>
				template>
			first-fruit>
		div>
		<script src="../vue.js">script>
		<script type="text/javascript">
			Vue.component('first-fruit',{
				props: ['list'],
				template: `
					
  • {{item.name}}
`
}) var vm = new Vue({ el:"#app", data: { list: [{ id: 1, name: 'apple' },{ id: 2, name: 'banana' },{ id: 3, name: 'orange' }] } })
script> body> html>

你可能感兴趣的:(前端技术整合,vue,组件化)