【Vue3】组件通信以及各种方式的对比

方式一:props

「父」向「子」组件发送数据

父组件:
定义需要传递给子组件的数据,并使用 v-bind 指令将其绑定到子组件的 props 上。

<template>
  <child-component :message="parentMessage" />
</template>

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

let parentMessage = ref('111')
</script>

子组件:
使用defineProps声明接收props。

<template>
  <div>{{ message }}</div>
</template>

<script setup>
defineProps(['message'])
</script>

「子」向「父」组件发送数据

父组件:
定义一个函数,参数为子组件中的数据,并使用 v-bind 指令将其绑定到子组件的 props 上。

<template>
  <child-component :sendData="getSonData"/>
</template>

<script setup>
import ChildComponent from './ChildComponent.vue'

// 定义一个函数,用于接收子组件中的数据
function getSonData(data){
	console.log("子组件中的数据:",data)
}
</script>

子组件:
defineProps接收props,调用父组件中声明的函数,并把数据当做参数传入。

<template>
  <button @click="sendData(data)">把数据发送到父组件</button>
</template>

<script setup>
import { ref } from 'vue'

let data = ref('111') // 子组件中的数据
defineProps(['sendData']) // 接收props
</script>

方式二:自定义事件

适用于「子」向「父」组件发送数据

父组件:
定义一个函数,参数为子组件中传递的数据,自定义事件名,并将函数传给子组件。

<template>
  <child-component @send-data="getSonData"/>
</template>

<script setup>
import ChildComponent from './ChildComponent.vue'

// 定义一个函数,用于接收子组件中的数据
function getSonData(data){
	console.log("子组件中的数据:",data)
}
</script>

子组件:
defineEmits声明事件,调用父组件中声明的事件回调函数,并把数据当做参数传入。
emit函数第一个参数为事件回调函数名,后续参数为该回调函数的参数。

<template>
  <button @click="emit('send-data',data)">把数据发送到父组件</button>
</template>

<script setup>
import { ref } from 'vue'

let data = ref('111') // 子组件中的数据
const emit = defineEmits(['send-data']) // 接收props
</script>

方式三:mitt

适用于所有组件间通信,将事件统一管理

类似vue2中的全局事件总线$bus以及pubsub消息订阅发布模式。由于Vue3中没有全局事件总线,所以需要使用mitt插件替代。
接收数据方:订阅消息(绑定好事件)
发送数据方:发布消息(在合适时机触发事件)

下载mitt

npm i mitt

根据官方提示,创建一个名为emitter的文件,其中创建并暴露emitter,在入口文件main.js中引用emitter。
emitter.js

// 引入mitt
import mitt from 'mitt'

// 调用mitt得到emitter,可以绑定、触发事件
const emitter = mitt()

// 暴露emitter
export default emitter

emitter实例中有四个方法,分别为emit「触发事件」、on「绑定事件」、off「解绑事件」、all「所有绑定事件」。

接收数据方:定义事件及回调函数

<template>
  <div>数据:{{ data }}</div>
  <MyComp />
</template>

<script setup>
import { ref } from 'vue'
import MyComp from "./MyComp.vue"
import emitter from './emitter.js'  // 引入

let data = ref('')
// 绑定send-data事件
emitter.on('send-data',(value)=>{
	data.value = value
})
</script>

发送数据方:触发事件并传入数据

<template>
  <button @click="emitter.emit('send-data',data)">发送数据</button>
</template>

<script setup>
import { ref } from 'vue'
import emitter from './emitter.js'  // 引入

let data = ref('111')
</script>

注意:接收数据方,需要在组件卸载时,及时解绑事件,避免内存泄漏。

import { onUnmounted } from 'vue'
onUnmounted(()=>{
	emitter.off('send-data')  // 解绑指定事件
})

方式四:v-model

首先需要知道的是:v-model是一个语法糖,其实现流程分为v-bind(数据 => 视图)以及v-on(视图 => 数据),从而实现数据与视图的双向绑定。

下面以input举例说明

<template>
  <input type="text" v-model="user_name" />

  <!-- v-model原始写法 -->
  <input
    type="text"
    :value="user_name"
    @input="user_name = (<HTMLInputElement>$event.target).value"
  />
</template>

<script setup lang="ts" name="Home123">
import { ref } from "vue"

let user_name = ref("")
</script>

<style scoped></style>

当Input封装为组件时,v-model的原始写法

<template>
  <MyInput v-model="user_name" /> 
  <MyInput :modelValue="user_name" @update:modelValue="user_name = $event" />
</template>

父组件

<template>
  <MyInput v-model="user_name" /> 
</template>

<script setup lang="ts" name="Home123">
import { ref } from "vue"
import MyInput from "./MyInput.vue"

let user_name = ref("")
</script>

<style scoped></style>

自定义Input组件

<template>
  <input
    type="text"
    :value="modelValue"
    @input="emits('update:modelValue', (<HTMLInputElement>$event.target).value)"
  />
</template>

<script setup lang="ts" name="MyInput123">
defineProps(["modelValue"])
let emits = defineEmits(["update:modelValue"])
</script>

<style scoped>
input {
  width: 200px;
  height: 40px;
  background-color: antiquewhite;
  border: 1px solid #efefef;
  border-radius: 5px;
}
</style>

v-model默认以 :modelValue 以及 @update:modelValue 两步实现。
如果绑定多个v-model就需要自定义属性名,可以在v-model后添加 :属性名

<template>
  <MyInput v-model:user="user_name" /> 
</template>

子组件中将原先modelValue变为自定义属性名

<template>
  <input
    type="text"
    :value="user"
    @input="emits('update:user', (<HTMLInputElement>$event.target).value)"
  />
</template>

<script setup lang="ts" name="MyInput123">
defineProps(["user"])
let emits = defineEmits(["update:user"])
</script>

子组件中Input的 $event到底是什么,以及什么时候可以.target。
对于原生事件来说, $event就是事件对象。
对于自定义事件来说, $event就是触发事件时,所传递的数据。

方式五:$attrs

适用于当前组件的父组件 和 当前组件的子组件通信,便于理解可以视为「祖孙」间通信

父组件

<template>
  <div class="father">
    父组件
    <Son :a="a" :b="b" :data="{ c, d }" />
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue"
import Son from "./Son.vue"

let a = ref("a")
let b = ref("b")
let c = ref("c")
let d = ref("d")
</script>

<style scoped>
.father {
  border: 1px solid #333;
  border-radius: 10px;
  padding: 20px;
}
</style>

子组件

<template>
  <div class="son">
    子组件 --- 父值a:{{ a }}
    <Sun />
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue"
import Sun from "./Sun.vue"

defineProps(["a"])
</script>

<style scoped>
.son {
  border: 1px solid skyblue;
  border-radius: 10px;
  padding: 20px;
}
</style>

子组件中未通过defineProps接收的值,会出现在attrs。

在这里插入图片描述
可以在子组件中,将 $attrs 再传递给子组件的子组件,也就是「孙组件」。

<template>
  <div class="son">
    子组件 --- 父值a:{{ a }}
    <Sun v-bind="$attrs" />
  </div>
</template>

切换到「孙组件」,可以看到在子组件中接收的a并没有一起传递。

在这里插入图片描述
孙组件根据attrs中属性名,接收值

<template>
  <div class="sun">孙组件</div>
  <div>b --- {{ b }}</div>
  <div>c --- {{ data.c }}</div>
  <div>d --- {{ data.d }}</div>
</template>

<script setup lang="ts">
import { ref } from "vue"

defineProps(["b", "data"])
</script>

<style scoped>
.sun {
  border: 1px solid #f5d8dc;
  border-radius: 10px;
  padding: 20px;
}
</style>

至此,「祖」向「孙」方向数据传递完毕,「孙」向「祖」同props传递一个函数即可。

父组件

<template>
  <div class="father">
    父组件
    <Son :a="a" :b="b" :data="{ c, d }" :changeD="changeD" /> // 函数传递
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue"
import Son from "./Son.vue"

let a = ref("a")
let b = ref("b")
let c = ref("c")
let d = ref("d")
// 定义函数
function changeD(params: string) {
  d.value = params
}
</script>

<style scoped>
.father {
  border: 1px solid #333;
  border-radius: 10px;
  padding: 20px;
}
</style>

子组件中由于未接收除a外的props,只是把attrs传递给孙组件,所以无需修改,此时attrs中多了父组件中刚刚定义好的函数。

孙组件 定义触发函数,传递数据

<template>
  <div class="sun">孙组件</div>
  <div>b --- {{ b }}</div>
  <div>c --- {{ data.c }}</div>
  <div>d --- {{ data.d }}</div>

  <button @click="changeD('e')">改变</button>  // 触发函数并将参数传给祖组件
</template>

<script setup lang="ts">
import { ref } from "vue"

defineProps(["b", "data", "changeD"])  // 接收祖组件中的函数
</script>

<style scoped>
.sun {
  border: 1px solid #f5d8dc;
  border-radius: 10px;
  padding: 20px;
}
</style>

方式六:$refs $parent

适用于父组件与多个子组件间的通信

子组件中通过defineExpose将数据暴露

<template>
  <div class="son">子组件1 ---- {{ son1_data }}</div>
</template>

<script setup lang="ts">
import { ref } from "vue"
let son1_data = ref("111")
// 把数据交给外部
defineExpose({ son1_data })
</script>

<style scoped>
.son {
  border: 1px solid skyblue;
  border-radius: 10px;
  padding: 20px;
}
</style>

父组件中通过ref,直接修改子组件中数据

<template>
  <div class="father">
    父组件
    <Son1 ref="s1" />
    <Son2 />
    <button @click="changeSonData">修改子数据</button>
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue"
import Son1 from "./Son1.vue"
import Son2 from "./Son2.vue"

let s1 = ref()
function changeSonData() {
  s1.value.son1_data = "父组件修改后的数据"
}
</script>

<style scoped>
.father {
  border: 1px solid #333;
  border-radius: 10px;
  padding: 20px;
}
</style>

如果需要同时修改多个子组件,可以使用 $refs

父组件

<template>
  <div class="father">
    父组件
    <button @click="changeSonData">修改子数据</button>
    <button @click="getAllChild($refs)">getall</button>
    <Son1 ref="s1" />
    <Son2 ref="s2" />
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue"
import Son1 from "./Son1.vue"
import Son2 from "./Son2.vue"

let s1 = ref()
let s2 = ref()
function changeSonData() {
  s1.value.son1_data = "父组件修改后的数据"
}
function getAllChild(refs: object) {
  console.log(refs)
}
</script>

<style scoped>
.father {
  border: 1px solid #333;
  border-radius: 10px;
  padding: 20px;
}
</style>

触发getall按钮,发现打印如下,即所有绑定ref的元素

在这里插入图片描述

可以循环该参数,批量修改子组件中同名数据

function getAllChild(refs: { [key: string]: any }) {
  for (const key in refs) {
    refs[key].money += 10
  }
}

子组件通过$parent可以修改父组件中的值

<button @click="getMoney($parent)">获取money</button>
function getMoney(parent: any) {
  parent.money -= 10
}

父组件中暴露数据

defineExpose({ money })

方式七:provide inject

适用于任意组件间通信,以下以爷爷组件与孙组件通信为例

父组件:provide提供数据,第一个参数为数据标识名,第二个参数为数据值。

<template>
  <div class="father">
    父组件
    <div>余额:{{ money }}</div>
    <Son />
  </div>
</template>

<script setup lang="ts">
import { provide, ref } from "vue"
import Son from "./Son.vue"

let money = ref(1000)

function reduceMoney(value: number) {
  money.value -= value
}

provide("balanceContext", { money, spendMoney: reduceMoney }) // 提供数据
</script>

<style scoped>
.father {
  border: 1px solid #333;
  border-radius: 10px;
  padding: 20px;
}
</style>

如果下载了扩展,自动补全了.value请手动删除,这么做会丢失响应式。
在这里插入图片描述

子组件:不同于$attrs,无需进行任何操作

<template>
  <div class="son">
    子组件
    <Sun />
  </div>
</template>

<script setup lang="ts">
import Sun from "./Sun.vue"
</script>

<style scoped>
.son {
  border: 1px solid skyblue;
  border-radius: 10px;
  padding: 20px;
}
</style>

孙组件:inject注入数据,第一个参数为数据标识名,要与provide中命名一致,第二个参数为默认值。

<template>
  <div class="sun">孙组件</div>
  <div>爷爷的余额 --- {{ money }}</div>
  <button @click="spendMoney(1)">花爷爷的钱</button>
</template>

<script setup lang="ts">
import { inject, ref } from "vue"
const { money, spendMoney } = inject("balanceContext", {
  money: 0,
  spendMoney: (p: number) => {},
}) // 注入数据
</script>

<style scoped>
.sun {
  border: 1px solid #f5d8dc;
  border-radius: 10px;
  padding: 20px;
}
</style>

方式八:Slot

在子组件中的展示内容需要依赖父组件中的数据的场景下,就可以使用插槽。
插槽分为三种,分别是默认插槽、具名插槽以及作用于插槽

默认插槽

父组件:在子组件标签内部写结构

<template>
  <div class="father">
    <h2>父组件</h2>
    <Son :title="title">
      <ul>
        <li v-for="item in list" :key="item.id">{{ item.verses }}</li>
      </ul>
    </Son>
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue"
import Son from "./Son.vue"

let title = ref("蝶恋花·阅尽天涯离别苦")
let list = ref([
  { id: 1, verses: "待把相思灯下诉" },
  { id: 2, verses: "一缕新欢" },
  { id: 3, verses: "旧恨千千缕" },
  { id: 4, verses: "最是人间留不住" },
  { id: 5, verses: "朱颜辞镜花辞树" },
])
</script>

<style scoped>
.father {
  border: 1px solid #333;
  border-radius: 10px;
  padding: 20px;
}
</style>

子组件:使用slot标签占位,接收父组件中标签内部的结构,如为空,展示slot标签内部内容。

<template>
  <div class="son">
    <h3>子组件</h3>
    <div>{{ title }}</div>
    <slot>默认值</slot>
  </div>
</template>

<script setup lang="ts">
defineProps(["title"])
</script>

<style scoped>
.son {
  border: 1px solid skyblue;
  border-radius: 10px;
  padding: 20px;
}
</style>

具名插槽

默认插槽只支持一块模版,如果子组件中需要多个slot,就需要通过标识区分这些插槽,这就是具名插槽。

父组件:将多个插槽内容分别包裹template标签,添加v-slot属性,:后是插槽名。
注意:老版本v-slot=""的写法不再推荐了,建议使用 :插槽名。

<template>
  <div class="father">
    <h2>父组件</h2>
    <Son>
      <template v-slot:t1>
        <h4>{{ title }}</h4>
      </template>
      <template v-slot:t2>
        <ul>
          <li v-for="item in list" :key="item.id">{{ item.verses }}</li>
        </ul>
      </template>
    </Son>
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue"
import Son from "./Son.vue"

let title = ref("蝶恋花·阅尽天涯离别苦")
let list = ref([
  { id: 1, verses: "待把相思灯下诉" },
  { id: 2, verses: "一缕新欢" },
  { id: 3, verses: "旧恨千千缕" },
  { id: 4, verses: "最是人间留不住" },
  { id: 5, verses: "朱颜辞镜花辞树" },
])
</script>

<style scoped>
.father {
  border: 1px solid #333;
  border-radius: 10px;
  padding: 20px;
}
</style>

通过编译器警告可以发现,v-slot只能用于组件或者template标签上。
在这里插入图片描述

v-slot: 语法糖写法为 #
在这里插入图片描述

子组件:slot标签中添加name属性,值需与父组件中v-slot:后的插槽名保持一致。

<template>
  <div class="son">
    <h3>子组件</h3>
    <slot name="t1">默认标题</slot>

    <!-- 子组件中的元素 -->
    <div>清·王国维</div>

    <slot name="t2">默认内容</slot>
  </div>
</template>

<script setup lang="ts">
defineProps(["title"])
</script>

<style scoped>
.son {
  border: 1px solid skyblue;
  border-radius: 10px;
  padding: 20px;
}
</style>

作用域插槽

如果渲染结构依赖的数据在子组件中,但是结构需要在父组件中声明。子组件就可以使用作用域插槽,将变量通过插槽传递给父组件。

需求:现有Son子组件,其中有数据list。父组件中需要展示三次子组件,分别以ul、ol、以及div标签遍历子组件中的list,并渲染。

子组件:将数据以slot属性的形式传递。

<template>
  <div class="son">
    <h3>子组件</h3>
    <slot :list="list" user="田本初"></slot>
  </div>
</template>

<script setup lang="ts">
import { reactive } from "vue"

let list = reactive([
  { id: 1, verses: "待把相思灯下诉" },
  { id: 2, verses: "一缕新欢" },
  { id: 3, verses: "旧恨千千缕" },
  { id: 4, verses: "最是人间留不住" },
  { id: 5, verses: "朱颜辞镜花辞树" },
])
</script>

<style scoped>
.son {
  border: 1px solid skyblue;
  border-radius: 10px;
  padding: 20px;
}
</style>

父组件:使用v-slot接收参数,其中包含了slot标签上所有props。
在这里插入图片描述

<template>
  <div class="father">
    <h2>父组件</h2>
    <Son>
      <template v-slot="params">
        <h4>{{ title }}</h4>
        <ul>
          <li v-for="item in params.list" :key="item.id">{{ item.verses }}</li>
        </ul>
      </template>
    </Son>
    <Son>
      <!-- 可以解构 -->
      <template v-slot="{ list }">
        <h4>{{ title }}</h4>
        <ol>
          <li v-for="item in list" :key="item.id">{{ item.verses }}</li>
        </ol>
      </template>
    </Son>
    <Son>
      <template v-slot="params">
        <h4>{{ title }}</h4>
        <div v-for="item in params.list" :key="item.id">{{ item.verses }}</div>
      </template>
    </Son>
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue"
import Son from "./Son.vue"

let title = ref("蝶恋花·阅尽天涯离别苦")
</script>

<style scoped>
.father {
  border: 1px solid #333;
  border-radius: 10px;
  padding: 20px;
}
</style>

如果使用的是具名插槽

子组件:slot标签中添加name属性

<slot name="son" :list="list" user="田本初"></slot>

父组件:template标签的v-slot后添加 :name,也可以使用语法糖。

<template v-slot:son="params"></template>

<template #son="params"></template>

方式九:Pinia

目前最适用于大量数据以及组件间通信的方式

配置与使用具体可参考另一篇文章:搭建Pinia环境及其基本使用,其中有详细说明。

总结

父传子

  • Props
  • v-model
  • $refs
  • 默认插槽、具名插槽

子传父

  • Props
  • 自定义事件
  • v-model (Props方式的语法糖)
  • $parent (优势:通过 $refs 父组件可同时操作多个子组件)
  • 作用域插槽

祖孙通信

  • $attrs(父传子,子不接收props继续传给孙组件)
  • provide inject (无需通过子组件,父组件可以直接传递给任意后代组件)

任意组件间通信

  • mitt
  • pinia 推荐

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/484596.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

6. ping在windows中的常见用法

&#xff08;1&#xff09;ping简介 1.ping简介 &#xff08;2&#xff09;在windows上用法 1.直接ping 对方IP&#xff08;无参数时&#xff09; 2.ping -t IP (长ping) 3.ping -n 包数量 4.ping -l 字节大小 IP 5.如何批量的ping一个网段&#xff1f; &#xff08;1&a…

24计算机考研调剂 | 【官方】山东工商学院

山东工商学院 考研调剂招生信息 招生专业&#xff1a; 学院概况&#xff1a; 计算机科学与技术学院始建于1999年&#xff0c;拥有计算机科学与技术一级学科硕士点,在2022软科中国最好学科排名中&#xff0c;计算机科学与技术学科位列全国第104位。在2022年“软科”中国大学专…

【MySQL】2.MySQL数据库的基本操作

目录 数据库基本操作 查看数据库信息 查看数据库结构 显示数据表的结构&#xff08;字段&#xff09; 常用的数据类型 数据库管理操作 SQL语句概述 SQL分类 1.DDL&#xff1a;数据定义语言 1.1创建数据库和表 创建数据库 创建数据表 1.2删除数据库和表 删除数据表…

音视频领域首个,阿里云推出华为鸿蒙 HarmonyOS NEXT 版音视频 SDK

近日&#xff0c;阿里云在官网音视频终端 SDK 栏目发布适配 HarmonyOS NEXT 的操作文档和 SDK&#xff0c;官宣 MediaBox 音视频终端 SDK 全面适配 HarmonyOS NEXT。 此外&#xff0c;阿里云播放器 SDK 也在华为开发者联盟官网鸿蒙生态伙伴 SDK 专区同步上线&#xff0c;面向所…

SpringCloud-记

目录 什么是SpringCloud 什么是微服务 SpringCloud的优缺点 SpringBoot和SpringCloud的区别 RPC 的实现原理 RPC是什么 eureka的自我保护机制 Ribbon feigin优点 Ribbon和Feign的区别 什么是SpringCloud Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发…

STM32之HAL开发——系统定时器(SysTick)

系统定时器&#xff08;SysTick&#xff09;介绍 SysTick—系统定时器是属于 CM3 内核中的一个外设&#xff0c;内嵌在 NVIC 中。系统定时器是一个 24bit的向下递减的计数器&#xff0c;计数器每计数一次的时间为 1/SYSCLK&#xff0c;一般我们设置系统时钟 SYSCLK等于 72M。当…

人工智能之Tensorflow变量作用域

在TensoFlow中有两个作用域&#xff08;Scope&#xff09;&#xff0c;一个时name_scope ,另一个是variable_scope。variable_scope主要给variable_name加前缀&#xff0c;也可以给op_name加前缀&#xff1b;name_scope给op_name加前缀。 variable_scope 通过所给的名字创建或…

【电路笔记】-场效应管(FET)电流源

场效应管(FET)电流源 文章目录 场效应管(FET)电流源1、概述2、偏置结 FET2.1 N沟道JFET偏置2.2 N沟道JFET输出特性3、JFET 作为恒流源4、JFET 零电压偏置5、JFET 负电压偏置6、FET 恒流源示例17、JFET电流源8、FET 恒流源示例29、FET 恒流源示例310、总结FET 恒流源使用 JFET 和…

Java学习笔记NO.26

T3.以面向对象的思想&#xff0c;编写自定义类描述IT从业者。 设定属性包括&#xff1a;姓名&#xff0c;年龄&#xff0c;技术方向&#xff0c;工作年限&#xff1b; 方法包括&#xff1a;工作。 要求&#xff1a; (1)设置属性的私有访问权限&#xff0c;通过公有的get,set…

业务服务:redisson

文章目录 前言一、配置1. 添加依赖2. 配置文件/类3. 注入redission3. 封装工具类 二、应用1. RedisUtils工具类的基本使用 三、队列1. 工具类2. 普通队列3. 有界队列&#xff08;限制数据量&#xff09;4. 延迟队列&#xff08;延迟获取数据&#xff09;5. 优先队列&#xff08…

Netty - 五种 I/O 多路复用机制 select、poll、epoll、kqueue、iocp(windows) 对比

文章目录 Preselect、poll、epoll、kqueue、iocp(windows) Pre 高性能网络编程 - select、 poll 、epoll 、libevent select、poll、epoll、kqueue、iocp(windows) 这里我将对比一下常见的多路复用技术&#xff1a;select、poll、epoll、kqueue 和 IOCP&#xff08;Windows&a…

分区表索引失效导致业务异常

业务无法正常进行&#xff0c;查看数据库后台进程&#xff0c;发现有大量阻塞 QL_ID WAIT_CLASS EVENT ------------- --------------- ------------------------- 1cpk7srb6cr0r User I/O db file scattered read 279knu21n06x6…

音视频开发之旅(78)- Docker使用和交互流程

目录 1.Docker是什么 2.DockerFile的使用 3.常用命令 4.Docker和Web服务的交互流程 5.资料 一、Docker是什么 Docker通过轻量级的容器化技术&#xff0c;使得应用程序及其依赖可以打包在一个可移植的容器中运行&#xff0c;确保应用在不同环境下的一致性和效率。 1.1 核心…

中断(NVIC)的使用--EXTI--TIM

目录 中断是什么 轮询 中断 中断调用情况 中断的分类 内部中断&#xff08;TIM、UART等&#xff09; tim.c tim.h 外部中断EXTI exti.c exti.h 中断是什么 在处理事件的时候有两种方式&#xff1a;轮询和中断。 轮询 顾名思义&#xff0c;就是每轮都询问一次。比如…

结构体类型详细讲解(附带枚举,联合)

前言&#xff1a; 如果你还对结构体不是很了解&#xff0c;那么本篇文章将会从 为什么存在结构体&#xff0c;结构体的优点&#xff0c;结构体的定义&#xff0c;结构体的使用与结构体的大小依次介绍&#xff0c;同样会附带枚举与联合体 目录 为什么存在结构体&#xff1a; 结构…

毕业设计:日志记录编写(3/17起更新中)

目录 3/171.配置阿里云python加速镜像&#xff1a;2. 安装python3.9版本3. 爬虫技术选择4. 数据抓取和整理5. 难点和挑战 3/241.数据库建表信息2.后续进度安排3. 数据处理和分析 3/17 当前周期目标&#xff1a;构建基本的python环境&#xff1a;运行爬虫程序 1.配置阿里云pytho…

【C++】如何用一个哈希表同时封装出unordered_set与unordered_map

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》《算法》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 目录 前言 1.哈希桶源码 2.哈希…

(三维重建学习)已有位姿放入colmap和3D Gaussian Splatting训练

这里写目录标题 一、colmap解算数据放入高斯1. 将稀疏重建的文件放入高斯2. 将稠密重建的文件放入高斯 二、vkitti数据放入高斯 一、colmap解算数据放入高斯 运行Colmap.bat文件之后&#xff0c;进行稀疏重建和稠密重建之后可以得到如下文件结构。 1. 将稀疏重建的文件放入高…

windows10 WSL启动Ubuntu虚拟机,安装DolphinScheduler

文章目录 1. 启动WSL与虚拟机2. 安装Docker与DolphinScheduler容器 1. 启动WSL与虚拟机 使用管理员权限运行命令&#xff1a; Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux重启后即可创建虚拟机 在Microsoft Store中搜索Ubuntu&…

Wear-Any-Way——可控虚拟试衣一键试穿,可自定义穿着方式

概述 Wear-Any-Way 是阿里巴巴最新推出的虚拟试衣技术&#xff0c;它不仅可以让用户在虚拟环境中试穿衣服&#xff0c;还可以根据需要自定义衣服的样式&#xff0c;比如卷起袖子、打开或拖动外套等。这种技术的引入旨在帮助消费者更好地了解衣服在不同穿着方式下的效果&#x…