前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Vue进阶——组件化开发

Vue进阶——组件化开发

作者头像
matt
发布2022-10-25 16:10:28
1.2K0
发布2022-10-25 16:10:28
举报
文章被收录于专栏:CSDN迁移

Vue进阶——组件化开发

一、什么是组件化

类似微服务的软件架构,在前端开发中,一个页面的实现往往十分复杂,我们可以将一个页面划分为多个块,每个块负责相应的功能,块之间通过通信来交互。这样的前端开发方式正是组件化开发,一个页面是一个大的组件树,其下又划分有很多小的组件。这样一来,不仅降低了一次开发的难度,而且避免了重复造轮子,组件可以灵活的嵌入其他的Vue项目中进行使用。

在这里插入图片描述
在这里插入图片描述

二、组件

1. 写法

  • 注册组件的步骤 创建组件的构造器:Vue.extend() 注册组件:全局/局部 使用组件:Vue实例范围内
  • 注册组件 全局:可以在多个Vue实例下使用,Vue.conponent( , ); 局部:在实例下注册,components: 属性
代码语言:javascript
复制
<script>
	var cpnCreater = Vue.extend({
		// 反单引号
		template: `
			<div>
				<h2>Vue Component</h2>
			</div>
		`
	});
	var vm = new Vue({
		el: '#app',
		components: {
			cpn: cpnCreater
		}
	});
</script>
  • 父子组件 在父组件创建时,可以添加components: 属性,引入子组件,运行时会立刻编译完成。 注意:声明顺序会影响结果。
  • 语法糖 V2.0之后的组件注册方式封装了Vue.extend()方法,使用对象代替,简化步骤。
代码语言:javascript
复制
<script>
	// 全局注册
	Vue.component('cpn1', {
		template:`
			<div>Component1 Test</div>
		`
	});
	
	var vm = new Vue({
		el: '#app',
		// 局部组件
		components: {
			'cpn2': {
				template: `
				<div>Component2 Test</div>
			`}
		}
	});
</script>
  • 模板抽离 组件内部不能访问Vue实例的数据; 组件有属于自己的HTML模板,也有自己的数据,且规定data为函数形式(隔离各组件实例的数据域)。
代码语言:javascript
复制
// 使用<script>标签
<script id="cpnDiv" type="text/x-handlebars-template">
	// 需要包含一个根
	<div>
		{{ title }}
		Component1 Test
	</div>
</script>

// 使用<template>标签
<template id="cpnTemp">
	<div>
		Component2 Test
	</div>
</template>

<script>
	// 全局注册
	Vue.component('cpn1', {
		template: '#cpnDiv',
		data() {
			title: 'Title'
		},
		methods: {}
	});
</script>

2. 通信

  • 父子组件通信 项目中的请求数据往往放在上层,需要在下层进行展示,这就涉及到组件之间的通信。
代码语言:javascript
复制
通过props向子组件传递数据
通过事件$emit() + v-on向父组件发送消息
代码语言:javascript
复制
<div :cmovies="movies"></div>

props: ['cmovies', 'cmessage']

// String/Number/Boolean/Array/Object/Date/Function/Symbol
props: {
	cmovies: Array,
	cmessage: String,
	cinfo: {
		type: String,
		// 类型是对象或数组时,默认值必须是函数,例如:default(){return [];}
		default: 'abc',
		// required: true
	}
}

说明: Vue不支持驼峰命名,需要用-+小写来代替。

子组件不推荐修改父组件传来的值,应创建一个data进行双向绑定。

代码语言:javascript
复制
// 父传子,其中Vue实例当作父
// props属性
<body>
	<div id="app">
		<cpn :cmovies="movies"></cpn>
	</div>
	
	<template id="cpnTemp">
		<div>
			<h2>Component2 Test</h2>
			<p>{{cmovies}}</p>
			<p>{{cmessage}}</p>
		</div>
	</template>
	
	<script>
		// 子组件
		const cpn = {
			template: '#cpnTemp',
			props: {
				cmovies: Array,
				cmessage: {
					type: String,
					default: "nothing..."
				}
			},
			data() {
				return {}
			}
		};
		
		var vm = new Vue({
			el: '#app',
			data: {
				message: 'Hi',
				movies: ['1', '2', '3']
			},
			components: {
				cpn: cpn
			}
		});
	</script>
</body>


// 子传父
// v-on + v-bind
<body>
	<div id="app">
		<cpn :cmovies="movies" @item-click="cpnClick"></cpn>
	</div>
	
	<template id="cpnTemp">
		<div>
			<h2>Component2 Test</h2>
			<p>{{cmovies}}</p>
			<p>{{cmessage}}</p>
			<button v-for="item in info" @click="btnClick(item)">{{item.name}}</button>
		</div>
	</template>
	
	<script>
		// 子组件
		const cpn = {
			template: '#cpnTemp',
			props: {
				cmovies: Array,
				cmessage: {
					type: String,
					default: "nothing..."
				}
			},
			data() {
				return {
					info: [
						{id: '001', name: 'aaa'},
						{id: '002', name: 'bbb'},
						{id: '003', name: 'ccc'},
						{id: '004', name: 'ddd'},
					]
				}
			},
			methods: {
				btnClick(item) {
					// 自定义事件
					this.$emit('item-click', item);
					console.log(item);
				}
			}
		};
		
		var vm = new Vue({
			el: '#app',
			data: {
				message: 'Hi',
				movies: ['1', '2', '3']
			},
			components: {
				cpn
			},
			methods: {
				cpnClick(item) {
					console.log('cpnClick', item);
				}
			}
		});
	</script>
</body>
  • .vue文件
代码语言:javascript
复制
<template></template>
<script></script>
<style></style>
  • 双向绑定 v-model = v-bind + v-on v-model + watch(components中)进行双向绑定
代码语言:javascript
复制
watch: {
	_paraName(newValue) {
		this._paraName = newValue...;
		this.$emit();
	}
}
在这里插入图片描述
在这里插入图片描述

3. 父子组件的访问方式

  1. 父访问子:children/refs this.children[index] / let t of this.children 标签上添加ref属性,即可通过this.
  2. 子访问父:parent/root this.

三、Slot 插槽(组件扩展性)

抽取共性,保留不同。

  1. 基本使用
代码语言:javascript
复制
// 多个值会一次性替换
<slot></slot>

// 默认为按钮标签
<slot><button>按钮</button></slot>
  1. 具名插槽 Vue 2.6.0之后使用v-slot代替了slotscope-slot
代码语言:javascript
复制
<cpn>
	// 组件中使用插槽
	<template v-slot="slot1">
		<span>It's me!</span>
	</template>
</cpn>

// 定义插槽
<template id="cpn">
	<div>
		<slot name="slot1"></slot>
	</div>
</template>
  1. 编译作用域 作用域插槽 父组件替换插槽的标签,但是内容由子组件来提供
代码语言:javascript
复制
<cpn>
	// 组件中访问子组件的message值
	<template v-slot="slot1">
		<span>{{ slot1.mydata }}</span>
	</template>
</cpn>

// 定义插槽,绑定message数据
<template id="cpn">
	<div>
		<slot name="slot1" :mydata="message"></slot>
	</div>
</template>

四、模板化概念

随着前端代码量的增多,通常会将代码组织在多个js中,进行维护,但这会造成类似全局变量同名、js文件的依赖等问题。

  • 自定义模块化 将js封装在一个函数内,并定义一个变量,返回一个对象结果。每次调用时使用变量名.对象.函数/变量
  • CommonJS(还有AMD、CMD、ES6)
代码语言:javascript
复制
// CommonJS规范的导出
module.exports = { add, mul }
// CommonJS规范的导入
const { add, mul } = require('./xxx.js')

引用<script type="module">时,js内部的数据都是局部的,无法被其他js文件访问。需要增加export和import关键字。

ES6 export关键字

代码语言:javascript
复制
export {
	name, sum
};
export var name = "...";
export function sum(){...};
export class Class{...};

// 只能由一个default
export default age

ES6 import关键字

代码语言:javascript
复制
import {name, sum} from "./xxx.js";
import * as im from "./xxx.js";  // 使用:im.name

// 不需要{},且可以自己命名
import addr from "./xxx.js";
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-07-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Vue进阶——组件化开发
  • 一、什么是组件化
  • 二、组件
    • 1. 写法
      • 2. 通信
        • 3. 父子组件的访问方式
        • 三、Slot 插槽(组件扩展性)
        • 四、模板化概念
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档