欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Vue-组件相关

程序员文章站 2022-07-02 15:35:45
vue组件相关组件为什么使用组件???定义组件定义全局组件定义局部组件调用组件内的属性,跟vue实例中的属性一样,但是有些是函数形式,有些是跟vue实例一样组件的参数组件的传参-父传子组件的传参-子传父组件插槽-slot具名插槽组件分离案例---todoList组件为什么使用组件???组件复用性强,可以更改几个参数等,就可以拿到其他地方用隔离(拆分),大型项目里,每个人只需要负责一部分,等定义组件定义全局组件使用 实例化的Vue对象调用组件方法component("组件名字" { tem...

组件

为什么使用组件???

  • 组件复用性强,可以更改几个参数等,就可以拿到其他地方用
  • 隔离(拆分),大型项目里,每个人只需要负责一部分,等

定义组件

定义全局组件

  • 使用 实例化的Vue对象调用组件方法component("组件名字" { template : 组件内容})
// 使用全局调用
Vue.component("Counter",{
	template : `
		<div>
			<button>按钮</button>
		</div>
	`
})

定义局部组件

  • 在Vue实例对象中使用components属性,components : { 组件名字 : { template : 组件内容}}
new Vue({
	el : "#app",
	data : {
		
	},
	components : {
		// 注册
		Counter : {
			template : `
				<div>
					<button>按钮</button>
				</div>
			`
		}
	}
})
  • 第二种方法 先声明 后注册
var Counters = {
		template : `
			<div>
				<button>按钮</button>
			</div>
		`
}
new Vue({
	el : "#app",
	data : {
	},
	// 注册组件
	components : { Counters },
})

调用

  • 组件的调用不区分首字符大小写
<Counter></Counter>
<counter></counter>
<Counters></Counters>
<counters></counters>
  • 组件的名字如果中间有大写字母调用时使用-来链接
<Counter-Item></Counter-Item>
<counter-item></counter-item>

组件内的属性,跟vue实例中的属性一样,但是有些是函数形式,有些是跟vue实例一样

  • 组件中有,data(函数),methods,created(函数),props(值可以为数组,对象形式),template,等

组件的参数

  • 在组件中自己定义data属性,但是值是函数 data : function() { return {}} 简写 data() {return {}}
components : {
	Counters : {
		template : `
			<div>
				<button @click="num++">{{num}}</button>
			</div>
		`,
		// 组件定义的参数
		data : function() {
			return {num : 1};
		},
	}
}

组件的传参-父传子

  • 在组件中调用时传递父组件的参数,但是,子组件去接收并且更改这个传递过来的数组
  • 传入使用 :传递数据的中间量的名字="父组件的数据"
  • 接收时:使用 props : ["传递数据的中间量的名字"],这个宽泛
  • 接收时也可用:props : { "传递数据的中间量的名字" : {type : 数据类型,defalut : 默认值}},这个比较严谨
    • 子组件接收父组件的数据,如果直接更改父组件传递过来的数据时会报错,
    • 因为:子组件很多,父组件的数据就一个,如果子组件都去改父组件的数据,会引发混乱
    • 所以父组件的参数,传递是单向的,只读的,尽量避免直接修改父组件数据
    • 为了解决这个问题,可以把传递过来的数据接,收到子组件自己的数据data() {}
    • 在生命周期函数最早能接收数据的阶段开始created() {}
<div id="app">
								<!-- 这里的count就是传递数据的中间量,item就是需要传输的数据 -->
	<Counters v-for="(item,index) in list" :key="index" :count="item"></Counter>
</div>
var Counters = {
		template : `
			<div>
			<!-- 这里就可以直接修改自己的数据了,不用因为直接修改父组件的数据而引发的错误混乱 -->
				<button @click="num++">{{num}}</button>
			</div>
		`,
		data : function() {
				return {num : 1};
			},
			// 接收, 这种不是很严格
			// props : ["count"],
			
			// 接收,设置默认值
			props : {
				"count" : {type : Number,default : 0}
			},
			
			// 子组件接收父组件的数据,如果更改时会报错,
			// 因为:子组件很多,父组件的数据就一个,如果子组件都去改父组件的数据,
			// 会引发混乱
			// 所以父组件的参数,传递是单向的,只读
			// 为了解决这个问题,可以把传递过来的数据接收到子组件自己的数据中
			// 在生命周期函数最早能接收数据的阶段开始created
			created : function() {
				// 在创建结束,挂载最早的阶段,把父组件的参数赋值给子组件自己的数据
				this.num = this.count;
			}
		}
}
new Vue({
	el : "#app",
	data : {
	},
	// 注册组件
	components : { Counters },
})

组件的传参-子传父

  • 子组件想要将自己的数据传递给父组件使用:this.$emit("传递数据的事件名",传递的数据);
  • 在组件上定义传递数据的事件:@传递数据的事件名="触发事件名($event)"$event是子组件传递过来的数据
  • 父组件接收时:因为就是一个事件,所以就可以写在methods里面,写事件方法,把传递过来的数据,再赋值给父组件的数据内
<div id="app">
<!-- @numchange就是传递的事件名 ,numbers就是需要父组件去执行获取子组件传递的数据的方法 ,$event就是子组件传递的数据-->
	<Step :min="20" :max="100" :count="5" @numchange="numbers($event)"></Step>
	<Step></Step>
	<!-- 这里获取父组件的数据显示子组件数据的变化 -->
	<p v-if="numberss">{{numberss}}</p>
</div>
<!-- 目标:当组件的数据放生改变时候,通知父组件 -->
var Step = {
	template : `
		<div class="step">
			<button :disabled="num <= min" @click="cal(-1)">-</button>
			<input type="text" v-model="num" @input="check()">
			<button :disabled="num >= max" @click="cal(+1)">+</button>
		</div>
	`,
	data : function() {
		return {num : 1};
	},
	props : {
		"count" : {type : Number,default : 1},
		"min" : {type : Number,default : 1},
		"max" : {type : Number,default : 999},
		"step" : {type : Number,default : 9},
	},
	created : function() {
		this.num = this.count
	},
	methods : {
		check() {
			if(this.num <= this.min) {
				this.num = this.min;
			}
			if(this.num >= this.max) {
				this.num = this.max
			}
			// 子组件将更改的num数据,发送一个numchange事件,用于父组件接收
			this.$emit("numchange",this.num);
			// 子组件为了传递数据,发送一个numchange方法,将this.num数据,发送给父组件
		},
		cal(type) {
			this.num += this.count*type;
			this.check()
		}
	}
}
new Vue({
	el : "#app",
	// 定义父组件的数据numberss
	data : {numberss : null},
	methods : {
		// 父组件执行触发的子组件的数据的额方法,e就是$event传递过来的数据
		numbers(e) {
			// 把子组件传递过来的数据赋值给父组件上的数据
			this.numberss = e;
		}
	},
	components : {Step},
})

组件插槽-slot

  • 可以进行组件的嵌套

匿名插槽

  • <组件名> <任何标签>内容</任何标签></组件名>,这个任何标签中的内容因为有插槽的存在可以插入到了组件<slot></slot>
  • <slot></slot> 再组件中放入一个这个标签,可以将组件,标签等插入打组件内部
<div id="app">
	<h1>组件插槽</h1>
	// parent是一个组件,
	<Parent>
	// p是 加的内容,可以插入组件内部
		<p>我是组件里面的p</p>
		// parent 还是刚刚的组件,发现组件内部嵌套组件
		<Parent>
			<Parent>
				
			</Parent>
		</Parent>
	</Parent>
</div>
var Parent = {
	template : `
		<div class="parent">
			<p>parent组件里的</p>
			<slot></slot>
			<!-- slot这个标签可以插入内容 -->
		</div>
	`,
}
new Vue({
	el : "#app",
	data : {},
	components : {Parent}
})

具名插槽

  • 将内容插入到对应名字的插槽中
  • <任何标签 slot="名字"></任何标签>,需要传递的内容
  • <slot name="名字"></slot>,将对应的内容插入到与名字对应相等的地方
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
		<style type="text/css">
			* {
				margin: 0;
				padding: 0;
			}
			body {
				padding: 50px;
			}
			.model {
				background-color: rgba(0,0,0,.3);
				position: absolute;
				z-index: 1000;
				height: 100vh;
				width: 100%;
				left: 0;
				right: 0;
				top: 0;
				display: flex;
				align-items: center;
				justify-content: center;
			}
			.model-content {
				width: 400px;
				height: 300px;
				background-color: #fff;
				display: flex;
				flex-direction: column;
			}
			.model-title{
				line-height: 44px;
				background-color: #fafafa;
				display: flex;
				justify-content: space-between;
				padding-left: 15px;
			}
			.close{ width: 44px; text-align: center; color:coral;}
			.model-foot{ height: 44px; padding: 0 15px; text-align: right;}
			.model-body{flex:1}
		</style>
	</head>
	<body>
		<div id="app">
			<h1>具名插槽</h1>
			<button @click="flag = true">弹出</button>
			<Model :title="'你确定要离开吗'" :visible="flag" @close="flag=$event">
				<div slot="foot">
					<button @click="flag = false">取消</button>
					<button @click="flag = false">确定</button>
				</div>
			</Model>
		</div>
	</body>
	<script type="text/javascript">
		var Model = {
			template : `
				<div class="model" v-if="visible">
					<div class="model-content">
						<div class="model-title">
							<div class="title">{{title}}</div>
							<div class="close" @click="$emit('close',false)">×</div>
						</div>
						<div class="model-body">内容</div>
						<div class="model-foot" v-if="$slots.foot">
							<slot name="foot"></slot>
						</div>
						<div class="model-foot" v-else>
							<p @click="$emit('close',false)">确定</p>
						</div>
					</div>
				</div>
			`,
			props : {
				"title" : {type : String,default : ''},
				"visible" : {type : Boolean,default : false}
			}
		}
		new Vue({
			el : "#app",
			data : {
				flag : false
			},
			components : {Model}
		})
	</script>
</html>

组件分离案例—todoList

  • 数据在那个组件那个组件操作数据(尽量)
  • 子组件传递数据,不操作数据
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="./vue.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body>
		<div id="app">
			
			<Inp @add="add($event)"></Inp>
			<List :list="list" @del="del($event)"></List>
		</div>
	</body>
	<script type="text/javascript">
		var Item = {
			template : `
				<div>
					<input type="checkbox"  :checked="item.done">
					{{item.title}}
					<button @click="$emit('del',item)">删除</button>
				</div>
			`,
			props : {
				"item" : {type : Object,default : {}}
			}
		};
		var List = {
			template : `
				<div>
					<Item 
						v-for="(item,index) in list" 
						:item="item" 
						:key="index"
						@del="$emit('del',$event)"
					></Item>
				</div>
			`,
			props : {
				"list" : {type : Array,default : []},
			},
			components : {Item}
		};
		var Inp = {
			template : `
				<div>
					<input type="text" v-model="temp" @keydown.enter="addHd()" />
				</div>
			`,
			data : function() {
				return {temp : ""}
			},
			methods : {
				addHd() {
					this.$emit("add",this.temp);
					this.temp = '';
				}
			}
		};
		new Vue({
			el : "#app",
			data : {
				list : [
					{done : true,title : "吃饭"},
					{done : true,title : "睡觉"},
					{done : true,title : "打豆豆"}
				]
			},
			components : {List,Inp},
			methods : {
				del(e) {
					var index = this.list.indexOf(e);
					this.list.splice(index,1);
				},
				add(val) {
					this.list.unshift({
						done : false,
						title : val
					})
				}
			}
		})
	</script>
</html>

本文地址:https://blog.csdn.net/qq_34182705/article/details/106860864