Skip to content

组件通讯

父传子

DANGER

js
// 父组件模块
<template>
    <div>父组件:123</div>
    <BBB :list="list"></BBB>
</template>
  
<script setup>
import {ref , reactive} from 'vue'
import BBB from './BBB.vue'
const list = ref('123')
</script>
  
<style>
</style>
// 父组件模块
<template>
    <div>父组件:123</div>
    <BBB :list="list"></BBB>
</template>
  
<script setup>
import {ref , reactive} from 'vue'
import BBB from './BBB.vue'
const list = ref('123')
</script>
  
<style>
</style>

DANGER

需要引用vue API import { defineProps } from 'vue';

js
// 子组件模块
<template>
  <div>子组件接收:{{ list }}</div>
</template>
<script setup>
import { defineProps } from 'vue';
const props = defineProps({
  list:String,
})
</script>

<style>

</style>
// 子组件模块
<template>
  <div>子组件接收:{{ list }}</div>
</template>
<script setup>
import { defineProps } from 'vue';
const props = defineProps({
  list:String,
})
</script>

<style>

</style>

子传父

DANGER

js
//父组件模块
<template>
    <div>父组件:{{ list }}</div>
    <BBB @emitClick="emitClick"></BBB>
</template>
  
<script setup>
import { ref } from 'vue'
import BBB from './BBB.vue'
const list = ref('我是父组件')
const emitClick = value => {
    list.value = value
}
</script>
  
<style></style>
//父组件模块
<template>
    <div>父组件:{{ list }}</div>
    <BBB @emitClick="emitClick"></BBB>
</template>
  
<script setup>
import { ref } from 'vue'
import BBB from './BBB.vue'
const list = ref('我是父组件')
const emitClick = value => {
    list.value = value
}
</script>
  
<style></style>

DANGER

需要把子传父的点击事件写入 emits这个方法里

js
// 子组件模块
<template>
  <div>我是子组件:123</div>
  <button @click="emitClick">子组件点击事件</button>
</template>

<script setup>
import { ref, defineEmits } from 'vue';
const emits = defineEmits(['emitClick'])
const emitValue = ref('子组件传数据递给父组件')
const emitClick = () => {
  emits('emitClick', emitValue.value)
}
</script>

<style></style>
// 子组件模块
<template>
  <div>我是子组件:123</div>
  <button @click="emitClick">子组件点击事件</button>
</template>

<script setup>
import { ref, defineEmits } from 'vue';
const emits = defineEmits(['emitClick'])
const emitValue = ref('子组件传数据递给父组件')
const emitClick = () => {
  emits('emitClick', emitValue.value)
}
</script>

<style></style>

父组件调用子组件的方法

DANGER

js
// 父组件
<template>
  <div>
    <button @click="handlClick">查询</button>
    <Home-vite ref="child"></Home-vite>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import HomeVite from './HomeView.vue'

const child = ref('')
const child1 = ref('我是父组件的方法')
const handlClick = () => { //父组件 点击事件
  child.value.getList(child1.value)   //调用子组件方法
}
</script>

<style></style>
// 父组件
<template>
  <div>
    <button @click="handlClick">查询</button>
    <Home-vite ref="child"></Home-vite>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import HomeVite from './HomeView.vue'

const child = ref('')
const child1 = ref('我是父组件的方法')
const handlClick = () => { //父组件 点击事件
  child.value.getList(child1.value)   //调用子组件方法
}
</script>

<style></style>

DANGER

defineExpose  需要用这个方法抛出方法
js
// 子组件
<template>
</template>

<script setup>
import { ref, defineEmits, defineExpose } from 'vue'
const getList = (value) => {     //子组件传递给父组件的方法
  console.log(
    '%c打印➜:', 'background:green;color:#fff;padding:4px;',
    value
  )
}
defineExpose({   //抛出要传递给父组件的方法
  getList
})

</script>

<style></style>
// 子组件
<template>
</template>

<script setup>
import { ref, defineEmits, defineExpose } from 'vue'
const getList = (value) => {     //子组件传递给父组件的方法
  console.log(
    '%c打印➜:', 'background:green;color:#fff;padding:4px;',
    value
  )
}
defineExpose({   //抛出要传递给父组件的方法
  getList
})

</script>

<style></style>

DANGER

defineExpose  再循环中for 使用 :ref
在循环中动态设置ref时,建议使用索引或数据唯一标识ID  :ref="el => setChildRef(el, index)"
js
 <div v-for="(domain, index) in deviceDomainList" :key="domain.domainValue" >
              <MachineTab v-if="domain.domainValue === 3" :domain="domain.domainValue" :ref="el => setChildRef(el, index)" />
              <DroneTab v-if="domain.domainValue === 0" :domain="domain.domainValue"  :ref="el => setChildRef(el, index)"/>
  </div>

  const childRefs = ref([])
// 循环中使用 :ref  设置子组件引用
const setChildRef = (el, index) => {
  if (el) {
    childRefs.value[index] = el
  }
}
//  父组件调用子组件的方法   <!-- 根据不同的域类型显示对应的组件 0 无人机 1 负载 2 遥控器 3 机场 100 无人车 默认 -->
const setViewModeBtnRef = (mode: string, val: number) => {
  if (val == 3) {
      childRefs.value.forEach((child, index) => {
        if (child && child.reset) {
          child.reset(mode)
        }
      })
    }


    
  子组件正常抛出
}
 <div v-for="(domain, index) in deviceDomainList" :key="domain.domainValue" >
              <MachineTab v-if="domain.domainValue === 3" :domain="domain.domainValue" :ref="el => setChildRef(el, index)" />
              <DroneTab v-if="domain.domainValue === 0" :domain="domain.domainValue"  :ref="el => setChildRef(el, index)"/>
  </div>

  const childRefs = ref([])
// 循环中使用 :ref  设置子组件引用
const setChildRef = (el, index) => {
  if (el) {
    childRefs.value[index] = el
  }
}
//  父组件调用子组件的方法   <!-- 根据不同的域类型显示对应的组件 0 无人机 1 负载 2 遥控器 3 机场 100 无人车 默认 -->
const setViewModeBtnRef = (mode: string, val: number) => {
  if (val == 3) {
      childRefs.value.forEach((child, index) => {
        if (child && child.reset) {
          child.reset(mode)
        }
      })
    }


    
  子组件正常抛出
}

DANGER

不推荐使用该方法不容易维护 $parent  待更新

子组件调用父组件的方法

替我上班,工资分你一半