【Vue3】(三)vue3中的pinia狀態管理、組件通信方式及總結、插槽

目錄

一、vue3的pinia

1、什么是pinia?

2、為什么Vue3選擇pinia?

3、使用pinia的好處

4、安裝pinia

?2、項目配置

3、存儲/讀取pinia中的數據

4、修改pinia中的數據

?5、storeToRefs(保持store中數據的響應式)

?6、getters

?7、監聽store中數據的變化:$subscribe

8、store的組合式寫法

?二、【props】傳參

三、【自定義事件】傳參

四、【mitt】傳參

1、認識mitt

2、使用mitt

?五、【v-model】傳參(平常基本不寫)

六、【$attrs】傳參

七、【$refs和$parent】傳參

1、概述

2、原理

3、組件使用實例

4、$refs和$parent使用精髓

?八、provide和inject

九、slot插槽

1、默認插槽

2、具名插槽

?3、作用域插槽

十、Vue3組件通信總結


一、vue3的pinia

1、什么是pinia?

????????pinia 是一個 Vue3 的狀態管理庫,它的 API 設計和 Vuex 有很大的相似之處,但是它的實現方式和 Vuex 完全不同,它是基于 Vue3 的新特性?Composition API?實現的,所以它的使用方式和 Vuex 也有很大的不同。

Pinia | The intuitive store for Vue.js值得你喜歡的 Vue Storehttps://pinia.vuejs.org/zh/

2、為什么Vue3選擇pinia?

????????在構建大型或中型Vue應用時,組件之間的狀態共享和管理是一個不可避免的挑戰。Vue.js的官方狀態管理庫Vuex在過去幾年里一直是解決這個問題的主流方案。但是,Vuex的復雜性和對TypeScript支持的限制促使社區尋找更簡潔、更靈活的解決方案。這就是Pinia應運而生的背景。

????????Pinia是Vue.js的一個全新狀態管理庫庫,由同一個團隊編寫,旨在提供一個更輕量級和用戶友好的狀態管理體驗。它以簡單直觀的API、完全的TypeScript支持和更好的開發體驗而受到歡迎。

3、使用pinia的好處

????????簡化的API、更好的TypeScript集成、開箱即用的DevTools集成、模塊化和靈活性、易于測試、輕量級、持久化和插件支持
????????Pinia提供了一個更加直觀和簡潔的API,使得狀態管理變得更加容易理解和實施。對于開發者來說,這意味著更少的學習曲線和更快的開發速度。由于Pinia自底向上設計了對TypeScript的支持,使用TypeScript的開發者將會享受到無縫的類型推導和更少的類型斷言。Pinia與Vue DevTools的集成提供了更好的調試體驗,允許開發者輕松追蹤和操作狀態,從而提高開發效率。Pinia支持將狀態分割為不同的模塊,使得狀態管理在大型應用中更加清晰和可維護。此外,它的靈活性允許你根據需要輕松地添加插件和中間件。由于Pinia的設計,編寫單元測試變得更加直觀。你可以輕松地模擬actions和測試state的變更。Pinia的代碼庫比Vuex更小,對于注重應用大小的項目來說,這是一個明顯的優勢。Pinia支持通過插件來擴展其功能,例如狀態持久化,這使得在瀏覽器刷新或關閉后恢復用戶狀態變得簡單

????????綜上所述,Pinia為開發Vue應用的狀態管理提供了一個現代化、高效和靈活的解決方案。隨著Vue 3的推進,Pinia正在成為越來越多Vue開發者的首選狀態管理庫

4、安裝pinia

1、安裝依賴

安裝pinia依賴:npm i pinia

?2、項目配置

????????目錄:main.ts

// 引入pinia
import { createPinia } from "pinia";
// 創建pinia
const pinia = createPinia()
// 安裝pinia
app.use(pinia)

3、存儲/讀取pinia中的數據

(1)在src下創建store目錄?

(2)在store目錄下創建ts文件(最好能明確地看出屬于哪個組件使用)

????????例如:count.ts

import { defineStore } from "pinia";
// 官方推薦使用Hooks的方式命名
export const useCountStore = defineStore('count',{// 狀態/數據(官方要求必須寫成一個函數)// state: 真正存儲數據的地方(類似于Vue2中的data)state(){return{sum: 6}}
})

(3)讀取pinia中的值

// 類似Hooks的思想
import { useCountStore } from "@/store/count";const countStore = useCountStore()// 以下兩種方式都可以拿到state中的數據
console.log('countStore', countStore.sum)
console.log('countStore', countStore.$state.sum)

4、修改pinia中的數據

?(1)修改單個數據:直接修改

 countStore.sum += 1

(2)修改多個數據:$patch 批量修改

countStore.$patch({sum:888,address:'陜西',city:'西安'
})

(1)和(2)的區別:方法(1)在修改多個數據的時候,會觸發多個mutatuons事件,但是方法(2)在修改數據的時候,只會觸發一個$patch事件

(3)使用action修改數據:處理復雜數據時使用

  • 需要在pinia中定義action函數
export const useCountStore = defineStore('count',{// actions里面放置的是一個一個的方法,用于響應組件中的動作actions:{increment(value){console.log('increment被調用了',value)// 修改數據// this是當前的storeconsole.log('this.sum', this.sum)this.sum += value}},// 狀態/數據(官方要求必須寫成一個函數)// state: 真正存儲數據的地方(類似于Vue2中的data)state(){return{sum: 6,city:'山西',address: '未知'}}
})
  • 使用action中定義的修改數據的函數
 // 第三種修改數據的方式:使用action屬性修改數據countStore.increment(n.value)

?5、storeToRefs(保持store中數據的響應式)

  • toRefs會將所包裹的數據全部變成ref對象,包括數據和方法,在這里不適用(vue3自帶的)
  • storeToRefs只會關注store中的數據,不會對方法進行ref包裹(pinia自帶的)
import { storeToRefs } from "pinia";
// 解構賦值countStore中的數據
// 1、為了保證數據的響應式,需要使用storeToRefs
// 2、storeToRefs只會關注store中的數據,不會對方法進行ref包裹
const {sum,city,address} = storeToRefs(countStore)

?6、getters

概念:當state中的數據,需要經過處理后再使用,可以使用getters配置。

????????在store中追加getters配置

export const useCountStore = defineStore('count',{// state: 真正存儲數據的地方(類似于Vue2中的data)state(){return{sum: 6,city:'山西',address: 'chinese'}},// 配置gettersgetters:{// 寫法一:bigSum:(state)=>{return state.sum * 10},// 寫法二:upperaddress(){// this可以拿到當前這個store對象console.log('this', this)return this.address.toUpperCase()}}
})

????????使用getters處理后的數據

<template><div class="count"><h2>當前求和為:{{ sum }},放大10倍后:{{ bigSum }}</h2><h2>當前地址為:{{ address }},轉換成大寫后:{{ upperaddress }}</h2></div>
</template><script setup lang="ts">
import { ref } from "vue";
// Hooks的思想
import { useCountStore } from "@/store/count";
import { storeToRefs } from "pinia";const countStore = useCountStore();// 解構賦值countStore中的數據
// 1、為了保證數據的響應式,需要使用storeToRefs
// 2、storeToRefs只會關注store中的數據,不會對方法進行ref包裹
const { sum, city, address, bigSum, upperaddress } = storeToRefs(countStore);</script>

?7、監聽store中數據的變化:$subscribe

  • 訂閱方法的使用:類似watch屬性,可以監聽state及其變化
  • 兩個參數:本次修改的信息真正的數據
talkStore.$subscribe((mutate, state) => {console.log("$subscribe監聽事件的變化", mutate, state);// 實現一個無感刷新數據的方法localStorage.setItem('talkList',JSON.stringify(state.talkList))  // 將數據存到本地存儲
});

8、store的組合式寫法

export const useTalkStore = defineStore('talk', () => {// 直接定義的數據,相當于stateconst talkList = reactive(JSON.parse(localStorage.getItem('talkList') as string) || [])// 直接定義的方法,就相當于actionasync function getATalk() {// 發請求// {data:{content:title}} => 這個寫法的意思是:將返回的結果對象賦值給data,然后再結構data給content,最后再把content賦值給titlelet {data: { content: title },} = await axios.get("https://api.uomg.com/api/rand.qinghua?fromat=json");// 將請求回來的字符串包裝成一個對象let obj = { id: nanoid(), title };console.log("obj", obj);talkList.unshift(obj);}// 注意:最后一定要return,要不然沒法使用return {talkList,getATalk}
})

?二、【props】傳參

概述:props是使用頻率最高的一種通信方式。作用:父傳子、子傳父

  • 父傳子:屬性值是非函數(變量)
  • 子傳父:屬性值是函數(方法)

父組件:

<template><div class="father"><h3>父組件1</h3><h4>父親的車:{{ car }}</h4><!-- 父傳子【參數】:使用 屬性傳參 的方式傳遞參數 --><!-- 父傳子【方法】:使用 屬性傳參 的方式傳遞參數--><h5>父組件接收到子組件的參數:{{ sonParams }}</h5><Child :dirver="car" :sendSon="getSonParams"/></div>
</template>
<script setup lang="ts" name="father">
import Child from "./Child.vue";
import { ref } from "vue";let car = ref('小米')
let sonParams = ref()// 方法
function getSonParams(params:type) {console.log('params', params)sonParams.value = params
}
</script>

子組件:

<template><div class="child"> <h3>子組件2</h3><h4>兒子的玩具:{{ toy }}</h4><!-- 子組件使用父組件參數 --><h5>子組件拿到父組件的參數:{{ dirver }}</h5><!-- 復雜寫法 --><button @click="handleFatherFun">方法1:觸發父組件的方法實例</button><br /><button @click="sendSon(toy)">方法2:把子組件的參數傳遞給父組件</button></div>
</template>
<script setup lang="ts" name="Child">
import { ref } from "vue";let toy = ref('奧特曼') // 子組件接收:聲名接收函數:defineProps 數組
let props = defineProps(['dirver','sendSon'])function handleFatherFun(params:type) {// 使用props.拿到父組件傳遞的參數props.sendSon(toy.value)
}
</script>

????????圖解代碼:

三、【自定義事件】傳參

????????在 Vue3 中,自定義事件是一種常用的機制,用于在組件之間傳遞數據。通過自定義事件,子組件可以向父組件發送數據,從而實現組件間的通信。

????????父組件:

<template><div><h3>父組件</h3><!-- 給子組件Child綁定事件 --><h4 v-show="toy">子給的玩具:{{ toy }}</h4><!-- 官方推薦:自定義事件使用kabab-case的事件名(a-b) --><Child @send-toy="saveToy"/></div>
</template><script setup lang="ts">
import Child from "./child.vue";
import { ref } from "vue";let toy = ref('')
// 用于處理子組件傳遞過來的數據
function saveToy(value:any) {console.log('saveToy', value)toy.value = value
}
</script>

????????子組件:

<template><div class="child"><h3>子組件</h3><h4>玩具:{{ toy }}</h4><button @click="emit('send-toy',toy)"></button></div>
</template><script setup lang="ts">
import { ref } from "vue";let toy = ref('奧特曼')
// 聲明事件
let emit = defineEmits(['send-toy'])
</script>

????????圖解代碼:

四、【mitt】傳參

1、認識mitt

? ? ? ? mitt是vue3提供的一個工具,能夠實現跨組件通信

下載mitt依賴:npm i mitt

① 創建mitt文件目錄

????????目錄地址:src/utils/emitter.ts

② 創建mitt對象

????????src/utils/emitter.ts

// 引入itt
import mitt from 'mitt'
// 調用mitt,得到emitter,emitter能:綁定事件,觸發事件
const emitter = mitt()
// 暴露emitter
export default emitter

③ 項目引入mitt(例如:main.ts)

// 引入mitt
import emitter from "@/utils/emitter";

④ mitt語法介紹

// 綁定事件
emitter.on('tast1',()=>{console.log('tast1被觸發了')
})emitter.on('tast2',()=>{console.log('tast2被觸發了')
})// 觸發事件
setTimeout(() => {emitter.emit('tast1')emitter.emit('tast2')
}, 1000);// 解除事件
setTimeout(() => {// 清除單個事件emitter.off('tast1')// 清除所有事件emitter.all.clear()
}, 3000);

2、使用mitt

????????組件1:

<template><div class="child1"><h2>子組件1</h2><h3>玩具:{{ toy }}</h3><button @click="emitter.emit('send-toy',toy)">玩具給Childe2玩</button></div>
</template><script setup lang="ts">
import { ref } from "vue";
import emitter from "@/utils/emitter";let toy = ref('奧特曼')
</script>

????????組件2:

<template><div class="child2"><h2>子組件2</h2><h3>電腦:{{ computer }}</h3><h4>Child1傳遞的玩具{{ toy }}</h4></div>
</template><script setup lang="ts">
import { ref,onUnmounted } from "vue";
import emitter from "@/utils/emitter";
// 數據
let computer = ref('聯想')
let toy = ref()// 給emitter綁定send-toy事件
emitter.on('send-toy',(value:any)=>{console.log('send-toy',value)toy.value = value
})
// 在組件卸載時,解綁emitter
onUnmounted(()=>{emitter.all.clear()
})
</script>

????????圖解代碼:

注意:當綁定事件的組件卸載時,最好清除掉emitter綁定的事件,防止內存占用?

?五、【v-model】傳參(平常基本不寫)

? ? ? ? v-model傳參方式一般適用于UI組件庫底層的傳參使用,所以,這里不做具體介紹,只說明底層原理,平常用的時候還是使用v-model即可

????????父組件:

<template><div class="father"><h3>父組件</h3><!-- v-model用在html標簽上 --><!-- <input type="text" v-model="userName"/> --><!-- v-model的底層原理: --><!-- <input type="text" :value="userName" @input="userName = (<HTMLInputElement>$event.target).value"> --><!-- v-model用在組件標簽上 --><!-- <Zhang v-model="userName"/> --><!-- v-model實現組件傳參的基本原理: --><Zhang :modelValue="userName" @update:modelValue="userName = $event"/></div>
</template><script setup lang="ts">
import { ref } from "vue";
import Zhang from "./zhang.vue";
// 數據
let userName = ref('張三')
</script>

????????子組件:

<template><div><h2>子組件</h2><input type="text" :value="modelValue"@input="emits('update:modelValue',(<HTMLInputElement>$event.target).value)"/></div>
</template><script setup lang="ts">
defineProps(['modelValue'])
const emits = defineEmits(['update:modelValue'])
</script>

拓展:

????????修改v-model的事件名稱

六、【$attrs】傳參

?1、概述:$attrs用于實現當前組件的父組件,向當前組件的子組件通信(祖→孫)

2、具體說明:$attrs是一個對象,包含所有父組件傳入的標簽屬性

????????注意:$attrs會自動排除props中聲明的屬性(可以任務聲明過的props被子組件自己“消費”了),也就是說:當父(祖-父-子)組件中以props的方式使用了某個屬性,在子組件中就不能使用這個屬性了

// 如果在父組件中用defineProps接收了a參數,那么a參數就沒法繼續傳遞了
defineProps(['a'])

????????祖組件:

<template><div class="father"><h2>父組件</h2><h4>a:{{ a }}</h4><h4>b:{{ b }}</h4><h4>c:{{ c }}</h4><h4>d:{{ d }}</h4><Child :a="a":b="b":c="c":d="d"v-bind="{x:200,y:100}":updateA="updateA" /></div>
</template><script setup lang="ts">
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"><h2>子組件</h2><GrandChild v-bind="$attrs"/></div>
</template><script setup lang="ts">
import GrandChild from "./grandChild.vue";
// 如果這里在defineProps接收了a參數,那么a參數就沒法繼續傳遞了
defineProps(['a'])
</script>

? ? ? ? 孫組件:

<template><div class="grand-child"><h2>孫組件</h2><h4>a:{{ a }}</h4><h4>b:{{ b }}</h4><h4>c:{{ c }}</h4><h4>d:{{ d }}</h4><button @click="updateA(6)">點我將爺爺組件中的a更新</button></div>
</template><script setup lang="ts">
defineProps(['a','b','c','d','x','y','updateA'])
</script>

七、【$refs和$parent】傳參

1、概述

  • $refs:用于父→子
  • $parent:用于子→父

2、原理

屬性說明
$refs值為對象,包含所有ref屬性標識的DOM元素或組件實例
$parent值為對象,當前組件的父組件實例對象

3、組件使用實例

? ? ? ? 父組件:

<template><div class="father"><h2>父組件</h2><h4>房產:{{ house }}</h4><button @click="changeToy">修改Child1的玩具</button><button @click="changeComputer">修改Child2的電腦</button><button @click="getAllChild($refs)">所有孩子的書增加</button><Child1 ref="c1" /><Child2 ref="c2" /></div>
</template><script setup lang="ts">
import { ref } from "vue";
import Child1 from "./child1.vue";
import Child2 from "./child2.vue";// 數據
let house = ref(4);
let c1 = ref();
let c2 = ref();function changeToy() {console.log("c1.value", c1.value);c1.value.toy = "小豬佩奇";
}function changeComputer() {console.log("c2.value", c2.value);c2.value.toy = "華為";
}function getAllChild(refs: { [key:string]: any }) {console.log("所有子組件", refs);for (const key in refs) {console.log("refs", refs[key]);refs[key].book += 3;}
}defineExpose({house})
</script>

? ? ? ? 子組件1:

<template><div class="child1"><h2>子組件1</h2><h4>玩具:{{ toy }}</h4><h4>書籍:{{ book }}本</h4><button @click="minusHouse($parent)">干掉父組件的一套房產</button></div>
</template><script setup lang="ts">
import { ref } from "vue";// 數據
let toy = ref('奧特曼')
let book = ref(3)function minusHouse(parent:any) {console.log('parent', parent)parent.house -= 1 
}// 把數據交給外部
defineExpose({toy,book})
</script>

? ? ? ? 子組件2:

<template><div class="child2"><h2>子組件2</h2><h4>電腦:{{ computer }}</h4><h4>玩具:{{ book }}</h4></div>
</template><script setup lang="ts">
import { ref } from "vue";// 數據
let computer = ref('聯想')let book = ref('奧特曼')// 把數據交給外部
defineExpose({computer,book})
</script>

4、$refs和$parent使用精髓

  • 父組件中,給子組件綁定ref屬性,通過$refs可以獲取到所有的子組件實例

  • 子組件,只有通過defineExpose宏函數,將想要暴露的數據暴露出去,父組件才能拿到數據

?八、provide和inject

????????能夠完全實現不借助于中間組件跨組件通信

父組件:

<template><div class="father"><h2>父組件</h2><h3>銀子:{{ money }}元</h3><h3>車子:一輛{{car.brand}},價值:{{car.price}}萬元</h3><Child /></div>
</template><script setup lang="ts">
import Child from "./child.vue";
import { ref, reactive, provide } from "vue";let money = ref(100);
let car = reactive({brand: "奔馳",price: 1000,
});
// 孫組件修改祖先組件的money數據
function updateMoney(value: number) {money.value -= value;
}// provide傳參:向后代提供數據
provide("moneyContext", { money, updateMoney });
provide("car", car);
</script>

????????子組件:

<template><div class="grandChild"><h2>孫組件</h2><h3>父組件【銀子】:{{ fatherMoney }}</h3><h3>父組件【車子】:一輛{{fatherCar.brand}},價值:{{fatherCar.price}}萬元</h3><button @click="updateMoney(6)">修改money</button></div>
</template><script setup lang="ts">
import { inject } from "vue";let { fatherMoney, updateMoney } = inject("moneyContext", {fatherMoney: 0,updateMoney: (value:number) => {},
});
let fatherCar = inject("car", { brand: "未知", price: "未知" });
</script>

九、slot插槽

????????插槽的用途就和它的名字一樣:有一個缺槽,我們可以插入一些東西。

????????插槽?slot?通常用于兩個父子組件之間,最常見的應用就是我們使用一些?UI?組件庫中的彈窗組件時,彈窗組件的內容是可以讓我們自定義的,這就是使用了插槽的原理。

1、默認插槽

????????父組件:

<template><div class="father"><h2>父組件</h2><div class="content"><!-- 默認插槽 --><Category title="熱門游戲列表"><ul><li v-for="item in games":key="item.id">{{ item.name }}</li></ul></Category></div></div>
</template><script setup lang="ts">
import Category from "./category.vue";
import { ref, reactive } from "vue";let games = reactive([{ id: "adadada01", name: "英雄聯盟" },{ id: "adadada02", name: "穿越火線" },{ id: "adadada03", name: "紅色警戒" },{ id: "adadada04", name: "王者農藥" },
]);let imgUrl = ref("https://z1.ax1x.com/2023/11/19/piNxLo4.jpg");let videoUrl = ref("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4");
</script>

????????子組件:

<template><div class="category"><h2>{{ title }}</h2><!-- 默認插槽 --><slot>默認插槽</slot></div>
</template><script setup lang="ts" name="Category">
defineProps(["title"]);
</script>

2、具名插槽

????????父組件:

<template><div class="father"><h2>父組件</h2><div class="content"><!-- 具名插槽 --><Category title="熱門游戲列表"><template v-slot:s2><ul><li v-for="item in games":key="item.id">{{ item.name }}</li></ul></template><template v-slot:s1><h3>描述信息</h3></template></Category></div></div>
</template><script setup lang="ts">
import Category from "./category.vue";
import { ref, reactive } from "vue";let games = reactive([{ id: "adadada01", name: "英雄聯盟" },{ id: "adadada02", name: "穿越火線" },{ id: "adadada03", name: "紅色警戒" },{ id: "adadada04", name: "王者農藥" },
]);let imgUrl = ref("https://z1.ax1x.com/2023/11/19/piNxLo4.jpg");let videoUrl = ref("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4");
</script><style lang="scss" scoped>

? ? ? ? 子組件:

<template><div class="category"><h2>{{ title }}</h2><!-- 具名插槽 --><slot name="s1"></slot><slot name="s2"></slot></div>
</template><script setup lang="ts" name="Category">
defineProps(["title"]);
</script>

?3、作用域插槽

?????????父組件:

<template><div class="father"><h2>父組件</h2><div class="content"><Game><template v-slot="games"><ul><li v-for="g in games.youxi":key="g.id">{{ g.name }}</li></ul></template></Game><Game><template v-slot="games"><ol><li v-for="g in games.youxi":key="g.id">{{ g.name }}</li></ol></template></Game><!-- 簡寫 --><Game><template #default="{youxi}"><div><h3 v-for="g in youxi":key="g.id">{{ g.name }}</h3></div></template></Game></div></div>
</template><script setup lang="ts">
import Game from "./game.vue";
</script>

????????子組件:

<template><div class="game"><h2>游戲列表</h2><!-- 作用域插槽 --><slot :youxi="games"></slot></div>
</template><script setup lang="ts">
import { reactive } from "vue";let games = reactive([{ id: "adadada01", name: "英雄聯盟" },{ id: "adadada02", name: "穿越火線" },{ id: "adadada03", name: "紅色警戒" },{ id: "adadada04", name: "王者農藥" },
]);
</script>

十、Vue3組件通信總結

組件關系傳遞方式
父傳子

1、props

2、v-model

3、$refs

4、默認插槽、具名插槽

子傳父

1、props

2、自定義事件

3、v-model

4、$parent

5、作用域插槽

祖傳孫、孫傳祖

1、$attrs

2、provide、inject

兄弟間、任意組件間

1、mitt

2、pinia

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/83406.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/83406.shtml
英文地址,請注明出處:http://en.pswp.cn/web/83406.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

WEB3全棧開發——面試專業技能點P1Node.js / Web3.js / Ethers.js

一、Node.js 事件循環 Node.js 的事件循環&#xff08;Event Loop&#xff09;是其異步編程的核心機制&#xff0c;它使得 Node.js 可以在單線程中實現非阻塞 I/O 操作。 &#x1f501; 簡要原理 Node.js 是基于 libuv 實現的&#xff0c;它使用事件循環來處理非阻塞操作。事件…

大數據學習棧記——Neo4j的安裝與使用

本文介紹圖數據庫Neofj的安裝與使用&#xff0c;操作系統&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安裝 Neofj可以進行官網安裝&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我這里安裝是添加軟件源的方法 最新版…

web架構4------(nginx常用變量,nginx中英文自動匹配,lnmp網站架構,正向代理,反向代理,負載均衡)

一.前言 本期來介紹nginx最后幾個知識點&#xff0c;看著要說的內容很多&#xff0c;其實一點也不多&#xff0c;都是所見即所得的東西。 二.nginx常用變量 2.1 常用變量 $args 請求中的參數&#xff0c;也叫查詢參數&#xff0c;如www.123.com/1.php?a1&b2的$args就是…

openeuler系統(CentOs)圖形化桌面黑屏/丟失(開啟VNC服務沖突)

1. VNC服務開啟如下&#xff1a; https://zhuanlan.zhihu.com/p/5049263261 在centos8系統上使用tigervnc-server搭建VNC_centos8 tigervnc-server-CSDN博客 2. 上述操作完成后&#xff0c;連接VNC仍會出現黑屏&#xff0c;則需要編輯/root/.vnc/xstartup&#xff1a; [運維…

MySQL:Prepared Statement 預處理語句

預處理語句&#xff08;Prepared Statements&#xff09;是 MySQL 中一種用于執行 SQL 查詢的高效、安全的方法。通過使用預處理語句&#xff0c;可以顯著提升查詢性能&#xff0c;并防止 SQL 注入攻擊。本文將詳細介紹 MySQL 預處理語句的概念、使用方法及其優勢。 一、預處理…

EPPLUS——CAD c#讀寫EXCEL的第三方庫

EPPLUS(可支持NET35) 在 CAD 的 C# 二次開發中&#xff0c;使用 EPPLUS 庫處理 Excel 文件具有以下顯著優點&#xff0c;尤其在兼容性、便捷性和性能等方面契合 CAD 項目的需求&#xff1a; 1. 跨.NET 版本兼容性強&#xff0c;適配 CAD 多環境部署 多框架支持&#xff1a;EP…

Linux知識回顧總結----進程狀態

本章將會介紹進程的一些概念&#xff1a;馮諾伊曼體系結構、進程是什么&#xff0c;怎么用、怎么表現得、進程空間地址、物理地址、虛擬地址、為什么存在進程空間地址、如何感性得去理解進程空間地址、環境變量是如何使用的。 目錄 1. 馮諾伊曼體系結構 1.1 是什么 1.2 結論 …

微信小程序之bind和catch

這兩個呢&#xff0c;都是綁定事件用的&#xff0c;具體使用有些小區別。 官方文檔&#xff1a; 事件冒泡處理不同 bind&#xff1a;綁定的事件會向上冒泡&#xff0c;即觸發當前組件的事件后&#xff0c;還會繼續觸發父組件的相同事件。例如&#xff0c;有一個子視圖綁定了b…

Android Test3 獲取的ANDROID_ID值不同

Android Test3 獲取的ANDROID_ID值不同 這篇文章來說明上一篇文章中說到的一個現象&#xff1a;在同一個項目中&#xff0c;創建不同的 app module&#xff0c;運行同一段測試代碼&#xff0c;獲取到的 ANDROID_ID 的值不同。 我也是第一次認真研究這個現象&#xff0c;這個還…

JSON 和 LabVIEW Data Types 互相轉換

使用JSONtext C:\Program Files (x86)\National Instruments\LabVIEW 2021\examples\JDP Science\JSONtext JSONtext LabVIEW Data Types.vi

docker和docker-compose的版本對應關系怎么看?

docker和docker-compose的版本對應關系怎么看&#xff1f;最近在安裝這兩個工具&#xff0c;像知道他們的版本對應關系&#xff0c;查了不少資料才找到。 雖然 Docker 和 Docker Compose 的版本并不嚴格綁定&#xff0c;但是在某些情況下&#xff0c;新版本的 Docker Compose …

郵科ODM攝像頭:多維度護航高鐵安全系統方案解析

?高鐵作為現代交通的重要支柱&#xff0c;其安全穩定運行依賴于高效的監控體系。攝像頭系統作為高鐵安全管理的“視覺感知中樞”&#xff0c;憑借多場景覆蓋、智能分析以及環境適應性設計&#xff0c;在行車安全、設備維護、乘客服務等方面發揮著不可或缺的作用。本文將從技術…

盒模型小全

CSS盒子模型詳解 1. 定義 CSS盒子模型是用于描述HTML元素在頁面中布局和表現的核心概念之一。在CSS中&#xff0c;所有HTML元素都被視為一個矩形的盒子&#xff0c;這些盒子封裝了周圍的HTML元素&#xff0c;并允許在其他元素和周圍元素邊框之間的空間放置內容。 2. 組成部分…

自定義鼠標效果 - 瀏覽器擴展使用教程

自定義鼠標效果 - 瀏覽器擴展使用教程 這里寫目錄標題 自定義鼠標效果 - 瀏覽器擴展使用教程功能特點安裝方法Chrome/Edge瀏覽器 使用指南1. 更改鼠標光標樣式2. 啟用鼠標軌跡效果3. 自定義軌跡效果點狀/彩虹/漸隱軌跡&#xff1a;表情軌跡&#xff1a; 管理自定義光標支持的文…

基于SpringBoot實現的課程答疑系統設計與實現【源碼+文檔】

基于SpringBootVue實現的課程答疑系統采用前后端分離架構方式&#xff0c;系統設計了管理員、學生、老師三種角色&#xff0c;系統實現了用戶登錄與注冊、個人中心、學生管理、老師管理、科目類型管理、學生問題管理、老師回答管理、老師信息管理、關注列表管理、交流區、輪播圖…

御微半導體面試總結

前一陣子在公司干的難受&#xff0c;所以再合肥這邊面試了幾家公司&#xff0c;挑一個御微半導體來說一下吧&#xff0c;公司主要是做半導體晶元測量的&#xff0c;具體啥我也不太明白。 公司產品線多&#xff0c;每條產品線配有獨立的軟件、結構、光學控制等人員開發語言和框…

Android Compose 自定義圓形取色盤

val Dp.toPx: Floatget() {var scale 3f // MyApplication.context.resources.displayMetrics.apply { // scale density // }return value * scale}val colors List(360) { i ->Color.hsv(360f - i, 1f, 1f) // 360到1的所有HSV顏色 }Preview …

vscode 配置 latex

下載插件 安裝插件前自行安裝 texlive, 按照 https://tug.org/texlive/ 要求安裝 找到 settings 打開 json 文件 在 json 文件中添加如下配置 "latex-workshop.latex.tools": [{"name": "latexmk","command": "latexmk",&qu…

安寶特方案丨船舶智造的“AR+AI+作業標準化管理解決方案”(質檢)

船舶質檢管理現狀&#xff1a;質檢環節部分依賴人工檢測&#xff0c;質檢員依據質量標準對產品進行抽檢或全檢。人工質檢受質檢員主觀因素影響較大&#xff0c;不同質檢員對標準的把握可能存在差異。 一、痛點與需求 1 Arbigtec 人工經驗依賴嚴重&#xff1a; 質檢員的檢測準確…

jenkins gerrit-trigger插件配置

插件gerrit-trigger下載好之后要在Manage Jenkins -->Gerrit Trigger-->New Server 中新增Gerrit Servers 配置好保存后點擊“狀態”查看是否正常