vue3常用组件通信方式

props

父组件以数据绑定的形式声明要传递的数据,子组件通过defineProperty()方法创建props对象来拿到父组件传来的数据。

父组件

<!-- list是我们要传递的数据 -->
<child :list="list"></child>

子组件

<template>
  <ul>
    <li v-for="i in props.list" :key="i">{{ i }}</li>
  </ul>
</template>
<script setup>
import { defineProps } from 'vue'
const props = defineProps({
  list: {
    type: Array,
    default: () => [],
  },
})
</script>

emit

用于子组件向父组件传递消息

父组件

<!-- add是子组件要传递的动作,handleAdd是监听到之后执行的事件 -->
<child @add="handleAdd"></child>
<script>
 const list = ref([1,2,3])
 const handleAdd = value => {
  list.value.push(value)
}
</script>

子组件

const emits = defineEmits(['add'])
emits('add', 1)

v-model方式

父组件

<child v-model:list="list" />
// 等价于
<child :list="pageTitle" @update:list="list = $event" />

子组件需要emit一个叫update:xxx的事件,再把需要更新的响应式数据传给emit方法的第二个参数

const emits = defineEmits(['update:list'])
emits('update:list', arr)

Refs

默认情况下,setup 组件是关闭的,通过模板 ref 获取组件的公共实例。如果需要公开,需要通过defineExpose API 公开。

父组件

<template>
  <ul class="parent list-group">
    <li class="list-group-item" v-for="i in childRefs?.list" :key="i">
      {{ i }}
    </li>
  </ul>
  <!-- The value of the child component ref is the same as that in the <script> -->
  <child ref="childRefs"></child>
  <!-- parent component -->
</template>
<script setup>
import { ref } from 'vue'
import child  from './child.vue'
const childRefs = ref(null)
</script>

子组件

<template>
  <div class="child-wrap input-group">
    <input
      v-model="value"
      type="text"
      class="form-control"
      placeholder="Please enter"
    />
    <div class="input-group-append">
      <button @click="handleAdd" class="btn btn-primary" type="button">
        add
      </button>
    </div>
  </div>
</template>
<script setup>
import { ref, defineExpose } from 'vue'
const list = ref(['JavaScript', 'HTML', 'CSS'])
const value = ref('')
// event handling function triggered by add
const handleAdd = () => {
  list.value.push(value.value)
  value.value = ''
}
defineExpose({ list })
</script>

provide/inject

provide/inject是 Vue 中提供的一对 API。无论层级多深,API 都可以实现父组件到子孙组件的数据传递。

父组件

<template>
  <child></child> 
</template>
<script setup>
import { ref, provide } from 'vue'
import child from './child.vue'
const list = ref(['JavaScript', 'HTML', 'CSS'])
const value = ref('')

provide('list', list.value)

const handleAdd = () => {
  list.value.push(value.value)
  value.value = ''
}
</script>

子组件

<template>
  <ul class="parent list-group">
    <li class="list-group-item" v-for="i in list" :key="i">{{ i }}</li>
  </ul>
</template>
<script setup>
import { inject } from 'vue'

const list = inject('list')
</script>

vuex

//store/index.js
import { createStore } from "vuex"
export default createStore({
   state:{ count: 1 },
   getters:{
       getCount: state => state.count
  },
   mutations:{
       add(state){
           state.count++
      }
  }
})
// main.js
import { createApp } from "vue"
import App from "./App.vue"
import store from "./store"
createApp(App).use(store).mount("#app")
// Page.vue
// 方法一 直接使用
<template>
   <div>{{ $store.state.count }}</div>
   <button @click="$store.commit('add')">按钮</button>
</template>
// 方法二 获取
<script setup>
   import { useStore, computed } from "vuex"
   const store = useStore()
   console.log(store.state.count) // 1
 
   const count = computed(()=>store.state.count) // 响应式,会随着vuex数据改变而改变
   console.log(count) // 1
</script>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值