方式一:props
props是实现父组件向子组件传递信息,props的数据是只读的。
使用实例:
父组件:
<script setup lang="ts">
// 导入子组件
import Child from './Child.vue'
import { ref } from 'vue';
const money = ref(1000);
</script>
<template>
<div class="box">
<h1>我是父组件</h1>
<hr />
<Child info="我是父组件参数" :money="money"></Child>
</div>
</template>
子组件:需要使用到defineProps方法去接受父组件传递过来的数据。
<script setup lang="ts">
//defineProps是Vue3提供方法,不需要引入直接使用
let props = defineProps(['info','money']); //数组|对象写法都可以
</script>
<template>
<div class="box">
<h1>我是子组件</h1>
<div style="color: red;">{{info}}<p>{{money}}</p></div>
</div>
</template>
效果图:
方式二:emit
emit方式是Vue3中最常见的组件通信方式,该方式用于子传父。
父组件中:
<template>
<h1>我是父组件</h1>
<p style="color: brown;">{{ list }}</p>
<hr />
<!-- add是子组件要传递的事件名称,handleAdd是监听到之后执行的事件 -->
<Child @add="handleAdd"></Child>
</template>
<script setup lang="ts">
// 导入子组件
import Child from './Child.vue';
import { ref } from 'vue';
const list = ref("");
const handleAdd = (item: string) => {
list.value = item;
};
</script>
子组件中:
<script setup lang="ts">
const emits = defineEmits(['add']);
const handleBtn = () => {
emits('add', '哈哈哈哈,我是子组件参数');
}
</script>
<template>
<div class="box">
<h1>我是子组件</h1>
<button @click="handleBtn">点击我</button>
</div>
</template>
效果视频:
方法三:pinia
Pinia 是一个专门为Vue.js设计的状态管理库,它提供了一种简单和直观的方式来管理应用程序的状态。在使用Pinia时,可以轻松地创建定义状态的存储,然后将其与Vue组件绑定,使它们能够使用该状态。与Vuex相比,Pinia 更加简单易用,体积更小,同时具有更好的 TypeScript 支持和插件系统。
安装和配置Pinia
yarn add pinia
# 或者使用 npm
npm install pinia
在安装完Pinia包之后,需要在main.ts文件中导入createPinia函数并将Pinia插件与Vue应用程序绑定,如下所示:
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import App from './App.vue';
const app = createApp(App);
const pinia = createPinia();
app.use(pinia);
app.mount('#app');
使用 createPinia() 函数创建并初始化Pinia插件实例,将其与Vue应用程序绑定使用app.use(pinia)。至此,我们就可以使用Pinia来管理Vue应用程序的状态了。
在src下创建stores文件夹,然后在stores文件夹创建counter.ts文件,里面配置如下:
import { defineStore } from 'pinia'
export const useStore = defineStore('storeId', {
state: () => {
return {
count: 100
}
},
getters: {
double: (state) => state.count * 2,
},
actions: {
increment() {
this.count++
},
},
});
然后再想调用pinia的页面里,导入stores文件夹,就可以直接使用state和getters,例如:
<script setup lang="ts">
import { useStore } from './stores/counter';
const store = useStore();
// console.log(store.count, '1111');
console.log(store.double, '1111');
</script>
<template>
<p> 数量:{{ store.count }}</p>
<p> getters: {{ store.double }}</p>
</template>
<style scoped></style>
效果:
Action 就不一样了,Action 相当于组件中的方法。它们可以通过 defineStore() 中的 actions 属性来定义;
<script setup lang="ts">
import { useStore } from './stores/counter';
const store = useStore();
// 将 action 作为 store 的方法进行调用
store.increment();
</script>
<template>
<!-- 即使在模板中也可以 -->
<button @click="store.increment()">{{ store.count }}</button>
</template>
<style scoped></style>
效果:
Action 也是一种将异步操作封装在 store中的方式,它是一个可以被调用的函数,也可以接收参数并修改 store 中的状态。 Action应该始终是同步的,并返回一个 Promise 对象,以便在处理异步操作时能够很好地处理结果。
例如:
方法四provide/inject:
provide和inject是Vue中提供的一对API,该API可以实现父组件向子组件传递数据,无论层级有多深,都可以通过这对API实现。示例代码如下所示:
父组件:
<template>
<!-- 父组件 -->
<p>我是父组件</p>
<!-- 子组件 -->
<childComponents></childComponents>
</template>
<script setup>
import { ref, provide } from 'vue'
import ChildComponents from './child.vue'
const list = ref(['JavaScript', 'HTML', 'CSS'])
// 向子组件提供数据
provide('list', list.value)
</script>
子组件:
<template>
<ul >
<li v-for="i in list" :key="i">{{ i }}</li>
</ul>
</template>
<script setup>
import { inject } from 'vue'
// 接受父组件提供的数据
const list = inject('list')
</script>
效果:
方法五Refs:
如果我们想要通过ref的方式获取组件或者元素,需要定义一个同名的Ref对象,在组件挂载后就可以访问了。
父组件:
<template>
<ul>
{{ childRefs?.list }}
</ul>
<!-- 子组件 ref的值与<script>中的保持一致 -->
<child-components ref="childRefs"></child-components>
<!-- 父组件 -->
</template>
<script setup>
import { ref } from 'vue'
import ChildComponents from './child.vue'
const childRefs = ref(null);
</script>
子组件:
<template>
<div>
我是子组件
</div>
</template>
<script setup>
import { ref, defineExpose } from 'vue'
const list = ref(['JavaScript', 'HTML', 'CSS'])
defineExpose({ list });
</script>
效果:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。