vue3 - 组件间的传值

组件间传参

父传子v-on/props

父组件使用v-on:绑定要传的参数:parentData="parentData"

html 复制代码
<template>
  <div>
    <Child1 :parentData="parentData"></Child1>
  </div>
</template>
<script setup lang="ts">
import Child1 from './components/Child1.vue';
import { ref } from 'vue';

const parentData = ref('父级组件参数:parentData');

onMounted(() => {
});
</script>

子组件使用props接收

html 复制代码
<template>
<div>
   父级组件参数:
   <p>{{ modelValue }}</p>
   <p>{{ parentData }}</p>
</div>
</template>
<script setup lang="ts">
const props = defineProps({
  modelValue: {
    type: String,
    required: false
  },
  parentData: {
    type: String,
    default: '父级组件参数:default'
  }
});
</script>

子传父emit

父组件自定义事件changeData传递给子组件

html 复制代码
<template>
  <div>
    <h2>父级组件</h2>
    <Child1 :parentData="parentData" v-model="defaultData" @changeData="changeData"></Child1>
  </div>
</template>
<script setup lang="ts">
import Child1 from './components/Child1.vue';
import { onMounted, reactive, ref, watch } from 'vue';

const defaultData = ref('v-model绑定参数:defaultData');
const parentData = ref('父级组件参数:parentData');

const changeData = (data: string) => {
  console.log('子组件传给父组件参数:', data);
  parentData.value = data;
};
</script>

子组件触发事件将需要传递给父组件的参数给事件,使用defineEmits接收事件,emit触发事件。

html 复制代码
<template>
  <div>
    <!-- 父组件参数 -->
    <div>
      父级组件参数:
      <p>
        {{ modelValue }}
      </p>
      <p>
        {{ parentData }}
      </p>
      <button @click="emit('changeData', '子组件传给父组件参数')">子组件传给父组件参数</button>
    </div>
  </div>
</template>
<script setup lang="ts">
import { onMounted, reactive, ref, watch } from 'vue';
const props = defineProps({
  modelValue: {
    type: String,
    required: false
  },
  parentData: {
    type: String,
    default: '父级组件参数:default'
  }
});

/**
 * 子组件传给父组件参数
 *  1. 定义事件
 *  2. 通过emit触发事件
 *  3. 父组件通过@changeData="changeData"接收事件
 */
const emit = defineEmits(['changeData'])
</script>

父传子:依赖/注入:provide/inject

父组件使用provide定义要传递给后代组件的方法、参数。(当需要给深层的某个子组件传递参数时,使用props传参需要一层一层的传递,不好维护代码,可使用provide/inject来实现)

html 复制代码
<template>
  <div>
    <h2>父级组件</h2>
    <button @click="provideData = '更新后的父级组件provide参数:provideData'">更新provideData</button>
    <Child1></Child1>
  </div>
</template>
<script setup lang="ts">
import Child1 from './components/Child1.vue';
import { ref, provide  } from 'vue';
    
const provideData = ref('父级组件provide参数:provideData');
provide('provideData1', provideData); // 传递响应式参数,父组件更新值,子组件跟着更新数据
provide('provideData2', provideData.value); // 直接传递值,父组件更新后子组件不会更新
</script>

子组件通过inject

html 复制代码
<template>
  <div class="child1">
    <div>
      父级组件参数:
      <p>inject:provideData1: {{ provideData1 }}</p>
      <p>inject:provideData2: {{ provideData2 }}</p>
    </div>
  </div>
</template>
<script setup lang="ts">
import { inject, ref } from 'vue';

const provideData1 = inject('provideData1');
const provideData2 = inject('provideData2');


</script>
<style scoped lang='scss'>
.child1{
  border: 1px solid #ccc;
}
</style>

状态管理pinia

1.安装:

tex 复制代码
npm install pinia

2.main.ts

创建一个 pinia 实例 (根 store) 并将其传递给应用

ts 复制代码
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'

const pinia = createPinia()
const app = createApp(App)

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

使用pinia参考地址:https://pinia.vuejs.org/zh/core-concepts/

3.定义store

/src/stores/counter.ts

ts 复制代码
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
  const name = ref('Eduardo')
  const doubleCount = computed(() => count.value * 2)
  function increment() {
    count.value++
  }

  return { count, doubleCount, increment }
})

4.使用

html 复制代码
<script setup>
import { useCounterStore } from '@/stores/counter'
// 在组件内部的任何地方均可以访问变量 `store` ✨
const store = useCounterStore()

// ❌ 下面这部分代码不会生效,因为它的响应式被破坏了
// 与 reactive 相同: https://vuejs.org/guide/essentials/reactivity-fundamentals.html#limitations-of-reactive
const { name, doubleCount } = store
name // 将会一直是 "Eduardo" //
doubleCount // 将会一直是 0 //
setTimeout(() => {
  store.increment()
}, 1000)


// 这一部分代码就会维持响应式
// 💡 在这里可以直接使用 `store.doubleCount`
const doubleValue = computed(() => store.doubleCount)
</script>

父传子:插槽 Slots

父组件使用slots传递html代码给子组件显示

html 复制代码
<template>
  <div>
    <h2>父级组件</h2>
    <Child1>
      <div>
        <p>父组件代码片段1</p>
      </div>
      <p>父组件代码片段2</p>

      <template #header>
        <p>父组件代码片段3</p>
      </template>
    </Child1>
  </div>
</template>
<script setup lang="ts">
import { te } from 'element-plus/es/locales.mjs';
import Child1 from './components/Child1.vue';
import { ref, provide  } from 'vue';
</script>
html 复制代码
<template>
  <div class="child1">
    <slot name="header">子组件头部插槽(具名插槽)</slot>
    <div>子组件内容1</div>
    <slot>子组件默认插槽</slot>
    <div>子组件内容2</div>
  </div>
</template>
<script setup lang="ts">
import { ref } from 'vue'


</script>
<style scoped lang='scss'>
.child1 {
  border: 1px solid #ccc;
}
</style>

父组件中具名插使用<template #插槽名>,子组件定义<slot name="header"></slot>,当父组件为给插槽传递内容时,会显示<slot></slot>标签之间的插槽默认内容,没有则不显示。

子传父:插槽 Slots

子组件定义传递的参数

html 复制代码
<template>
	<slot name="header" :count ="1" :text='text1'></slot>
	<slot :count ="2" :text='text2'></slot>
</template>

父组件接收子组件的参数

html 复制代码
<template #header="headerProps">
    {{ headerProps.count }} {{ headerProps.text }}
</template>

<template #header="{count,text}">
    {{ count }}{{text}}
</template>

<!-- 默认插槽 -->
<template v-slot="defaultProps">
    {{ defaultProps.count }} {{ defaultProps.text }}
</template>

<template v-slot="{count,text}">
    {{ count }}{{text}}
</template>

<template #default="defaultProps">
    {{ defaultProps.count }} {{ defaultProps.text }}
</template>

<template #default="{count,text}">
    {{ count }}{{text}}
</template>

注:这个传参方式主要在封装组件时使用,例如element plus组件中table

父传子

父组件使用子组件暴露的方法,执行方法,将参数传递给方法中

html 复制代码
<template>
  <div>
    <Child1 ref='child'></Child1>
  </div>
</template>
<script setup lang="ts">
import Child1 from './components/Child1.vue';
import { ref } from 'vue';

const params = ref({
    name:'',
    type:''
})
const child = ref(null);

onMounted(() => {
    child.value.open(params.value)
});
</script>
html 复制代码
<script setup lang="ts">
const open = (params)=>{
    console.log('父组件传递的参数:',params)
}
    
// 暴露方法给父组件
defineExpose({
  open
});
</script>
相关推荐
盛夏绽放37 分钟前
jQuery 知识点复习总览
前端·javascript·jquery
胡gh3 小时前
依旧性能优化,如何在浅比较上做文章,memo 满天飞,谁在裸奔?
前端·react.js·面试
大怪v3 小时前
超赞👍!优秀前端佬的电子布洛芬技术网站!
前端·javascript·vue.js
胡gh3 小时前
你一般用哪些状态管理库?别担心,Zustand和Redux就能说个10分钟
前端·面试·node.js
项目題供诗3 小时前
React学习(十二)
javascript·学习·react.js
无羡仙3 小时前
Webpack 背后做了什么?
javascript·webpack
老华带你飞4 小时前
校园交友|基于SprinBoot+vue的校园交友网站(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·校园交友网站
roamingcode5 小时前
Claude Code NPM 包发布命令
前端·npm·node.js·claude·自定义指令·claude code
码哥DFS5 小时前
NPM模块化总结
前端·javascript
灵感__idea5 小时前
JavaScript高级程序设计(第5版):代码整洁之道
前端·javascript·程序员