组件之间的传值
1、父传子 props
2、父传子 slot
3、父传子 不建议用 attrs
4、 子传父 ref
5、子传父 emit
6、povide/inject只能在setup的时候用。
7、利用vuex和pinia去实现数据的交互
1、实现代码App.vue
javascript
<script setup>
import TestProps from './components/TestProps.vue';
import TestEmit from './components/TestEmit.vue';
import TestProvideInject from './components/TestProvideInject.vue';
import TestRef from './components/TestRef.vue';
import TestAttrs from './components/TestAttrs.vue';
import TestSlot from './components/TestSlot.vue';
import { createApp, provide, reactive, ref } from 'vue';
const mm = ref("父值 test");
const pmsg = "父值 test"
function pcallback()
{
console.log("pcallback");
}
function pEmitclicked(m)
{
console.log("pEmitclicked " + m);
}
function pclicked()
{
console.log("pclicked ");
provide("user","test1")
}
//provide() can only be used inside setup().
provide("user","test")
provide("userObj",{"a":"b"})
provide("userFunc",()=>{return "aaa"})
let testref = ref();
function prefClicked()
{
console.log("title:", testref.value.title);
console.log("msg:", testref.value.msg);
testref.value.func();
testref.value.title = "sssssss";
}
</script>
<template>
<div>
<p>父传子 props</p>
<p>子传父 emit</p>
<p> povide/inject只能在setup的时候用</p>
<p>子传父 ref</p>
<p>父传子 不建议用 attrs</p>
<p>父传子 slot</p>
</div>
<div>
<TestProps></TestProps>
<TestProps :message="pmsg"></TestProps>
<TestProps message="我是传值" :callback="pcallback"></TestProps>
</div>
<div>
<p>emit===========================</p>
<button @click="pEmitclicked">pEmitclicked</button>
<TestEmit @subemit="pEmitclicked"></TestEmit>
</div>
<div>
<p>provide/inject===========================</p>
<button @click="pclicked">provide/inject</button>
<TestProvideInject></TestProvideInject>
</div>
<div>
<p>Ref===========================</p>
<button @click="prefClicked">ref</button>
<TestRef ref="testref"></TestRef>
</div>
<div>
<p>attrs===========================</p>
<TestAttrs msg="test" msg2="2222"></TestAttrs>
</div>
<div>
<p>slot===========================</p>
<TestSlot></TestSlot>
<TestSlot> {{ mm }}</TestSlot>
<TestSlot>
<template v-slot:header>
<h1>Here header title</h1>
</template>
</TestSlot>
</div>
</template>
<style scoped>
</style>
2、TestProps.vue
javascript
<template>
<h3>props</h3>
<a>{{ msg }} : {{ message }}</a>
<button @click="callback_p">调用函数</button>
</template>
<script>
import { ref } from 'vue'
export default {
props : {
message : {
type : String,
required: true,
default : "default message ",
},
obj : { type: Object,
// 对象或数组默认值必须从一个工厂函数获取
default() {
return { message: 'hello' }
}
},
callback : {type: Function,
// 与对象或数组默认值不同,这不是一个工厂函数 ------ 这是一个用作默认值的函数
default() {
console.log("default clicked");
return 'Default function'
}
}
},
setup(props) //需要传值
{
const msg = ref("提示");
function callback_p()
{
props.callback();
}
return {msg,callback_p};
}
}
</script>
<!-- <script setup>
import { ref } from "vue";
const msg = ref("提示");
//需要自己定义props
const props = defineProps({
message : {
type : String,
required: true,
default : "default message ",
},
obj : {
type : Object
},
aryobj : {
type : Array,
default : []
},
callback : {
type : Function,
default() {
console.log("default clicked");
return "function"
}
}
})
function callback_p()
{
props.callback();
}
</script> -->
3、TestAttrs.vue
javascript
<template >
<div>
{{ msg }} + {{ attrs.msg2 }}
</div>
</template>
<script>
import { ref, useAttrs } from "vue";
export default {
inheritAttrs: true,
setup(props, context){
const msg = ref("msg1");
const attrs = context.attrs;
return {msg, attrs}
},
}
</script>
<!-- <script setup>
import { ref, useAttrs } from "vue";
const msg = ref("msg1");
const attrs = useAttrs();
console.log("attrs:",attrs);
</script> -->
4、TestSlot.vue
javascript
<template >
<div>
<slot>defaut slot</slot>
<slot name="header"></slot>
</div>
</template>
5、TestRef.vue
javascript
<template>
<h3>{{ title }}</h3>
</template>
<!--
<script>
import { ref } from "vue";
export default {
setup()
{
const title = ref("title");
const msg = ref({
title:"aaa"
});
function func()
{
console.log("func");
}
return {title, msg, func}
}
}
</script> -->
<script setup>
import { ref } from "vue";
const title = ref("title");
const msg = ref({
title:"aaa"
})
function func()
{
console.log("func");
}
defineExpose({
title,
msg,
func
})
</script>
6、TestEmit.vue
javascript
<template>
<h3>emit+++++</h3>
<div>{{ msg }}
<button @click="clicked">子传父</button>
</div>
</template>
<!-- <script>
import { ref } from 'vue';
export default {
emits : {
subemit : function(str)
{
console.log("subemit " + str);
//msg.value = str;
return true;
}
},
methods : {
clicked : function clicked()
{
console.log("clicked ");
this.$emit("subemit", this.msg);
}
},
setup()
{
const msg = ref("msg");
//这里声明无效需要用methods
function clicked1()
{
console.log("kkk");
this.$emit("subemit", this.msg.value);
}
return {msg,clicked1}
}
}
</script> -->
<script setup>
import { ref } from 'vue';
const msg = ref("msg");
const emits = defineEmits({
subemit : function(str)
{
console.log("subemit " + str);
return true;
}
})
function clicked()
{
console.log("clicked ");
emits("subemit", msg.value);
}
</script>
<style>
</style>
7、TestProvideInject.vue
javascript
<template>
<div>inject provide test {{ puser }}</div>
<button @click="pb">test</button>
</template>
<!-- <script lang="ts">
import { ref } from 'vue'
export default {
setup() {
const msg = ref("msgtest");
return {msg}
},
methods :
{
pb : function()
{
console.log(this.msg);
this.$emit("subemit", this.msg);
}
},
emits : {
subemit : function(str){
console.log("subemit " + str);
return true; //要有返回值,不然有warning
}
}
}
</script> -->
<script setup>
import { inject, ref } from 'vue'
const msg = ref("msgtest");
const puser = inject("user");
const puserObj = inject("userObj");
const userFunc = inject("userFunc");
console.log(puser, puserObj, userFunc())
</script>
8、终极方法vuex和pinia
参考