目录
5. $attrs/$listeners隔代组件传值(爷孙组件参数互传)
一、组件:
组件就是一个个vue文件。将一个网页拆成一个个模块写在不同的vue文件中。在主页面中进行拼接。
![](https://img-blog.csdnimg.cn/815a079150c64828a3dcc2bb08bd26b9.png)
二、组件目录:
我们写的组件都放到:src/componets 目录下面
我们写的组件都放到:src/componets 目录下面
三、组件的使用
组件是可以复用的
步骤:
(1)在componets目录下面定义一个vue文件;
(2)在父组件中引入子组件文件:
<script>
import content from "./components/Content.vue"
</script>
(3)在父组件中引用子组件:
components: {
conte:content----》conte:组件名称;content组件文件名
},
(4)使用:
在父组件中<template>标签中使用,因为这个标签里面才能展示
列:
<template>
<div>
<conte></conte>
</div>
</template>
四、组件中数据存放:
Vue中data必须是一个函数,而且返回值是一个对象,每次返回都是新的对象
五、父组件向子组件传值以及调用方法
1.父向子传值:props
父组件向子组件传参,通过自定义属性的方式进行传参,在子组件中使用prop定义自定义的属性,然后在父组件中通过v-bind指令把需要传递的数据绑定在子组件上,那在子组件中props里面的自定义属性可以直接使用。
props是单向数据流,传过来的props数据是不能修改的,如果要使用这个这个数据,可以定义一个props的值并返回。或者使用watch来观察props的值的变化。
父组件
<template>
//页面引入直接用
<children :arr="childrenList"></children>
</template>
<script>
//引入子页面
import children from "../views/children";
export default {
//注册
components: {
children
},
data() {
return {
// 传向子页面的值
childrenList: [],
};
},
</script>
子组件
// 某个子组件中:
export default {
props: {
arr: {
type: Array,
default:[],
}
}
}
vue中computed和watch的区别
计算属性computed :
-
支持缓存,只有依赖数据发生改变,才会重新进行计算
-
不支持异步,当computed内有异步操作时无效,无法监听数据的变化
-
computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值
-
如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed
-
如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有一个get和一个set方法,当数据变化时,调用set方法。
侦听属性watch:
-
不支持缓存,数据变,直接会触发相应的操作;
-
watch支持异步;
-
监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
-
当一个属性发生变化时,需要执行对应的操作;一对多;
-
监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其他操作,函数有两个参数,
immediate:组件加载立即触发回调函数执行,
deep: 深度监听,为了发现对象内部值的变化,复杂类型的数据时使用,例如数组中的对象内容的改变,注意监听数组的变动不需要这么做。注意:deep无法监听到数组的变动和对象的新增,参考vue数组变异,只有以响应式的方式触发才会被监听到。
2.父组件调用子组件中的方法 :ref
父组件
<template>
//页面引入直接用
<children ref="childrenref"></children>
</template>
<script>
//引入子页面
import children from "../views/children";
export default {
//注册
components: {
children
},
data() {
return {
childrenList:[]
};
},
mounted() {
tochildren(){
this.$refs.childrenref.comeFather(this.childrenList)
},
}
<script>
子组件
// 某个子组件中:
<script>
mounted() {
//写一个方法就可以了
comeFather(data){
console.log(data+"来自父亲的关爱");
},
}
<script>
3.子组件向父组件传值emit
子组件向父组件传数据使用自定义事件, vue 组件提供了一个emit(‘自定义事件名’, 传递的数据) ),子组件传递数据时,触发响应的事件函数,就会自动触发通过$emit给父组件绑定的自定义事件,自定义事件接受一个参数,参数就是子组件传递过来的数据。
父组件
<!-- 父组件 -->
<template>
<div class="test">
<test-com @childFn="parentFn"></test-com>
<br/>
子组件传来的值 : {{message}}
</div>
</template>
<script>
export default {
// ...
data() {
return {
message: ''
}
},
methods: {
parentFn(payload) {
this.message = payload;
}
}
}
</script>
子组件
<!-- 子组件 -->
<template>
<div class="testCom">
<input type="text" v-model="message" />
<button @click="click">Send</button>
</div>
</template>
<script>
export default {
// ...
data() {
return {
// 默认
message: '我是来自子组件的消息'
}
},
methods: {
click() {
this.$emit('childFn', this.message);
}
}
}
</script>
-
这样我们就基本实现了子组件向父组件发送值了
4.兄弟之间传参
兄弟组件之间的数据传递,通过eventBus来做中间的桥梁,传输方通过中间组件调用 emit 传数据,接收方通过on 接受数据,两者之间的自定义属性名保持一致。
// 传输方组件调用方式
import Bus from '@/EventBus.js'
Bus.$emit('pass-value', this.say);
// 接收方接受参数
import Bus from '@/EventBus.js'
created() {
Bus.$on('pass-value', val => {
this.sibilingValue = val;
})
}
5. $attrs/$listeners隔代组件传值(爷孙组件参数互传)
- $attrs
1.包含了父作用域中不被 prop 所识别 (且获取) 的特性绑定 (class 和 style 除外);
2.当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind=“$attrs” 传入内部组件。通常配合 interitAttrs 选项一起使用。 - $listeners
1.包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。
2.它可以通过 v-on=“$listeners” 传入内部组件。 - 简单来说:$attrs 与$listeners是两个对象,$attrs 里存放的是父组件中绑定的非 Props 属性,$listeners 里存放的是父组件中绑定的非原生事件。
爷传孙($attrs)
//爷组件
<div id="app">
<Home :msg="msg"></Home>
</div>
//父组件(父组件的操作最简单,但不做就会传不过去)
<div class="home">
<Sun v-bind="$attrs"></Sun>
</div>
//孙组件
<div class="sun">
{{ msg }}
</div>
//props直接接受
props:{ msg:String, }
孙传爷($listeners)
//爷组件
<div id="app">
<Home @setVal="setVal">></Home>
</div>
methods:{ setVal(val){ this.msg = val; } }
//父组件(父组件的操作最简单,但不做就会传不过去)
<div class="home">
<Sun v-on="$listeners"></Sun>
</div>
//孙组件
<div class="sun">
<button @click="toVal">点我</button>
</div>
methods:{ toVal(){ this.$emit("setVal",this.msg) } }
6.通过Vuex数据共享
通过Vuex存储数据, Vuex是一个专为vue.js 应用程序开发的状态管理模式, 它采用集中式存储管理数据,以相应的规则保证状态以一种可预测的方式发生改变, 一变全变,同步更新数据。
// 注册代码
const store = new Vue.Store({
state:{
count: 100
},
mutations: {
addCount(state, val = 1) {
state.count += val;
},
subCount(state, val = 1) {
state.count -= val;
}
}
})
// 组件调用
this.$store.commit('addCount'); // 加 1
this.$store.commit('subCount'); // 减 1