概述
侦听器
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>
结果:
注意:
- 所有的侦听器,都应该定义在watch节点下。
- 侦听器本质是一个函数,监听那个数据的变化就将那个数据的变量名作为方法名。
- 侦听器有两种格式:函数格式、对象格式。
- 侦听器可以带参数拿到新值和旧值。
- 方法形式的侦听器无法打开页面后自动调用,但是对象形式的可以通过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>
结果:
注意:
- 方法格式的帧听器无法监听对象的属性变化。当对象的属性发生变化时,侦听器不会触发。
- 对象格式的格式的侦听器可以通过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>
结果:
注意:
- 所有计算属性都定义在computed节点下。
- 计算属性,定义时是方法,调用时是属性。
- 计算属性所依赖的值发生变化后,计算属性会重新计算。
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>
结果:
注意:
- props自定义属性,运行使用者通过自定义属性,为当前组件指定初始值。
- props的数据可以直接在模板中使用。
- vue规定组件中props是只读的,不建议直接修改props的数据,否则会报错。要是想修改props的值,可以把props的值转存到data。
- v-bind指令和props一起使用,引号里的值变为js代码。如果是“2”,2由字符串类型转为数值类型。
- 可以设置自定义属性的默认值,当用户没有传入值,显示默认值。
- 可以指定自定义属性必须为数字类型,否则会报错。
- 可以设置属性必填项属性,不填会报错。
样式冲突
默认情况下,写.vue组件中的样式会全局生效,因此很容易造成多个组件之间的样式冲突问题。
导致组件之间样式冲突的原因:
- 单页面程序中,所有组件的DOM结构,都是基于唯一的index.html。
- 每个组件的样式,都会影响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>
结果:
注意:
- /deep/ .a p代表[data-v-9ea40744] .a p 。
- /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实现数据共享。
步骤:
- 创建eventBus.js模块,并向外共享一个Vue的实例对象。
- 数据发送方,调用bus.$emit(‘事件名称’,要发送的数据)触发自定义事件。
- 数据接收方,调用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样式冲突组件之间的数据共享所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复