方式一: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>

效果图:
image.png

方式二: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>

效果视频:
效果.gif

方法三: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>

效果:
1.png
2.png

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>

效果:
3.gif

Action 也是一种将异步操作封装在 store中的方式,它是一个可以被调用的函数,也可以接收参数并修改 store 中的状态。 Action应该始终是同步的,并返回一个 Promise 对象,以便在处理异步操作时能够很好地处理结果。
例如:
image.png

方法四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>

效果:
5.png

方法五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>

效果:
6.png


打盹的自行车_pcjIC
1 声望1 粉丝