一、在子组件中获取父组件的数据
1.通过$attr
$attrs包含的是组件没有被注册到prop上的属性,
可以将父组件没有用过的值通过v-bind直接传递给子组件
代码:
<body>
<div id="app">
<my-content :title="title" :content="content" class="aaa"></my-content>
</div>
<script>
//通过$attrs
const vm = new Vue({
el: '#app',
data: {
content: '我是内容内容内容内容内容内容内容',
title: '我是标题'
},
components: {
myContent: {
props: ['title'],
created (){
console.log(this.$attrs); //包含的这个组件没有被注册的属性,打印出来content
},
inheritAttrs: false,//如果某个属性没有被用,会直接显示在行间,设置inheritAttrs:false可以防止这种情况
//通过v-bind将$attrs传递给子组件
template: `<div>
<h3>{{title}}</h3>
<my-p v-bind="$attrs"></my-p>
</div>`,
components:{
myP: {
props:['content'],
template: `<p>{{content}}</p>`
}
}
}
}
});
</script>
</body>
如果某个属性没有被用,会直接显示在行间,
设置inheritAttrs:false可以防止这种情况。
2.通过$parent
可以在子组件里通过$parent来获取父组件的实例,
同时也可以在父组件里通过 $children来获取子组件的实例,
子组件在挂载完毕才有,所以应在生命周期的mounted里获取
但这种方法并不推荐,写起来也麻烦。
<body>
<div id="app">
<my-content :title="title" :content="content" class="aaa"></my-content>
</div>
<script>
//通过$parent
const vm = new Vue({
el: '#app',
data: {
content: '我是内容内容内容内容内容内容内容',
title: '我是标题'
},
components: {
myContent: {
// props: ['title'],
created (){
console.log(this.$parent); //打印出根实例
this.title = this.$parent.title;
},
mounted() {
console.log(this.$children);
},
inheritAttrs: false,
template: `<div>
<h3>{{title}}</h3>
<my-p></my-p>
</div>`,
components:{
myP: {
// props:['content'],
created(){
this.content = this.$parent.$parent.content;
},
template: `<p>{{content}}</p>`
}
}
}
}
});
</script>
</body>
3.通过provide和inject
在父组件上有一个属性,provide,可以写入想提供给子组件的值,并且不只是直接子组件,孙子组件也可以拿到,相当于传家宝,子组件或孙子组件可以使用inject来获取provide里的数据。
举例:
<body>
<div id="app">
<my-content :title="title" :content="content" class="aaa"></my-content>
</div>
<script>
//provide inject
const vm = new Vue({
el: '#app',
provide: {
content: '我是内容内容内容内容内容内容内容',
title: '我是标题'
},
components: {
myContent: {
inject: ['title'],
template: `<div>
<h3>{{title}}</h3>
<my-p></my-p>
</div>`,
components:{
myP: {
inject:['content'],
template: `<p>{{content}}</p>`
}
}
}
}
});
</script>
</body>
二、在父组件中获取子组件的数据
1.通过$children
$children是一个数组,因为可能有很多子组件,但 p a r e n t 是 一 个 对 象 。 这 个 在 上 面 parent是一个对象。 这个在上面 parent是一个对象。这个在上面parent的地方有提,不多写了。
2.引用 (ref)
ref引用可以放在dom上,也可以放在组件上,在实例中使用this.$refs可以获取到全部的引用。
<body>
<div id="app">
<div ref="dom">i am a dom</div>
</div>
<script>
//引用 ref 可以放到dom上,也可以放到组件上, 可以在是实例里用this.$refs拿到引用
const vm = new Vue({
el: "#app",
mounted (){
console.log(this.$refs);
console.log(this.$refs.dom);
}
});
</script>
</body>
打印结果:
如果有两个ref名一样的标签,则只会获取到后一个。
但是使用v-for循环产生的标签,则会以数组的形式获取到全部的标签
举例:
<body>
<div id="app">
<!-- 两个具有相同的ref名的dom只能获取到后一个 -->
<div ref="dom">i am a dom</div>
<div ref="dom">i am a dommmmm</div>
<!-- 通过for循环的方式 获取到的ref是一个数组, -->
<div ref="dom2" v-for="item in 5">i am a dom</div>
</div>
<script>
//引用 ref 可以放到dom上,也可以放到组件上, 可以在是实例里用this.$refs拿到引用
const vm = new Vue({
el: "#app",
mounted (){
console.log(this.$refs);
console.log(this.$refs.dom);
console.log(this.$refs.dom2);
}
</script>
</body>
输出结果:
通过组件上的ref拿到的是组件实例。
<body>
<div id="app">
<my-cmp ref="cmp"></my-cmp>
</div>
<script>
// 引用 ref 可以放到dom上,也可以放到组件上, 可以在是实例里用this.$refs拿到引用
const vm = new Vue({
el: "#app",
mounted (){
console.log(this.$refs.cmp.msg); // hello world
this.$refs.cmp.cmpFunc(); //执行了myCmp组件的method
},
components: {
myCmp: {
data (){
return {
msg : 'hello world'
}
},
methods: {
cmpFunc (){
console.log('cmp');
}
},
template: '<div>i am a compontent</div>'
}
}
});
</script>
</body>
3.监听组件事件
组件是不能感知事件的,可以通过两种方法来获取组件的事件。
(1)通过.native让组件可以感知原生的事件
<my-cmp @click.native="func"></my-cmp>
(3)$emit
<my-cmp @click="func"></my-cmp>
const vm = new Vue({
el: "#app",
methods: {
func (data){
console.log('func');
}
},
components: {
myCmp: {
props: ['func'],
data (){
return {
msg : 'hello world'
}
},
methods: {
cmpFunc (){
console.log('cmp');
},
handleClick (){
this.$emit('click', this.msg); //要触发的事件, 参数
}
},
template: `<div>i am a compontent
<button @click="handleClick">点击</button>
</div>`
}
}
});
(2)$listener
$listener可以获取到所有组件上的事件,也可以通过v-on绑定
<my-cmp @click="func" @like="like"></my-cmp>
const vm = new Vue({
el: "#app",
methods: {
func (data){
console.log('func');
},
like (){
console.log('like');
}
},
components: {
myCmp: {
props: ['func'],
data (){
return {
msg : 'hello world'
}
},
methods: {
cmpFunc (){
console.log('cmp');
},
handleClick (){
// console.log(this.$listeners);
// this.$listeners.click(this.msg);
this.$emit('click', this.msg); //要触发的事件 参数
this.$listeners.like(); // 也可以执行自定义事件
}
},
template: `<div>i am a compontent
<button @click="handleClick">点击</button>
<button v-on="$listeners">click</button>
</div>`
}
}
});