vue3的组件通信

vue3的组件通信

1: v-model实现vue的通信

A组件

<template>
  <h1>我是父组件--{{title}}</h1>
  <hr>
  <B v-model="title"></B>
</template>

<script setup>
  import { ref } from 'vue'
  import B from "./components/B.vue";
  let title = ref("张三")
</script>

<style>

</style>

B组件

<template>
  <div class="hello">
    <h1>我是子组件--{{title}}</h1>
    <button @click="mutateParentTitle">修改父组件的title值</button>
  </div>
</template>

<script setup>
  import { ref } from 'vue'
  const props = defineProps({
    modelValue:String
  })
  const title = ref(props.modelValue)
  const emit = defineEmits(["update:modelValue"])
  const mutateParentTitle = ()=>{
    title.value = title.value == '张三' ? '李四' : '张三'
    emit("update:modelValue",title.value)
  }
</script>

<style scoped>

</style>

2: provide和inject

  • A组件
<template>
  <h1>我是父组件--{{title}}</h1>
  <hr>
  <B ></B>
</template>

<script setup>
  import { ref,provide } from 'vue'
  import B from "./components/B.vue";
  let title = ref("张三")
  provide("sendTitle",title.value)
</script>

<style>

</style>

  • B组件
<template>
  <div class="hello">
    <h1>我是子组件--{{title}}</h1>
  </div>
</template>

<script setup>
  import { ref,inject } from 'vue'
  const title = inject("sendTitle")
</script>

<style scoped>

</style>

3: pinia(vuex5版本)

main.js(yarn add -D pinia)
import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'
const pinia = createPinia()
let app = createApp(App)

app.use(pinia)
app.mount('#app')

新建store,新建count.js和index.js
  • count.js
import { defineStore } from 'pinia'

// 定义 Store, 命名建议: useXxxxStore
// 参数1:Store 的唯一标识
// 参数2:配置对象,可以提供 state actions getters
const useCounterStore = defineStore('counter', {
  // 相当于组件 data
  state() {
    return {
      count: 0,
    }
  },
  // 相当于组件 computed
  getters: {
    double() {
      console.log(this) // 代表实例化的pinia
      return this.count * 2
      },
  },
  // 相当于组件 methods 在 pinia中 没有mutations,只有 actions,不管是同步还是异步的代码,都可以在actions中完成。
  actions: {
    add() {
      this.count++
    },
    addAsync() {
      setTimeout(() => {
        this.count++
      }, 1000)
    },
  },
})

// 导出 Store
export default useCounterStore


  • index.js
import useCounterStore from './count'

// 统一导出 useStore 方法
export default function useStore() {
  return {
    counter: useCounterStore(),
  }
}


  • 页面中使用
<template>
  <h1>轻量状态管理库 Pinia</h1>>
  <hr>
    <h1>解构pinia如何得到响应式数据-storeToRefs</h1>
   <h1>{{ count }}</h1>
  <h3>{{ double }}</h3>
</template>

<script setup>
import { storeToRefs } from 'pinia'
import  useStore  from './store/index.js'
// 使用 Store
const { counter } = useStore()
// storeToRefs 的使用 如果直接从pinia中解构数据,会丢失响应式, 使用storeToRefs可以保证解构出来的数据也是响应式的

const { count, double } = storeToRefs(counter)

</script>

<style>
</style>

4: emit组件通信

 -子组件
 <template>
  <div class="home">
    <button @click="mutateHandler">修改父组件的值</button>
  </div>
</template>

<script setup>
  const emit = defineEmits(['myClick'])
  const mutateHandler = () =>{
   emit("myClick",222)
  }
</script>
-父组件
<template>
{{title}}
<Home @click="myClick"></Home>
</template>

<script setup>
// @ is an alias to /src
import Home from '@/views/HomeView.vue'
import { ref } from 'vue'
const title = ref("张三")
const myClick = ()=>{
  title.value = "李四"
}


</script>
<style>

</style>


5: bus组件通信

- bus.js
import mitt from 'mitt'
const bus = mitt()
export default bus
 -组件A
 <template>
{{title}}
<Home @click="myClick"></Home>
<button @click="busEmit">bus组件通信</button>
</template>

<script setup>
// @ is an alias to /src
import Home from '@/views/HomeView.vue'
import bus from '@/utils/bus.js'
import { ref } from 'vue'

const busEmit = ()=>{
  console.log("this",this)
  bus.emit('busEmit', "你好");
}
</script>

 -组件B
 <template>
  <div class="home">
    <button @click="mutateHandler">修改父组件的值</button>
  </div>
</template>

<script setup>
  import { onMounted,onBeforeUnmount  } from 'vue';
  import bus from '@/utils/bus.js'
  onMounted(()=>{
    bus.on('busEmit', (data) => {
      console.log("data====",data)
    });
  })
  onBeforeUnmount(()=>{
    bus.off('busEmit');
  })
</script>

6:ref通信

-组件A
<template>
  <div class="home">
    <button>我是Home组件的标题{{title}}</button>
  </div>
</template>

<script setup>
  import { ref } from 'vue'
  const title = ref("小张三")
  const mutateHandler = ()=>{
    title.value = "小李四"
  }

  defineExpose({
    mutateHandler
  })
 
</script>

-组件B
<template>
<Home ref="children"></Home>
<button  @click="myClick">修改Home组件的title</button>

</template>

<script setup>
import Home from '@/views/HomeView.vue'
import { ref } from 'vue'
const children = ref(null)
const myClick = ()=>{
  children.value.mutateHandler()
}



</script>


7: props通信

 -组件A
 <template>
   <Home :title="title"></Home>
</template>
<script setup>
import Home from '@/views/HomeView.vue'
import { ref } from 'vue'
const title = ref("张三")
</script>
 -组件Home
 <template>
  <div class="home">
    <button>我是子组件的标题{{title}}</button>
  </div>
</template>

<script setup>
  defineProps({
    title:{
      type: String
    }
  })

</script>

未完待续~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容