setup

Vue2中的组件传值

父传子 $attrs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//父组件
<template>
<v-child msg="hello" school="vue2父传子"></v-child>
</template>

<script>
import vChild from "./theChild.vue"
export default {
components:{
vChild
}
}
</script>

<style>

</style>

子组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<template>
<h2>this is child</h2>
</template>

<script>
export default {
props:["msg"], //子组件通过props接收
mounted(){
console.log(this); //打印this
}
}
</script>

<style>
</style>

当子组件通过 props 接收 父组件 传过来的值时, this上的**$attrs**啥都没;

当子组件通过 props 接收 父组件 传过来的值,但并没有全部接收, this上的**$attrs**有未接收的父组件传的值;

当子组件去掉 props,即不接收父组件 传过来的值时 this上的**$attrs**有父组件传过来的值;

结论:vue2中vue实例中的**$attrs**可以捡漏父组件传过来,但props未接收的数据;

父传子Vue2

vue3中的组件传值

父传子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//父组件
<template>
<v-child msg="hello" school="父传子"></v-child>
</template>

<script>
import vChild from "./theChild.vue"
export default {
components:{
vChild,
}
}
</script>

<style>

</style>

子组件 setup 的第一个参数

setup外和2一样,得先用props接收一下,然后setup的第一个参数就是接收的父亲传来的值;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<template>
<h2>this is child</h2>
</template>

<script>
export default {
props: ["msg", "school"],
// 第一个参数是接收父组件传来的值,形参,当然也不一定叫props;
// 第二个参数是上下文 主要关注其 attrs , emit , slots属性
setup(props,context) {
console.log(props); //Proxy {msg: 'hello', school: '父传子'}
},
};
</script>

<style>
</style>

子组件 setup 的第二个参数 context;

context.attrs与2中的this.$attts一样,是捡漏的,即props没接收到的 ,就去context.attrs里面了;

1
2
3
4
5
6
7
8
9
10
export default {
props: ["msg"],
// 第一个参数是接收父组件传来的值,形参,当然也不一定叫props;
// 第二个参数是上下文 主要关注其 attrs , emit , slots属性
setup(props, context) {
// console.log(context); //上下文 主要关注其 attrs , emit , slots属性
//context.attrs 相当于vue2中的 this.$attrs 捡漏的...
console.log(context.attrs); //Proxy {school: '父传子', __vInternal: 1}
},
};

子传父

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//父组件
<template>
<v-child msg="hello" school="父传子" @lala="fsl"></v-child>
</template>

<script>
import vChild from "./theChild.vue"
export default {
components:{
vChild,
},
setup(){
const fsl=(value)=>{
console.log(`接收到了子组件传来的${value}`)
}
return{
fsl,
}
}
}
</script>

<style>
</style>

context.emit与2中的this.$emits一样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//子组件
<template>
<h2>this is child</h2>
<button @click="childToPatent">子传父</button>
</template>

<script>
export default {
props: ["msg","school"],
// 第一个参数是接收父组件传来的值,形参,当然也不一定叫props;
// 第二个参数是上下文 主要关注其 attrs , emit , slots属性
setup(props, context) {
// console.log(context); //上下文 主要关注其 attrs , emit , slots属性

const childToPatent=()=>{
context.emit("lala",666)
}
return{
childToPatent,
}
},
};
</script>

<style>
</style>

但是这样还是不行滴,会出提示的,需要在子组件中用 emits解决

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//子组件
export default {
props: ["msg","school"],
emits:["lala"],
// 第一个参数是接收父组件传来的值,形参,当然也不一定叫props;
// 第二个参数是上下文 主要关注其 attrs , emit , slots属性
setup(props, context) {
// console.log(context); //上下文 主要关注其 attrs , emit , slots属性

const childToPatent=()=>{
context.emit("lala",666)
}
return{
childToPatent,
}
},
};

传递有名字的插槽需要用template包装起来,然后用 v-slot:xxx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//父组件
<template>
<v-child>
<!-- 传递实名插槽 需要 v-slot:xxx -->
<template v-slot:qwe>
<span>123</span>
</template>

<template v-slot:abc>
<span>123</span>
</template>

</v-child>
</template>

<script>
import vChild from "./theChild.vue";
export default {
components: {
vChild,
},
};
</script>

<style>
</style>

子组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<template>
<h2>this is child</h2>
</template>

<script>
export default {
// 第一个参数是接收父组件传来的值,形参,当然也不一定叫props;
// 第二个参数是上下文 主要关注其 attrs , emit , slots属性
setup(props, context) {
// console.log(context); //上下文 主要关注其 attrs , emit , slots属性
console.log(context.slots) //Proxy {_: 1, __vInternal: 1, qwe: ƒ, abc: ƒ}
},
};
</script>

<style>
</style>