组件之间的传值
1、父传子 props
2、父传子 slot
3、父传子 不建议用 attrs
4、 子传父 ref
5、子传父 emit
6、povide/inject只能在setup的时候用。
7、利用vuex和pinia去实现数据的交互
1、实现代码App.vue
<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
<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
<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
<template ><div><slot>defaut slot</slot><slot name="header"></slot></div>
</template>
5、TestRef.vue
<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
<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");//这里声明无效需要用methodsfunction 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
<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
参考
Vue组件之间数据通信12种方式_vue组件间通信_小胖梅前端的博客-CSDN博客
vue组件间通信的六种方式(完整版)_vue的组件之间是如何交互的, 几种方式_学编程的ADD的博客-CSDN博客