我是靠谱客的博主 矮小小白菜,最近开发中收集的这篇文章主要介绍Vue2.x学习20221005侦听器计算属性props样式冲突组件之间的数据共享,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

侦听器

watch侦听器允许开发者监听数据的变化,从而针对数据的变化做出特定的操作。

帧听简单数据

<template>
	<div class="home">
		<input v-model="message" />
		<input v-model="username" />
	</div>

</template>

<script>
	export default {
		//vue组件中的data不能像之前一样,不能指向一个对象
		//data必须是一个函数,数据被返回出去
		data() {
			return {
				message: 'hello feng ye',
				username: 'dyf'
			}
		},
		name: 'HomeView',
		components: {

		},
		methods: {

		},
		//所有的侦听器,都应该定义在watch节点下
		watch: {
			//侦听器本质是一个函数,监听那个数据的变化就将那个数据的变量名作为方法名
			//侦听器可以带参数拿到新值和旧值
			message(newVal, oldVal) {
				console.log(newVal, oldVal, "监听到数据的变化!")
			},
			//定于对象格式的侦听器
			//方法形式的侦听器无法打开页面后自动调用,但是对象形式的可以通过immediate: true立即调用
			username: {
				//侦听器的处理函数
				handler(newVal, oldVal) {
					console.log(newVal, oldVal, "监听到数据的变化!")
				},
				immediate: true
			}
		}
	}
</script>

结果:
在这里插入图片描述
注意:

  1. 所有的侦听器,都应该定义在watch节点下。
  2. 侦听器本质是一个函数,监听那个数据的变化就将那个数据的变量名作为方法名。
  3. 侦听器有两种格式:函数格式、对象格式。
  4. 侦听器可以带参数拿到新值和旧值。
  5. 方法形式的侦听器无法打开页面后自动调用,但是对象形式的可以通过immediate: true立即调用。

帧听对象数据

<template>
	<div class="home">
		<input v-model="info.username" />
		<input v-model="info2.username" />
	</div>

</template>

<script>
	export default {
		//vue组件中的data不能像之前一样,不能指向一个对象
		//data必须是一个函数,数据被返回出去
		data() {
			return {
				info: {
					username: 'dyf'
				},
				info2: {
					username: 'dyf'
				}
			}
		},
		name: 'HomeView',
		components: {

		},
		methods: {

		},
		
		watch: {
			
			info(newVal, oldVal) {
				console.log(newVal, oldVal, "监听到数据的input1变化!")
			},	
			info2: {
				
				handler(newVal, oldVal) {
					console.log(newVal, oldVal, "监听到数据的input2变化!")
				},
				deep: true
			}
		}
	}
</script>

结果:
在这里插入图片描述
注意:

  1. 方法格式的帧听器无法监听对象的属性变化。当对象的属性发生变化时,侦听器不会触发。
  2. 对象格式的格式的侦听器可以通过deep: true属性深度侦听对象的变化。

计算属性

计算属性指的是通过一系列计算得到的最终属性值。这个属性计算的过程可以定义为方法,自动调用。

<template>
	<div class="home">
		<input style="display: block;" v-model="r"/>
		<input style="display: block;" v-model="g"/>
		<input style="display: block;" v-model="b"/>
		<div :style="[{backgroundColor:rgb},{width:'300px'},{height:'300px'}]">
			{{rgb}}
		</div>
	</div>

</template>

<script>
	export default {
		//vue组件中的data不能像之前一样,不能指向一个对象
		//data必须是一个函数,数据被返回出去
		data() {
			return {
				r: 0,
				g: 0,
				b: 0
			}
		},
		name: 'HomeView',
		components: {

		},
		methods: {

		},
		//所有计算属性都定义在computed节点下
		//计算属性,定义时是方法,调用时是属性
		computed:{
			//rgb作为一个计算属性,被定义成了方法格式
			//最终,在这个方法中,要返回一个生成好的rgb(x,x,x)字符串
			rgb(){
				//模板字符串需要在反引号下生效
				return `rgb(${this.r},${this.g},${this.b})`;
			}
		}
	}
</script>

结果:
在这里插入图片描述
注意:

  1. 所有计算属性都定义在computed节点下。
  2. 计算属性,定义时是方法,调用时是属性。
  3. 计算属性所依赖的值发生变化后,计算属性会重新计算。

props

props是组件的自定义属性,在封装通用组件的时候,合理地使用props可以极大的提高组件的复用性。

//组件提供者
<template>
	<div class="about">
		<h1>This is an about page</h1>
		<p>{{count}}</p>
	</div>
</template>
<script>
	export default {
		//props自定义属性,运行使用者通过自定义属性,为当前组件指定初始值
		//自定义属性的名字,是封装者自己定义,合法即可
		//props的数据可以直接在模板中使用
		//vue规定组件中props是只读的,不建议直接修改props的数据,否则会报错

		//props:['init'],
		props: {
			init: {
				//设置自定义属性的默认值,当用户没有传入值,显示默认值
				default: 6,
				//指定自定义属性必须为数字类型,否则会报错
				type: Number,
				//属性必填项,不填会报错
				required: true
				
			}
		},
		data() {
			return {
				//要是想修改props的值,可以把props的值转存到data中
				count: this.init
			}
		},
		name: 'AboutView',
		components: {

		},
		methods: {

		},
	}
</script>

//组件调用者
<template>
	<div class="home">
		<AboutView init="1"></AboutView>
		<AboutView :init="1"></AboutView>
		<AboutView ></AboutView>
	</div>

</template>

<script>
	import AboutView from "@/views/AboutView.vue"
	export default {
		//vue组件中的data不能像之前一样,不能指向一个对象
		//data必须是一个函数,数据被返回出去
		data() {
			return {
				
			}
		},
		name: 'HomeView',
		components: {
			AboutView
		},
		methods: {

		},
		
	}
</script>

结果:
在这里插入图片描述

注意:

  1. props自定义属性,运行使用者通过自定义属性,为当前组件指定初始值。
  2. props的数据可以直接在模板中使用。
  3. vue规定组件中props是只读的,不建议直接修改props的数据,否则会报错。要是想修改props的值,可以把props的值转存到data。
  4. v-bind指令和props一起使用,引号里的值变为js代码。如果是“2”,2由字符串类型转为数值类型。
  5. 可以设置自定义属性的默认值,当用户没有传入值,显示默认值。
  6. 可以指定自定义属性必须为数字类型,否则会报错。
  7. 可以设置属性必填项属性,不填会报错。

样式冲突

默认情况下,写.vue组件中的样式会全局生效,因此很容易造成多个组件之间的样式冲突问题。
导致组件之间样式冲突的原因:

  1. 单页面程序中,所有组件的DOM结构,都是基于唯一的index.html。
  2. 每个组件的样式,都会影响index.html的DOM样式。

解决样式冲突的原理

添加自定义属性data-v-***解决:

<template>
	<div class="home">
		<p data-v-001>三大城市的从</p>
		<p data-v-001>vfd </p>
		<p data-v-001>fdvd</p>
		<AboutView ></AboutView>
	</div>

</template>

<script>
	import AboutView from "@/views/AboutView.vue"
	export default {
		data() {
			return {
				
			}
		},
		name: 'HomeView',
		components: {
			AboutView
		},
		methods: {

		},
		
	}
</script>
<style>
	p[data-v-001]{
		
		background-color: coral;
	}
</style>

<template>
	<div class="about">
		<h1>This is an about page</h1>
		<p>{{count}}</p>
		<p data-v-002>三大城市的从</p>
		<p data-v-002>vfd </p>
		<p data-v-002>fdvd</p>
	</div>
</template>
<script>
	export default {
			
		data() {
			return {
			
				count: 1
			}
		},
		name: 'AboutView',
		components: {

		},
		methods: {

		},
	}
</script>
<style>
	p[data-v-002]{
		
		background-color: aqua;
	}
</style>

结果:
在这里插入图片描述

scoped

用户自定义属性比较麻烦,vue通过scoped属性自动为每个标记的vue组件创建自定义属性。

<template>
	<div class="about">
		<h1>This is an about page</h1>
		<p>{{count}}</p>
		<p>123</p>
		<p>1232343 </p>
		<p>fd3433vd</p>
	</div>
</template>
<script>
	export default {
			
		data() {
			return {
			
				count: 1
			}
		},
		name: 'AboutView',
		components: {

		},
		methods: {

		},
	}
</script>
<style scoped>
	p{
		
		background-color: aqua;
	}
</style>

<template>
	<div class="home">
		<p>三大城市的从</p>
		<p>vfd </p>
		<p>fdvd</p>
		<AboutView ></AboutView>
	</div>

</template>

<script>
	import AboutView from "@/views/AboutView.vue"
	export default {
		data() {
			return {
				
			}
		},
		name: 'HomeView',
		components: {
			AboutView
		},
		methods: {

		},
		
	}
</script>
<style scoped>
	p{	
		background-color: coral;
	}
</style>

结果:
在这里插入图片描述

/deep/样式穿透

在父组件中修改子组件的样式。

//父组件
<template>
	<div class="home">
		<p>三大城市的从</p>
		<p>vfd </p>
		<p>fdvd</p>
		<AboutView class="a"></AboutView>
	</div>

</template>

<script>
	import AboutView from "@/views/AboutView.vue"
	export default {
		data() {
			return {
				
			}
		},
		name: 'HomeView',
		components: {
			AboutView
		},
		methods: {

		},
		
	}
</script>
<style scoped>
	p{	
		background-color: coral;
	}
	/deep/ .a p{
		background-color: blue;
	}
</style>

//子组件
<template>
	<div class="about">
		<h1>This is an about page</h1>
		<p>{{count}}</p>
		<p>123</p>
		<p>1232343 </p>
		<p>fd3433vd</p>
	</div>
</template>
<script>
	export default {
			
		data() {
			return {
			
				count: 1
			}
		},
		name: 'AboutView',
		components: {

		},
		methods: {

		},
	}
</script>
<style scoped>
	p{
		
		background-color: aqua;
	}
</style>

结果:
在这里插入图片描述

注意:

  1. /deep/ .a p代表[data-v-9ea40744] .a p 。
  2. /deep/代表当前vue组件自定义属性的值。

组件之间的数据共享

父子组件

父组件向子组件传递信息

利用自定义属性实现父->子传递信息

子组件向父组件传递信息

利用自定义事件

//父组件
<template>
	<div class="home">
		<AboutView @numChange="getNum"></AboutView>
	</div>

</template>

<script>
	import AboutView from "@/views/AboutView.vue"
	export default {
		data() {
			return {

			}
		},
		name: 'HomeView',
		components: {
			AboutView
		},
		methods: {
			getNum(val) {
				console.log("已经触发!", val);
			}
		},

	}
</script>

//子组件
<template>
	<div class="about">
		<h1>This is an about page</h1>
		<p>{{count}}</p>
		<button @click="add">+1</button>
	</div>
</template>
<script>
	export default {

		data() {
			return {
				count: 1
			}
		},
		name: 'AboutView',
		components: {

		},
		methods: {
			add() {
				this.count += 1;
				this.$emit('numChange',this.count);
			}
		},
	}
</script>

结果:
在这里插入图片描述

子组件定义和触发自定义事件,例如this.$emit(‘numChange’,this.count)。
父组件注册和接收被触发的事件。

兄弟组件

在vue.2.X中,兄弟组件使用EventBus实现数据共享。
在这里插入图片描述
步骤:

  1. 创建eventBus.js模块,并向外共享一个Vue的实例对象。
  2. 数据发送方,调用bus.$emit(‘事件名称’,要发送的数据)触发自定义事件。
  3. 数据接收方,调用bus.$on(‘事件名称’,事件处理函数)注册一个自定义事件。
//兄弟发送方
<template>
	<div>
       <button @click="send">发生给兄弟组件信息</button>
	</div>

</template>

<script>
	import eventBus from '@/assets/eventBus.js'
	export default {
		data() {
			return {
				message: 'hello'
			}
		},
		name: 'child_c',
		components: {
			
		},
		methods: {
			send() {
				eventBus.$emit("share",this.message)
			}
		},

	}
</script>

//兄弟接收方
<template>
	<div class="about">
		<h1>This is an about page</h1>
		<p>{{count}}</p>
		<button @click="add">+1</button>
		<p>兄弟组件共享信息:{{get}}</p>
	</div>
</template>
<script>
	import eventBus from '@/assets/eventBus.js';
	export default {

		data() {
			return {
				count: 1,
				get: null
			}
		},
		created() {
			eventBus.$on('share', val => {
				this.get = val;
				console.log(val);
			})

		},
		name: 'AboutView',
		components: {

		},
		methods: {
			add() {
				this.count += 1;
			}
		},
	}
</script>

//主组件
<template>
	<div class="home">
		<AboutView ></AboutView>
		<child></child>
	</div>

</template>

<script>
	import AboutView from "@/views/AboutView.vue"
	import child from "@/views/child.vue"
	export default {
		data() {
			return {

			}
		},
		name: 'HomeView',
		components: {
			AboutView,
			child
		},
		methods: {
			
		},

	}
</script>

结果:
在这里插入图片描述

最后

以上就是矮小小白菜为你收集整理的Vue2.x学习20221005侦听器计算属性props样式冲突组件之间的数据共享的全部内容,希望文章能够帮你解决Vue2.x学习20221005侦听器计算属性props样式冲突组件之间的数据共享所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部