组件间传参
父传子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>