0
点赞
收藏
分享

微信扫一扫

【vue2.x(四)】vue组件

MaxWen 2022-03-25 阅读 84

1. 组件概念

什么是组件化

把页面上可重用的部分封装为组件,从而方便项目的开发和维护,体现了封装的思想。

组件化的好处

提高了前端代码的复用性和灵活性,提升了开发效率和后期的可维护性。

组件开发三要素(prop,自定义事件,slot)

prop用于定义组件的属性。
自定义事件用于触发组件的事件。
slot用于组件功能的扩展。

使用组件的三个步骤

1)定义组件(创建组件)

2)注册组件

3)使用组件(编写组件标签)

2. 基本使用

1)定义组件

使用Vue.extend(options)创建,其中options和new Vue(options)中的options基本一样。

区别点:

  • 不写el;
  • data必须写成函数;
  • 使用template配置组件结构。

2)注册组件

  • 局部注册:在new Vue中增加components选项
  • 全局注册:Vue.component(‘组件名’,组件)

3)使用组件

将组件名作为标签名,直接在页面元素位置编写即可。

非单文件组件(基本不用)

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>关注微信公众号【程序员战羽】</title>
		<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body>
		<!-- 关注微信公众号【程序员战羽】,获取更多技术文章 -->
		<div id="app1">
			<!-- 3、使用组件 -->
			<my-mp></my-mp>
		</div>
		<hr >
		<div id="app2">
			<!-- 3、使用组件 -->
			<my-mp></my-mp>
			<!-- 报错 -->
			<!-- <my-blog></my-blog>  --> 
		</div>
		<hr >
		<div id="app3">
			<!-- 3、使用组件 -->
			<my-blog></my-blog>
		</div>
		<script type="text/javascript">
			//1、定义组件
			const mp = Vue.extend({
				template:`
					<div><p>本人微信公众号名称【{{name}}】</p>
					<p>{{des}}</p>
					<button @click="showName">显示微信公众号名称</button></div>
				`,
				data() {
					return {
						name:'程序员战羽',
						des:'主要分享java相关技术栈知识,欢迎关注!!!'
					}
				},
				methods:{
					showName(){
						alert(this.name)
					}
				}
			})
			
			//1、定义组件
			const myBlog = Vue.extend({
				template:`
					<div><p>本人csdn博客【{{blogName}}】</p>
					<p>{{blogDes}}</p>
					</div>
				`,
				data() {
					return {
						blogName:'和光同其尘',
						blogDes:'坚持输出原创文章,欢迎关注!!!'
					}
				},
			})
			//2、注册组件
			//全局注册
			Vue.component('my-mp',mp)
			const app1 = new Vue({
				el:'#app1'
			})
			const app2 = new Vue({
				el:'#app2'
			})
			const app3 = new Vue({
				el:'#app3',
				components:{  //局部注册
					'MyBlog':myBlog,
					// myBlog
				}
			})
		</script>
	</body>
</html>

组件嵌套

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>关注微信公众号【程序员战羽】</title>
		<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body>
		<!-- 关注微信公众号【程序员战羽】,获取更多技术文章 -->
		<div id="app">
		</div>
		<script type="text/javascript">
			//1、定义MyMp组件
			const myMp = Vue.extend({
				name:'my-mp',
				template:`
					<div><h2>本人微信公众号名称【{{name}}】</h2>
					<p>{{des}}</p>
					</div>
				`,
				data() {
					return {
						name:'程序员战羽',
						des:'主要分享java相关技术栈知识,欢迎关注!!!'
					}
				}
			})
			//定义my-blog组件
			const myBlog = Vue.extend({
				name:'my-blog',
				template:`
					<div><h2>本人csdn博客【{{blogName}}】</h2>
					<p>{{blogDes}}</p>
					<my-mp></my-mp>
					</div>
				`,
				data() {
					return {
						blogName:'和光同其尘',
						blogDes:'坚持输出原创文章,欢迎关注!!!'
					}
				},
				//注册组件
				components:{
					myMp
				}
			})
			//定义app组件
			const app = Vue.extend({
				template:`
					<div>	
						<my-blog></my-blog>
					</div>
				`,
				//注册组件
				components:{
					myBlog
				}
			})
			//创建vm
			new Vue({
				template:'<app></app>',
				el:'#app',
				//注册组件
				components:{app}
			})
		</script>
	</body>
</html>

单文件组件(常使用这种写法)

举例如下:
整体项目结构如图
在这里插入图片描述

MyBlog.vue文件

<template>
	<div>
		<p>本人csdn博客【{{blogName}}】</p>
		<p>{{blogDes}}</p>
	</div>
</template>
<script>
	 export default {
		name:'MyBlog',
		data(){
			return {
				blogName:'和光同其尘',
				blogDes:'坚持输出原创文章,欢迎关注!!!'
			}
		}
	}
</script>
<style>
	p{
		font-size: 2em;
		text-align: center;
	}
</style>

MyMp.vue文件

<template>
	<div>
		<p>本人微信公众号名称【{{name}}】</p>
		<p>{{des}}</p>
		<button @click="showName">显示微信公众号名称</button>
	</div>
</template>
<script>
	 export default {
		// name属性:当前组件名称(建议:每个单词的首字母大写)
		name:'MyMp',
		data(){   
			return {
				name:'程序员战羽',
				des:'主要分享java相关技术栈知识,欢迎关注!!!'
			}
		},
		methods: {
			showName(){
				alert(this.name)
			}
		},
	}
</script>

App.vue文件

<template>
	<div>
		<MyBlog></MyBlog>
		<MyMp></MyMp>
	</div>
</template>
<script>
	//引入组件
	import MyBlog from './MyBlog.vue'
	import MyMp from './MyMp.vue'
	export default {
		name:'App',
		components:{
			MyBlog,
			MyMp
		}
	}
</script>

index.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>组件基本使用_改进写法</title>
	</head>
	<body>
		<!-- 准备一个容器 -->
		<div id="app"></div>
		<script type="text/javascript" src="../../js/vue.js"></script>
		<script type="text/javascript" src="./main.js"></script>
	</body>
</html>

main.js

import App from './App.vue'
new Vue({
	el:'#app',
	template:`<App></App>`,
	components:{App},
})

3. 组件间传值

父组件向子组件传数据(props)

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>父组件向子组件传值</title>
		<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body>
		<!-- 
			父向子传值(prop)
			父组件: div #app
			子组件:title-component、hobbys-component 
		-->
		<div id="app">
			<!-- 静态传值 -->
			<!-- <title-component title="我的微信公众号【程序员战羽】,爱好是:"></title-component> -->
			<!-- v-bind动态传值(单个值) -->
			<title-component v-bind:title="title"></title-component>
			<!-- v-bind动态传值(数组) -->
			<hobbys-component v-for="hobby in hobbies" v-bind:hobby="hobby" v-bind:key="hobby.id"></hobbys-component>
			<!-- <hobbys-component></hobbys-component> -->
		</div>
		<script>
			// 子组件(所需要的数据title由父组件提供)
			var titleComponent = {
				props: ["title"],
				template: `<p>{{title}}</p>`
			}
			//子组件(所需要的数据hobby由父组件提供)
			var hobbysComponent = {
				template: `
	            <p>{{hobby}}</p>
	            `,
				props: ["hobby"],
				data() {
					return {}
				}
			}
			// var hobbysComponent = {
			//     // 数据是自身提供的 (hobbies)
			//     template: `<ul><li v-for='hobby in hobbies' v-bind:key='hobby.id'>{{hobby}}</li></ul>`,
			//     data() {
			//         return {
			//             hobbies: ['爬山', '看电视剧']
			//         }
			//     }
			// }
			const app = new Vue({
				el: "#app",
				components: {
					"hobbys-component": hobbysComponent,
					"title-component": titleComponent
				},
				data: {
					title: "我的微信公众号【程序员战羽】,爱好是:",
					hobbies: ['爬山', '看电视剧'], 
				}
			})
		</script>
	</body>
</html>

子组件向父组件传数据($emit)

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>子组件向父组件传值</title>
		<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body>
		<!-- 
	        子向父传值:使用事件传值$emit
			父组件:div #app
	    -->
		<div id="app">
			<!-- v-bind:通过prop给子组件传递desc的初始值 -->
			<!-- v-on监听:子组件通过$emit给父组件传递新的desc的值 -->
			<div>
				<update-desc v-bind:desc='desc' v-on:change-desc="onChangeDesc"></update-desc>
				<!-- 此种方式不用写vue实例中的methods方法 -->
				<!-- <update-desc v-bind:desc='desc' v-on:change-desc="desc=$event"></update-desc> -->
			</div>
		</div>
		<script>
			// 子组件
			Vue.component('update-desc', {
				props: ['desc'],
				template: `
	                    <div>
	                        <h3>{{ desc }}</h3>
	                        <button v-on:click='$emit("change-desc","本人csdn博客是【和光同其尘】")'>
	                            修改描述
	                        </button>
	                    </div>
	                    `
			})
			const app = new Vue({
				el: "#app",
				data: {
					desc: "本人微信公众号是【程序员战羽】"
				},
				methods: {
					onChangeDesc: function(value) {
						// 将chinesename换成传递过来的数据
						this.desc = value
					}
				}
			})
		</script>
	</body>
</html>

举报

相关推荐

0 条评论