学习Vue3的第四天

目录

pinia

安装 Pinia

存储+读取数据

修改数据(三种方式)

storeToRefs

getters

$subscribe

store组合式写法

组件通信

props

自定义事件

mitt

v-model

$attrs

$refs、$parent

provide、inject

slot


pinia

Pinia 是一个用于 Vue.js 的状态管理库,作为 Vuex 的替代方案,旨在提供更简单、更灵活的状态管理功能。它与 Vue 3 紧密集成,充分利用了 Vue 的 Composition API,提供了更直观的 API 和更强大的功能。

安装 Pinia

npm install pinia

操作 src/main.ts

import { createPinia } from 'pinia';
import { createApp } from 'vue';
import App from './App.vue';const pinia = createPinia();
const app = createApp(App);app.use(pinia);
app.mount('#app');

存储+读取数据

Store 是一个保存:状态、业务逻辑 的实体,每个组件都可以读取、写入它。

在 Pinia 中,可以使用 defineStore 来定义一个 store。这个 store 包括 state、getters 和 actions,相当于组件中的: `data`、 `computed` 和 `methods`。

import { defineStore } from 'pinia';
import axios from 'axios';
import { nanoid } from 'nanoid';// 定义一个名为useLoveTalkStore的Pinia存储模块
export const useLoveTalkStore = defineStore('loveTalk', {// 定义模块的状态state: () => ({talkList: [{ id: 'yuysada01', content: '你今天有点怪,哪里怪?怪好看的!' },{ id: 'yuysada02', content: '草莓、蓝莓、蔓越莓,你想我了没?' },{ id: 'yuysada03', content: '心里给你留了一块地,我的死心塌地' }]}),// 定义模块的动作actions: {// 异步获取情话并添加到列表中async getLoveTalk() {try {// 发起HTTP GET请求获取随机情话const { data: { content: title } } = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json');// 生成唯一ID并创建新的情话语对象const obj = { id: nanoid(), content: title };// 将新的情话添加到列表后面this.talkList.push(obj);} catch (error) {// 请求失败时输出错误信息console.error('Error fetching love talk:', error);}}}
});
<template><div><!-- 按钮用于获取爱情话语 --><button @click="fetchLoveTalk">Get Love Talk</button><!-- 循环显示爱情话语列表 --><ul><li v-for="talk in loveTalkStore.talkList" :key="talk.id">{{ talk.content }}</li></ul></div>
</template><script lang="ts">
import { defineComponent } from 'vue';
import { useLoveTalkStore } from '@/store/talk';export default defineComponent({setup() {// 使用爱情话语的storeconst loveTalkStore = useLoveTalkStore();/*** 获取爱情话语的方法*/const fetchLoveTalk = async () => {await loveTalkStore.getLoveTalk();};return { loveTalkStore, fetchLoveTalk };}
});
</script>

修改数据(三种方式)

直接修改

直接通过 store 的 state 属性来修改数据:

countStore.sum = 666;

这种方式简单直接,但通常建议避免直接修改,因为这可能绕过一些管理逻辑(比如响应式更新)。

批量修改

使用 $patch 方法批量更新多个属性:

countStore.$patch({sum: 999,school: 'atguigu'
});

$patch 方法允许一次性更新 store 的多个属性,并且它会保留之前的其他属性值。

通过 Action 修改

在 store 中定义 actions,以便在更新数据时可以包含额外的业务逻辑:

import { defineStore } from 'pinia';export const useCountStore = defineStore('count', {state: () => ({sum: 0,school: ''}),actions: {// 加increment(value: number) {if (this.sum < 10) {this.sum += value;}},// 减decrement(value: number) {if (this.sum > 1) {this.sum -= value;}}}
});

使用 actions 的好处在于可以在状态更新之前或之后执行额外的逻辑,比如检查条件、调用其他函数等。

组件中调用 Action

在组件中,可以通过 store 实例调用 actions:

import { useCountStore } from './stores/countStore'; // 假设 store 定义在 countStore 文件中export default {setup() {const countStore = useCountStore();// 示例:调用 increment 方法const incrementValue = 5;countStore.increment(incrementValue);// 示例:调用 decrement 方法const decrementValue = 2;countStore.decrement(decrementValue);}
};

storeToRefs

storeToRefs 函数将 Pinia store 中的 state 数据转换为 Vue 的 ref 对象,从而使得这些数据在模板中保持响应性。

这与 Vue 的 toRefs 函数类似,但 storeToRefs 特别针对 Pinia 的 store 设计,确保了 store 数据的响应式管理(`pinia`提供的`storeToRefs`只会将数据做转换,而`Vue`的`toRefs`会转换`store`中数据。)。使用 storeToRefs 使得组件模板中对 store 的引用更加清晰和简洁。

<template><div class="count"><h2>当前求和为:{{sum}}</h2></div>
</template><script setup lang="ts" name="Count">import { useCountStore } from '@/store/count'/* 引入storeToRefs */import { storeToRefs } from 'pinia'/* 得到countStore */const countStore = useCountStore()/* 使用storeToRefs转换countStore,随后解构 */const {sum} = storeToRefs(countStore)
</script>

storeToRefs 的优势

  • 保持响应性: 使用 storeToRefs 可以确保 store 的属性在模板中保持响应性。它将 state 属性转换为 ref 对象,从而可以在模板中直接使用。
  • 简化代码: 在模板中直接使用 storeToRefs 转化的属性,避免了对 countStore.sum 的直接引用,代码更简洁。
  • 提高可维护性: 对于较大的 store,使用 storeToRefs 可以避免直接解构 state 对象,提高代码的可维护性和清晰度。

getters

getters 是用于从 state 中派生计算值的属性,它们可以看作是 state 的“计算属性”。

  • 计算属性:getters 可以对 state 中的数据进行处理,返回一个计算后的值。
  • 缓存:getters 是基于其依赖的 state 缓存的,只有当依赖的 state 发生变化时,getters 才会重新计算。
  • 使用方法:可以在组件中直接访问 getters,它们就像普通的属性一样。
import { defineStore } from 'pinia';/*** 定义一个名为Counter的Pinia存储* 该存储用于管理计数器相关的状态和操作*/
export const useCounterStore = defineStore('counter', {/*** 定义存储的状态* 返回一个包含初始状态的对象*/state: () => ({count: 0, // 计数器的当前值message: '你好,Pinia!' // 欢迎消息}),/*** 定义Getter,用于处理状态并返回结果*/getters: {/*** 获取计数器值的两倍* @param state 当前的状态* @returns 计数器值的两倍*/doubledCount: (state) => state.count * 2,/*** 将消息转换为大写* @param state 当前的状态* @returns 大写的消息*/uppercaseMessage: (state) => state.message.toUpperCase()},/*** 定义可以修改状态的方法*/actions: {/*** 增加计数器的值*/increment() {this.count++;},/*** 更新消息* @param newMessage 新的消息内容*/updateMessage(newMessage) {this.message = newMessage;}}
});
<template><div><!-- 显示计算后的计数值 --><p>计数: {{ doubledCount }}</p><!-- 显示转换为大写的消息 --><p>消息: {{ uppercaseMessage }}</p><!-- 触发计数增加的操作按钮 --><button @click="increment">增加</button><!-- 输入框,用于用户输入新的消息 --><input v-model="newMessage" placeholder="输入新消息" /><!-- 触发消息更新的操作按钮 --><button @click="updateMessage">修改消息</button></div>
</template><script setup>
import { storeToRefs } from 'pinia';
import { useCounterStore } from '@/store/counterStore';// 获取计数和消息的计算属性以及定义新的消息引用
const counterStore = useCounterStore();
// 将store中的属性转换为Vue中的ref,以便在模板中使用
const { doubledCount, uppercaseMessage } = storeToRefs(counterStore);
const newMessage = ref('');// 增加计数
function increment() {counterStore.increment();
}// 更新消息
function updateMessage() {counterStore.updateMessage(newMessage.value);
}
</script>

$subscribe

$subscribe 是 Pinia 中用于侦听 state 变化的一个方法。可以用它来监控 state 的任何变化,并在变化发生时执行特定的操作。它允许对 store 的 state 进行观察和响应。

talkStore.$subscribe((mutate,state)=>{console.log('LoveTalk',mutate,state)localStorage.setItem('talk',JSON.stringify(talkList.value))
})

store组合式写法

import {defineStore} from 'pinia';export const useCounterStore = defineStore('counter', {state: () => ({count: 0,}),actions: {increment() {this.count++;},decrement() {this.count--;},},
});
<template><div><p>计数: {{ counterStore.count }}</p><button @click="counterStore.increment">增加</button><button @click="counterStore.decrement">减少</button></div>
</template><script setup>
import {useCounterStore} from '@/store/counterStore';const counterStore = useCounterStore();
</script>

组件通信

在 Vue 3 中,组件通信与 Vue 2 相比有一些显著的变化:

事件总线:

  • Vue 2:常用事件总线进行组件间的通信。
  • Vue 3:推荐使用 mitt 或其他轻量级的事件库,作为事件总线的替代方案。mitt 是一个小巧的事件发射器,可以很方便地用来处理组件之间的事件。

状态管理:

  • Vue 2:使用 vuex 进行状态管理。
  • Vue 3:pinia 作为推荐的状态管理库,提供了更简洁的 API 和更好的 TypeScript 支持。

双向绑定:

  • Vue 2:使用 .sync 修饰符来处理双向绑定。
  • Vue 3:将 .sync 的功能优化到了 v-model 中,使得双向绑定更加一致和简洁。你可以通过在 v-model 上自定义事件名称来实现类似 .sync 的功能。

事件和属性:

  • Vue 2:使用 $listeners 来访问和传递事件监听器。
  • Vue 3:将 $listeners 和其他属性合并到 $attrs 中,可以通过 v-bind="$attrs" 来传递这些属性。

子组件访问:

  • Vue 2:可以通过 $children 访问子组件。
  • Vue 3:去掉了 $children,推荐使用 ref 和 expose 来访问和操作子组件。使用 ref 可以更精确地控制子组件实例的引用。

props

在 Vue 中,props 是一种常用的组件间通信方式,主要用于 父组件到子组件 的数据传递。

父组件:

<template><div class="parent"><!-- 按钮用于触发获取随机情话的事件 --><button @click="fetchQuote">获取随机情话</button><!-- 子组件用于展示获取到的随机情话 --><ChildComponent :message="randomQuote" /></div>
</template><script setup>
import {ref} from 'vue';
import axios from 'axios';
import ChildComponent from './demos.vue';// 定义一个响应式变量来存储随机情话
const randomQuote = ref('');/*** 异步函数,用于从API获取随机情话*/
const fetchQuote = async () => {try {// 使用axios库从指定API获取随机情话const {data: {content}} = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json');// 将获取到的情话内容赋值给randomQuote变量randomQuote.value = content;} catch (error) {// 如果发生错误,输出错误信息到控制台console.error('Failed to fetch quote:', error);}
};
</script><style scoped>
.parent {background-color: #f0f8ff; /* 轻微蓝色背景,用于区分页面其他部分 */padding: 20px;border-radius: 8px;
}
</style>

子组件

<template><!-- 这个模板用来显示从父组件传递的消息 --><div class="child"><p>{{ message }}</p></div>
</template><script setup>
import {defineProps} from 'vue';// 定义组件接受的props,包括一个名为message的字符串类型属性
const props = defineProps({message: String
});
</script><style scoped>
/* 为.child类定义样式,使其具有轻微的绿色背景,适当的内边距和圆角 */
.child {background-color: #e6ffe6; /* 轻微绿色背景 */padding: 10px;border-radius: 4px;margin-top: 10px;
}
</style>

总结

  • 父传子:通过 props 传递数据,属性值通常是静态数据或者动态计算的值。
  • 子传父:通过自定义事件(例如使用 emit)将数据传递回父组件。子组件触发事件,父组件处理事件并获取数据。

这种方式保证了数据流的单向性,父组件将数据传递给子组件,子组件通过事件向父组件反馈变化。

自定义事件

自定义事件是 Vue 中用来实现子组件与父组件之间通信的一种方式。

概述

自定义事件用于子组件向父组件传递信息。子组件通过 emit 方法触发事件,父组件通过 v-on 监听这些事件并响应。

区分原生事件与自定义事件

原生事件

  • 事件名是固定的,如 click、mouseenter 等。
  • 事件对象 $event 包含关于事件的详细信息,如 pageX、pageY、target 和 keyCode。

自定义事件

  • 事件名是任意名称,如 update, customEvent 等。
  • 事件对象 $event 是触发事件时通过 emit 方法传递的数据,可以是任何类型的值。

子组件

<template><div class="parents"><button @click="fetchQuote">获取随机情话</button></div>
</template><script setup>
import {defineEmits} from 'vue';
import axios from 'axios';// 定义可用于子组件向父组件发送信息的自定义事件
const emit = defineEmits(['quoteReceived']);/*** 异步获取随机情话并发送到父组件*/
const fetchQuote = async () => {try {// 使用axios库从API获取随机情话数据const {data: {content}} = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json');// 触发自定义事件,将获取到的情话内容传递给父组件emit('quoteReceived', content);} catch (error) {// 在控制台记录获取情话失败的错误信息console.error('获取情话失败:', error);}
};
</script><style scoped>
.parents {background-color: #ffcccb; /* 浅红色背景 */border: none;padding: 10px 20px;border-radius: 5px;cursor: pointer;
}
</style>

父组件:

<template><div class="parent"><!-- 引入子组件,并监听quoteReceived事件 --><ChildComponent @quoteReceived="handleQuoteReceived" /><!-- 条件性渲染接收到的报价 --><p v-if="quote">{{ quote }}</p></div>
</template><script setup>
import {ref} from 'vue';
import ChildComponent from './ChildComponent.vue';// 定义一个响应式变量quote来存储报价信息
const quote = ref('');/*** 处理接收到的报价数据* @param {string} receivedQuote - 接收到的报价字符串*/
const handleQuoteReceived = (receivedQuote) => {quote.value = receivedQuote;
};
</script><style scoped>
.parent {background-color: #e6e6ff; /* 浅蓝色背景 */padding: 20px;border-radius: 8px;
}
</style>

mitt

mitt 是一个轻量级的事件发布/订阅库,适用于组件间通信,特别是在 Vue.js 或其他前端框架中。它可以用来在不同组件间传递消息,而无需组件之间直接依赖。

安装 mitt

npm install mitt

创建一个事件总线

import mitt from 'mitt';
const emitter = mitt();
export default emitter;

在子组件中发布事件

<template><button @click="sendMessage">发送消息</button>
</template><script setup>
import emitter from './eventBus.ts';const sendMessage = () => {emitter.emit('message', 'Hello from child!');
};
</script><style scoped>
button {background-color: #ffcccb;border: none;padding: 10px 20px;border-radius: 5px;cursor: pointer;
}
</style>

在父组件中订阅事件

<template><div><ChildComponent /><p v-if="message">{{ message }}</p></div>
</template><script setup>
import {ref, onMounted, onUnmounted} from 'vue';
import emitter from './eventBus.ts';
import ChildComponent from './ChildComponent.vue';const message = ref('');const handleMessage = (msg) => {message.value = msg;
};onMounted(() => {emitter.on('message', handleMessage);
});onUnmounted(() => {emitter.off('message', handleMessage);
});
</script><style scoped>
div {background-color: #e6e6ff;padding: 20px;border-radius: 8px;
}
</style>

v-model

v-model 是 Vue.js 中用于双向数据绑定的指令,它可以轻松地实现父子组件之间的通信。在 Vue.js 中,v-model 通常用于表单元素(如 <input>, <textarea>, <select>),但它也可以用于自定义组件以实现父子组件间的双向数据绑定。

基础示例

假设我们有一个父组件和一个子组件,父组件希望通过 v-model 来双向绑定子组件中的数据。

子组件

<template><div><input v-bind="inputProps" @input="updateValue"/></div>
</template><script setup>
import {defineProps, defineEmits} from 'vue';const props = defineProps({modelValue: String, // 这里定义了 v-model 的绑定值
});const emit = defineEmits(['update:modelValue']); // 触发事件来更新 v-model 绑定的值const updateValue = (event) => {emit('update:modelValue', event.target.value); // 当输入值改变时,触发事件更新父组件的数据
};
</script>
<style scoped>
div {background-color: #ffcccb;padding: 20px;border-radius: 8px;
}
</style>

父组件

<template><div><ChildComponent v-model="parentValue" /><p>父组件中的值: {{ parentValue }}</p></div>
</template><script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';const parentValue = ref(''); // 父组件中的数据</script>
<style scoped>
div {background-color: #e6e6ff;padding: 20px;border-radius: 8px;
}
</style>

$attrs

概述

$attrs 是 Vue.js 提供的一个特殊对象,用于在当前组件中接收并传递父组件传递的属性,这些属性未被当前组件声明为 props。它支持从祖组件到孙组件的通信。

具体说明

$attrs 包含所有父组件传递的非 props 属性(如 HTML 属性、用户自定义属性等),但排除了已在子组件中声明的 props。这样,子组件可以通过 $attrs 将这些属性继续传递给孙组件,确保属性链的完整传递。

父组件:

<template><div class="father"><h3>父组件</h3><Child :a="a" :b="b" :c="c" :d="d" v-bind="{x:100,y:200}" :updateA="updateA"/></div>
</template><script setup lang="ts" name="Father">import Child from './Child.vue'import { ref } from "vue";let a = ref(1)let b = ref(2)let c = ref(3)let d = ref(4)function updateA(value){a.value = value}
</script>

子组件:

<template><div class="child"><h3>子组件</h3><GrandChild v-bind="$attrs"/></div>
</template><script setup lang="ts" name="Child">import GrandChild from './GrandChild.vue'
</script>

孙组件:

<template><div class="grand-child"><h3>孙组件</h3><h4>a:{{ a }}</h4><h4>b:{{ b }}</h4><h4>c:{{ c }}</h4><h4>d:{{ d }}</h4><h4>x:{{ x }}</h4><h4>y:{{ y }}</h4><button @click="updateA(666)">点我更新A</button></div>
</template><script setup lang="ts" name="GrandChild">defineProps(['a','b','c','d','x','y','updateA'])
</script>

$refs、$parent

$refs

用途:父组件 → 子组件

概述:$refs 是一个对象,包含所有被 ref 属性标识的 DOM 元素或子组件实例。它允许你直接访问子组件或 DOM 元素,通常用于在父组件中调用子组件的方法或操作 DOM。

$parent

用途:子组件 → 父组件

概述:$parent 是当前组件实例的父组件实例对象。通过 $parent,子组件可以访问父组件的方法、数据或其他属性。然而,过度使用 $parent 可能会使组件之间的耦合变得紧密,影响可维护性。

示例

<template><div><h1>{{ message }}</h1><ChildComponent ref="childComponentRef" /><button @click="callChildMethod">调用子组件的方法</button></div>
</template><script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';// 定义数据
const message = ref('这是父组件的消息');// 定义方法
const childComponentRef = ref(null);const callChildMethod = () => {childComponentRef.value.changeMessageInParent();
};const updateMessage = (newMessage) => {message.value = newMessage;
};// 暴露方法给子组件
defineExpose({updateMessage
});
</script>
<template><div><button @click="updateParentMessage">更新父组件的消息</button></div>
</template><script setup>
import {getCurrentInstance} from 'vue';// 获取父组件实例
const parent = getCurrentInstance().parent;// 定义方法
const updateParentMessage = () => {parent.exposed.updateMessage('子组件更新了父组件的消息');
};const changeMessageInParent = () => {parent.exposed.updateMessage('子组件方法被调用了');
};// 暴露方法给父组件
defineExpose({changeMessageInParent
});
</script>

provide、inject

provide 和 inject 是 Vue 3 中用于实现祖孙组件直接通信的机制。它们允许祖先组件向其所有的后代组件传递数据或方法,而不需要逐层传递 props。这在复杂的组件树中尤其有用,可以避免 prop drilling(逐层传递 props)。

概述

  • provide:在祖先组件中定义并提供数据或方法,供后代组件使用。
  • inject:在后代组件中声明并接收祖先组件提供的数据或方法。

示例

父组件

<template><div style="background-color: #e0f7fa; padding: 20px;"><h1>{{ message }}</h1><ChildComponent /></div>
</template><script setup>
import {provide, ref} from 'vue';
import ChildComponent from './ChildComponent.vue';// 定义数据
const message = ref('这是父组件的消息');// 提供数据和方法
provide('message', message);
provide('updateMessage', (newMessage) => {message.value = newMessage;
});
</script>

子组件

<template><div style="background-color: #b2ebf2; padding: 20px;"><button @click="updateParentMessage">更新父组件的消息</button><GrandChildComponent /></div>
</template><script setup>
import {inject} from 'vue';
import GrandChildComponent from './GrandChildComponent.vue';// 注入数据和方法
const message = inject('message');
const updateMessage = inject('updateMessage');// 定义方法
const updateParentMessage = () => {updateMessage('子组件更新了父组件的消息');
};
</script>

孙子组件

<template><div style="background-color: #80deea; padding: 20px;"><button @click="updateParentMessage">孙子组件更新父组件的消息</button></div>
</template><script setup>
import { inject } from 'vue';// 注入数据和方法
const message = inject('message');
const updateMessage = inject('updateMessage');// 定义方法
const updateParentMessage = () => {updateMessage('孙子组件更新了父组件的消息');
};
</script>

slot

在 Vue 3 中,slot 是一种强大的内容分发机制,允许父组件向子组件传递内容。slot 可以分为三种类型:默认插槽、具名插槽和作用域插槽。

  • 默认插槽:默认插槽是最简单的插槽类型,父组件传递的内容会被插入到子组件的默认插槽中。
  • 具名插槽:具名插槽允许父组件向子组件的不同位置传递内容,通过 name 属性来区分不同的插槽。
  • 作用域插槽:作用域插槽允许子组件向父组件传递数据,父组件可以通过作用域插槽访问这些数据。

父组件

<template><div style="background-color: #e0f7fa; padding: 20px;"><h1>{{ message }}</h1><ChildComponent><!-- 具名插槽 --><template #header><h2>这是父组件传递的头部内容</h2></template><!-- 作用域插槽 --><template #default="slotProps"><p>这是父组件传递的默认内容</p><p>{{ slotProps.text }}</p></template><template #footer><p>这是父组件传递的尾部内容</p></template></ChildComponent></div>
</template><script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';// 定义数据
const message = ref('这是父组件的消息');
</script>

子组件

<template><div style="background-color: #b2ebf2; padding: 20px;"><header><slot name="header"></slot></header><main><slot :text="slotData"></slot></main><footer><slot name="footer"></slot></footer></div>
</template><script setup>
import { ref } from 'vue';// 定义数据
const slotData = ref('这是子组件传递的数据');
</script>

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue-i18n 使用 $t 导致的 Typescript 报错问题

目录 1&#xff0c;问题2&#xff0c;解决 1&#xff0c;问题 在 Vue3 项目中使用 vue-i18n v9.14.0 时&#xff0c;可以&#xff1a; <template><div>{{ t(xxx) }}</div> </template><script setup lang"ts"> import { useI18n } f…

顶踩Emlog插件源码

源码介绍 顶踩Emlog插件源码 前些天看到小刀娱乐网的文章页面有了一些变化&#xff0c;那就是增加了一个有价值/无价值的顶踩按钮。 样式也是非常的好看 再加上两个表情包是非常的有趣。 写到了Emlog系统&#xff0c;效果如上图。 如何使用&#xff1a; 需要在echo_log.…

Datasheet SHT20芯片的数据手册

Datasheet SHT20芯片的数据手册 I2C读取湿度传感器返回的16位数据。SCL SDA 14位有效&#xff0c;我以为是将后二位删除&#xff0c;实际上看完手册才知道是后二位值无用&#xff0c;不是删除&#xff0c;而是清0&#xff0c;实际上还是16为&#xff0c;知识后二位是0还是1&…

Flume 日志采集系统

Flume 日志采集系统 一、Flume 概述二、Flume 架构设计2.1 架构图2.2 Flume Source 类型2.3 Flume Channel 类型2.4 Flume Sink 类型 三、Flume 安装部署3.1 下载解压3.2 上传解压3.3 修改配置文件2.4 启动 Flume Agent 四、案例实践&#xff1a;Flume 分布式集群搭建4.1 Flume…

基于SpringBoot的准妈妈孕期交流平台

你好呀&#xff0c;我是计算机学姐码农小野&#xff01;如果有相关需求&#xff0c;可以私信联系我。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot框架 工具&#xff1a;IDEA/Eclipse、Navicat 系统展示 首页 管理员登录 用户管理 早教…

利用CubeMX复现正点原子TFTLCD驱动例程

来源&#xff1a;正点原子 FMC的工作原理暂时先欠着&#xff0c;先记录一下CRUD的过程。 第一步准备一个us级别延时函数&#xff0c;不会的参考拙作&#xff1a;STM32的定时器简介-CSDN博客 第二部开启FMC外设&#xff1a; ①进入 Pinout->FMC 配置栏&#xff0c;配置 …

如何做好网络安全

随着互联网技术的飞速发展&#xff0c;网站已成为企业对外展示、交流和服务的重要窗口。然而&#xff0c;随之而来的网站安全问题也日益凸显&#xff0c;给企业的业务发展和用户数据安全带来了巨大威胁。因此&#xff0c;高度重视网站安全已成为网络安全的首要任务。今天我们就…

使用ffmpeg在视频中绘制矩形区域

由于项目需要对视频中的人脸做定位跟踪&#xff0c; 我先使用了人脸识别算法&#xff0c;对视频中的每个帧识别人脸、通过人脸库比对&#xff0c;最终记录坐标等信息。 然后使用ffmpeg中的 drawbox 滤镜功能&#xff0c;选择性的绘制区域。从而实现人脸定位跟踪 1、drawbox …

用于协作代码开发的 10 大 GitHub 集成

GitHub 是开发人员的天堂。开发人员在分布式 GitHub 存储库中存储和管理其源代码,允许多个贡献者同时处理项目。这种协作行动将生产力提高了 22%,将修复漏洞的速度提高了 7 倍,并将入职时间缩短了 80%。 作为一个版本控制系统,它允许开发人员跟踪和审查更改、管理分支和合…

【Sceneform-EQR】通过sceneform-eqr实现一个视频播放器(使用安卓MediaPlayer实现视频播放)

在前一篇文档中介绍了如何在AR\三维场景创建几种背景 【Sceneform-EQR】scenefrom-eqr中的几种背景实现(不仅用于AR、三维场景&#xff0c;在图片、视频播放器中也适用) 本文将侧重介绍如何使用安卓MediaPlayer实现视频播放。 ↓↓↓↓↓↓↓↓↓↓↓↓ 以下正文 ↓↓↓↓↓↓…

李彦宏内部讲话曝光,谈大模型三大认知误区:智能体还是非共识

“外界对大模型有相当多的误解&#xff0c;”近日据媒体报道&#xff0c;李彦宏的一则内部讲话曝光。在最近一次和员工交流中&#xff0c;李彦宏谈及三个大模型认知误区&#xff0c;涵盖了大模型竞争、开源模型效率、智能体趋势等热点话题。 李彦宏认为未来大模型之间的差距可…

DWI扩散磁共振成像和结构连接组学指南

扩散磁共振成像和结构连接组学指南 引言流程概述扩散磁共振成像(dMRI)dMRI基础ADC&#xff08; apparent diffusion coefficient, 表观扩散系数&#xff09;MD&#xff08;mean diffusivity, 平均扩散率&#xff09;FA&#xff08; fractional anisotropy, 分数各向异性&#x…

“左侧文字横向”的QTabWidget

左侧用 QToolButton 组&#xff0c; 右侧用 QStackedWidget&#xff0c;信号槽绑定切换页面 可定制化高 QButtonGroup* btnGp new QButtonGroup(this);btnGp->addButton(ui->btn1, 0);btnGp->addButton(ui->btn2, 1);btnGp->addButton(ui->btn3, 2);connect…

MongoDB的Map-Reduce操作与聚合管道操作的两个实例相互转换

一、插入集合 comment 的文档的内容 二、题目要求 将集合 comment 中的文档进行聚合操作&#xff0c;即将字段 state为1的文档查询出来&#xff0c;然后按字段 nickname 进行分组,最后计算出每个评论者的评论条数。 三、mapReduce 操作代码 db.comment.mapReduce(// Map函数&…

linux搭建深度学习平台

linux搭建深度学习平台&#xff08;Ubuntu&#xff09; /home/guangyao/anaconda3 我服务器的anaconda地址 ~/anaconda3 1 首先就是打开浏览器&#xff0c;我实验室的是火狐&#xff0c;搜索anaconda下载&#xff0c;找到下载目录&#xff0c;cd进去&#xff0c; 2安装 bas…

鸿蒙界面开发——组件(6):属性字符串(StyledString)文本输入

属性字符串StyledString/MutableStyledString MutableStyledString继承于StyledString&#xff0c;以下统一简称StyledString。 是功能强大的标记对象&#xff0c;可用于字符或段落级别设置文本样式。 通过将StyledString附加到文本组件&#xff0c; 可以通过多种方式更改文本…

爆改YOLOv8|利用SCConv改进yolov8-即轻量又涨点

1&#xff0c;本文介绍 SCConv&#xff08;空间和通道重构卷积&#xff09;是一种高效的卷积模块&#xff0c;旨在优化卷积神经网络&#xff08;CNN&#xff09;的性能&#xff0c;通过减少空间和通道的冗余来降低计算资源的消耗。该模块由两个核心组件构成&#xff1a; 空间重…

ELK在Linux上部署教程

Docker Compose搭建ELK Elasticsearch默认使用mmapfs目录来存储索引。操作系统默认的mmap计数太低可能导致内存不足&#xff0c;我们可以使用下面这条命令来增加内存 sysctl -w vm.max_map_count262144创建Elasticsearch数据挂载路径 mkdir -p /echola/elasticsearch/data对…

【截图服务 +打包】pkg打包 puppeteer

目录 最后结论 windows打包成服务 定制executablePath 用程序来查找chrome.exe 代替上面的写配置文件 服务遇到的问题 使用java开一个线程启动 遇到的问题与解决 版本匹配问题 打出包后的运行报错问题 linux下的安装 安装n 库缺少 程序运行后的报错 制作 运行报…

IT前端好用的工具集

在线抠图网站 https://www.remove.bg/ 将iconfont转成css显示 https://transfonter.org/ 免费的在线图片压缩 https://tinypng.com/ JSON在线格式化工具 https://www.sojson.com/ 国内人工智能kimi.moonshot工具 https://kimi.moonshot.cn/chat/crft7a6sdv14grouufs0 自动…