飞道的博客

vue3 的8种通信 方式

436人阅读  评论(0)

目录

1.defineProps  defineEmits  defineExpose/ref

ts写法

defineEmit

defineExpose

2.v-model   组件标签可同时写多个v-model 不再支持  .sync

3.provide inject

4.attrs  会包含父组件的props 属性的集合  一旦用props接收,attrs

就接收不到了

5.插槽

6.Vuex  pinia 

7. provide inject

8.mitt

基于vue 3.2

1.defineProps  defineEmits  defineExpose/ref


  
  1. <template>
  2. <div>
  3. <button @click="changeSonValue">changeNum </button>
  4. <h1>{{ n }} </h1>
  5. <h1 v-for="(item, index) in obj">{{ item }} </h1>
  6. </div>
  7. </template>
  8. <script setup>
  9. import { ref, watch } from "vue";
  10. // let props = defineProps(["num", "obj","changeNum"]); //简单
  11. let props = defineProps({ num:{ type: Number}, obj:{ type: Object}}) //限制类型
  12. let n = ref(props. num); //props 获取所有props的对象
  13. // console.log(n);
  14. const changeSonValue = ( ) => {
  15. n. value++;
  16. };
  17. let changeNumFromFather = ( )=>{
  18. props. changeNum()
  19. }
  20. watch(n, (n,o)=>{
  21. console. log(n);
  22. },{ immediate: true, deep: true});
  23. watch(props. obj, (n,o)=>{
  24. console. log(n);
  25. },{ deep: true, immediate: true})
  26. watch([n,props. obj], ()=>{}) //多个监视用数组
  27. </script>
  28. <style scoped></style>

defineEmits


  
  1. //father
  2. <!--
  3. * new page
  4. * @ author: keepCoding-gyk
  5. * @ since: 2022- 12- 04
  6. * father. vue
  7. -->
  8. <template>
  9. <div>
  10. <h1>
  11. {{num}}
  12. <son @changeNum="getNum"> </son>
  13. </h1>
  14. </div>
  15. </template>
  16. <script setup>
  17. import { ref } from 'vue';
  18. import son from './son.vue'
  19. let num = ref( 666);
  20. let getNum = ( v)=>{
  21. num. value+=v
  22. }
  23. </script>
  24. <style lang="scss" scoped>
  25. </style>
  26. //son
  27. <!--
  28. * new page
  29. * @ author: keepCoding-gyk
  30. * @ since: 2022- 12- 04
  31. * son. vue
  32. -->
  33. <template>
  34. <div>
  35. <button @click="changeNumFromFather">changeNumFromFather </button>
  36. </div>
  37. </template>
  38. <script setup>
  39. let emits = defineEmits([ 'changeNum']);
  40. let changeNumFromFather =( )=>{
  41. emits( 'changeNum', 1)
  42. }
  43. </script>
  44. <style lang="scss" scoped></style>

defineExpose  父组件需要借助ref


  
  1. <!--
  2. * new page
  3. * @ author: keepCoding-gyk
  4. * @ since: 2022- 12- 04
  5. * father. vue
  6. -->
  7. <template>
  8. <div >
  9. <son ref="son1"> </son>
  10. <button @click="test">test </button>
  11. </div>
  12. </template>
  13. <script setup >
  14. import son from './son.vue';
  15. import { ref } from 'vue';
  16. const son1 = ref( null)
  17. console. log(son1);
  18. let test = ( )=>{
  19. console. log(son1. value. num);
  20. son1. value. changeNum()
  21. }
  22. </script>
  23. <style lang="scss" scoped>
  24. </style>
  25. <!--
  26. * new page
  27. * @ author: keepCoding-gyk
  28. * @ since: 2022- 12- 04
  29. * son. vue
  30. -->
  31. <template>
  32. <div>
  33. <h1>{{num}} </h1>
  34. </div>
  35. </template>
  36. <script setup>
  37. import { ref } from 'vue';
  38. let num = ref( 666);
  39. let changeNum = ( )=>{
  40. num. value ++
  41. }
  42. defineExpose ({num,changeNum});
  43. </script>
  44. <style lang="scss" scoped>
  45. </style>

ts写法

defineProps 三种写法


  
  1. let props= defineProps([ 'str'])
  2. console. log(props);
  3. let props = defineProps({
  4. str: String,
  5. arr:{
  6. type: Object,
  7. default: ()=>[ 1, 2]
  8. }
  9. })
  10. let props = defineProps<{
  11. str:string,
  12. arr:number[]
  13. }>()
  14. withDefaults(defineProps<{ //设置默认值
  15. str:string,
  16. arr:number[]
  17. }>(),{
  18. arr: ()=>[ 666]
  19. })

defineEmit


  
  1. let emit = defineEmits([ 'ca'])
  2. let emit = defineEmits<{ // 可以对每一个参数进行限制
  3. ( e: 'ca', a:string, b:number, c:string): void
  4. }>()
  5. let changeArr = ( )=>{
  6. emit( 'ca', '999', 88, 'jjj')
  7. }

defineExpose


  
  1. defineExpose<{ n:string, s: Function}>({
  2. n: '999',
  3. s: ()=> console. log( '999'),
  4. })
  5. let wf = ref< InstanceType< typeof sVue>>();
  6. onMounted( ()=>{
  7. wf. value?. s();
  8. console. log(wf. value?. n);
  9. })

2.v-model   组件标签可同时写多个v-model 不再支持  .sync


  
  1. <!--
  2. * new page
  3. * @ author: keepCoding-gyk
  4. * @ since: 2022- 12- 04
  5. * father. vue
  6. -->
  7. <template>
  8. <div >
  9. <h1>father {{num1}} </h1>
  10. <sonVue v-model:value1="num1" v-model:value2="num2" > </sonVue>
  11. </div>
  12. </template>
  13. <script setup >
  14. import { ref } from 'vue';
  15. import sonVue from './son.vue';
  16. let num1 = ref( 666);
  17. let num2 = ref( 888)
  18. </script>
  19. <style lang="scss" scoped>
  20. </style>
  21. <!--
  22. * new page
  23. * @ author: keepCoding-gyk
  24. * @ since: 2022- 12- 04
  25. * son. vue
  26. -->
  27. <template>
  28. <div>
  29. <input type="text" v-model="num" @change="changeFatherValue1">
  30. <button @click="changeFatherValue1">46546546 </button>
  31. </div>
  32. </template>
  33. <script setup>
  34. import { ref } from 'vue';
  35. let props = defineProps({ value1:{}, value2:{}}) //{value:{}}
  36. let emits = defineEmits([ 'value1'])
  37. let num = ref(props. value1)
  38. let changeFatherValue1 = ( )=>{
  39. emits( 'update:value1',num. value)
  40. }
  41. </script>
  42. <style lang="scss" scoped>
  43. </style>

3.provide inject


  
  1. <!--
  2. * new page
  3. * @ author: keepCoding-gyk
  4. * @ since: 2022- 12- 05
  5. * grand. vue
  6. -->
  7. <template>
  8. <div >
  9. <h1>grand </h1>
  10. <father> </father>
  11. </div>
  12. </template>
  13. <script setup >
  14. import { getCurrentInstance, provide, ref } from 'vue';
  15. import father from './father.vue'
  16. let num = ref( 10);
  17. provide( 'num',num. value);
  18. provide( 'test', 99999999)
  19. </script>
  20. <style lang="scss" scoped>
  21. </style>
  22. <!--
  23. * new page
  24. * @ author: keepCoding-gyk
  25. * @ since: 2022- 12- 05
  26. * father. vue
  27. -->
  28. <template>
  29. <div >
  30. <son> </son>
  31. </div>
  32. </template>
  33. <script setup >
  34. import son from './son.vue'
  35. </script>
  36. <style lang="scss" scoped>
  37. </style>
  38. <!--
  39. * new page
  40. * @ author: keepCoding-gyk
  41. * @ since: 2022- 12- 05
  42. * son. vue
  43. -->
  44. <template>
  45. <div >
  46. </div>
  47. </template>
  48. <script setup >
  49. import { inject } from 'vue';
  50. let num = inject( 'num');
  51. console. log(num);
  52. let test = inject( 'test');
  53. console. log(test);
  54. </script>
  55. <style lang="scss" scoped>
  56. </style>

4.attrs  会包含父组件的props 属性的集合  一旦用props接收,attrs

就接收不到了


  
  1. <!--
  2. * new page
  3. * @ author: keepCoding-gyk
  4. * @ since: 2022- 12- 05
  5. * father. vue
  6. -->
  7. <template>
  8. <div >
  9. <son :m1="m1" :m2="m2"> </son>
  10. </div>
  11. </template>
  12. <script setup >
  13. import { ref } from 'vue';
  14. import son from './son.vue'
  15. let m1 = ref( 10);
  16. let m2 = ref( 100);
  17. </script>
  18. <style lang="scss" scoped>
  19. </style>
  20. <!--
  21. * new page
  22. * @ author: keepCoding-gyk
  23. * @ since: 2022- 12- 05
  24. * son. vue
  25. -->
  26. <template>
  27. <div >
  28. </div>
  29. </template>
  30. <script setup >
  31. import { useAttrs } from 'vue';
  32. let props = defineProps([ 'm1']);
  33. let attrs = useAttrs();
  34. console. log(attrs);
  35. </script>
  36. <style lang="scss" scoped>
  37. </style>

5.插槽

vue2
匿名插槽 <slot/>
具名 <slot name="xxx"/> 模版标签 v-slot:xxx 或 #xxx
作用域 <slot :name="xxx"/>  模版  slot-scope="{name}"
vue3  匿名 具名不变
作用域

<slot :name="xxx"/>  模版  v-slot="{name}" 或者  #default="{name}" 或者

 v-slot:default="slotProps"

动态插槽  


  
  1. <template #[dyniamic]>
  2. <h1>{{ dyniamic }}</h1>
  3. </template>
  4. import { ref } from 'vue';
  5. let dyniamic = ref( 'dyniamic')
  6. let dyniamicChange = ( )=>{
  7. dyniamic. value = 'test'
  8. }
  9. <slot name= "dyniamic"></slot>
  10. <slot name="test"></slot>

具名插槽也可以 当作用域 用


  
  1. <template v- slot:app= "scope">
  2. {{ scope }}
  3. </template>
  4. <slot name="app" :msg="arr"></slot>

6.Vuex  pinia 

https://blog.csdn.net/gu2022_3_5_21_23/category_12150734.html

7. provide inject

支持向子组件注射穿透  ,可以多级使用

父组件


  
  1. //父组件
  2. import sonVue from './com/son.vue';
  3. import { provide } from 'vue';
  4. provide( 'qq', 'sss')
  5. provide( 'test', '你好世界');

子组件 或 孙组件


  
  1. let qq=inject<string>( 'qq')
  2. let test = inject( 'test')

8.mitt

由于 Vue 3 原型上 没有了 $on , 所以原来的事件总线 不能用了,但是 现在有一个包 延续了 该种通信方式 那就是 mitt

npm i mitt -S

mitt.js 创建一个实例


  
  1. import mitt from 'mitt'
  2. let mitts = mitt()
  3. export default mitts

组件A


  
  1. let str = ref( "你好世界");
  2. let handleStr = ( ) => {
  3. mitt. emit( "getStr", str. value);
  4. };

组件B


  
  1. mitt. on( 'getStr', (v)=>{
  2. str. value = v
  3. })
  4. onUnmounted( ()=>{
  5. mitt. off( 'getStr')
  6. })


转载:https://blog.csdn.net/gu2022_3_5_21_23/article/details/128178062
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场