Vue3的几种通信方式

294 阅读2分钟

1.父子组件通信

(和vue2区别不大) 1.父传子 父组件:在子组件上通过 v-bind绑定属性 子组件:先定义下基本类型,然后通过setup的第一个参数取获取传过来的值

父组件
<template>
  <Children :value='value'></Children>
</template>
<script lang='ts'>
import Children from './Children.vue'
import { defineComponent, reactive, toRefs } from 'vue'
export default defineComponent({
  components: { Children },
  setup() {
    const data = reactive({
      value: '我是父组件'
    })
    return {
      ...toRefs(data)
    }
  }
})
</script>
子组件
<template>
    {{value}} 
</template>
<script lang='ts'>
import { defineComponent } from 'vue'
export default defineComponent({
  props: {
    value: String
  }
})
</script>

2.子传父 父组件:在子组件上绑定一个事件,并定义回调 子组件:通过setup的第二个参数去接受,第二个参数包含了(attrs,emit,slots),这里我们用到第二个参数中的emit去传值。

父组件
<template>
  {{value}}
  <Children @changeValue='changeValue'></Children>
</template>

<script lang='ts'>
interface DataProps {
  value: string;
  changeValue: () => void;
}
import Children from './Children.vue'
import { defineComponent, reactive, toRefs } from 'vue'
export default defineComponent({
  components: { Children },
  setup() {
    const data = reactive({
      value: 'msg',
      changeValue: (val: string) => {
        data.value = val
      }
    })
    return {
      ...toRefs(data)
    }
  }
})
</script>
子组件
<template>
  <button @click="change">chang</button>
</template>

<script lang='ts'>
import { defineComponent, reactive, toRefs } from 'vue'
export default defineComponent({
  setup(props, context) {
    const parent = { ...context }
    const data = reactive({
      change: () => {
        parent.emit('changeValue', '我被子组件改变了')
      }
    })
    return {
      ...toRefs(data)
    }
  }
})
</script>

2.Provide 和 inject

应用方式与vue2无区别。 详细步骤: 1.将要传递给后代的方法或数据通过Provide的方式传递出去

  provide() {
    return {
      msg: '123123123'
    }
  },

2.后代组件通过Inject方式接受,即可使用。

inject: ['msg', 'show']

以下是详细代码

grandParent组件
<template>
    <Parent></Parent>
</template>
<script lang="ts">
import { defineComponent, reactive, toRefs } from 'vue'
import Parent from './parent.vue'
export default defineComponent({
  components: { Parent },
  provide() {
    return {
      msg: '123123123',
      show: function () {
        console.log(12312312)
      }
    }
  },
  setup() {
    const data = reactive({
      msg: '12312'
    })
    return {
      ...toRefs(data)
    }
  }
})
</script>
parent组件
<template>
  <son></son>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import son from './son.vue'
export default defineComponent({
  components: { son }
})
</script>
son组件
<template>
  {{msg}}
  <button type="button" @click="show">console</button>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
  inject: ['msg', 'show']
})
</script>

3.localStorage / sessionStorage
localStorage数据不受页面刷新影响,也不会因关闭窗口、标签页或重新启动浏览器而丢失。
sessionStorage对象应该主要用于存储只在会话期间有效的小块数据。如果需要跨会话持久存储数据,可以使用localStorage。
两种存储方法的区别在于,存储在localStorage中的数据会保留到通过JavaScript删除或者用户清除浏览器缓存。

但是这种通信比较简单,缺点是数据和状态比较混乱,不太容易维护,且数据类型是字符串。
通过window.localStorage.getItem(key)获取数据
通过window.localStorage.setItem(key,value)存储数据
通过window.sessionStorage.getItem(key)获取数据
通过window.sessionStorage.setItem(key,value)存储数据
注意用JSON.parse() / JSON.stringify() 做数据格式转换
localStorage / sessionStorage可以结合vuex, 实现数据的持久保存,同时使用vuex解决数据和状态混乱问题.
(暂时就写这么多,过后继续补充。)