學習VUE3——組件(一)

組件注冊

分為全局注冊和局部注冊兩種。

全局注冊:

main.jsmain.ts中,使用 Vue 應用實例的 .component() 方法,讓組件在當前 Vue 應用中全局可用。

import { createApp } from 'vue'
import MyComponent from './App.vue'const app = createApp({})app.component('MyComponent', MyComponent)

.component() 方法可以被鏈式調用:

app.component('ComponentA', ComponentA).component('ComponentB', ComponentB).component('ComponentC', ComponentC)

全局注冊后,組件可以在此應用的任意組件的模板中使用:

<!-- 這在當前應用的任意組件中都可用 -->
<ComponentA/>
<ComponentB/>
<ComponentC/>

全局注冊存在的問題:

  1. 全局注冊,但并沒有被使用的組件無法在生產打包時被自動移除 (也叫“tree-shaking”)。如果你全局注冊了一個組件,即使它并沒有被實際使用,它仍然會出現在打包后的 JS 文件中。
  2. 全局注冊在大型項目中使項目的依賴關系變得不那么明確。在父組件中使用子組件時,不太容易定位子組件的實現。和使用過多的全局變量一樣,這可能會影響應用長期的可維護性。

局部組件:

一、在使用 <script setup> 的單文件組件中,導入的組件可以直接在模板中使用,無需注冊:

<script setup>
import ComponentA from './ComponentA.vue'
</script><template><ComponentA />
</template>

二、如果沒有使用 <script setup>,則需要使用 components 選項來顯式注冊:

import ComponentA from './ComponentA.js'export default {components: {ComponentA: ComponentA // 根據ES2015可直接縮寫成ComponentA},setup() {// ...}
}

Tips:

局部注冊的組件僅在當前組件中可用,在后代組件中不可用。

組件數據傳遞

props接收聲明

在使用 <script setup> 的單文件組件中,props 可以使用 defineProps() 宏(所有的宏都無需引入)來聲明:

<script setup>
const props = defineProps(['foo'])console.log(props.foo)
</script>

沒有使用 <script setup> 的組件中,props 可以使用 props 選項來聲明:

export default {props: ['foo'],setup(props) {// setup() 接收 props 作為第一個參數console.log(props.foo)}
}

除了使用字符串數組來聲明 prop 外,還可以使用對象的形式,并聲明prop項的類型:

// 對于以對象形式聲明的每個屬性,key 是 prop 的名稱,而值則是該 prop 預期類型的構造函數。
// 使用 <script setup>
defineProps({title: [String, Number], // 字符串或數字類型likes: Number
})
// 非 <script setup>
export default {props: {title: [String, Number],likes: Number}
}// 在ts中也可以使用類型標注來聲明
<script setup lang="ts">defineProps<{title?: stringlikes?: number}>()
</script>

Prop 名字格式

為了和 HTML attribute 對齊,我們通常在向子組件傳遞 props時,會將其寫為 kebab-case 形式:

<MyComponent greeting-message="hello" />

還可以傳入動態值:

<!-- 根據一個變量的值動態傳入 -->
<BlogPost :likes="post.likes" /><!-- 僅寫上 prop 但不傳值,會隱式轉換為 `true` -->
<BlogPost is-published />

使用一個對象綁定多個 prop

如果你想要將一個對象的所有屬性都當作 props 傳入,你可以使用沒有參數的 v-bind,即只使用 v-bind 而非 :prop-name。如下所示:

const post = {id: 1,title: 'My Journey with Vue'
}
<BlogPost v-bind="post" />
// 等價于
<BlogPost :id="post.id" :title="post.title" />

單向數據流

所有的 props 都遵循著單向綁定原則,props 因父組件的更新而變化,自然地將新的狀態向下流往子組件,而不會逆向傳遞。這避免了子組件意外修改父組件的狀態的情況,不然應用的數據流將很容易變得混亂而難以理解。如果強行在子組件上修改props,Vue 會在控制臺上向你拋出警告。

如果實在有修改的需求,可以用prop作為初始值后,新定義一個局部數據屬性:

const props = defineProps(['initialCounter'])
// 計數器只是將 props.initialCounter 作為初始值
// 像下面這樣做就使 prop 和后續更新無關了
const counter = ref(props.initialCounter)

后子組件通過拋出事件defineEmits,來通知父組件同步更改的傳入的prop。

Prop校驗

寫了類型的聲明時,如果傳入的值不滿足類型要求,Vue 會在瀏覽器控制臺中拋出警告來提醒使用者。這在開發給其他開發者使用的組件時非常有用。

聲明對 props 的校驗有如下方法:

defineProps({// 基礎類型檢查// (給出 `null` 和 `undefined` 值則會跳過任何類型檢查)propA: Number,// 多種可能的類型propB: [String, Number],// 必傳,且為 String 類型propC: {type: String,required: true},// 必傳但可為空的字符串propD: {type: [String, null],required: true},// Number 類型的默認值propE: {type: Number,default: 100},// 對象類型的默認值propF: {type: Object,// 對象或數組的默認值// 必須從一個工廠函數返回。// 該函數接收組件所接收到的原始 prop 作為參數。default(rawProps) {return { message: 'hello' }}// 可簡寫為default: () => ({ message: 'hello' })},// 自定義類型校驗函數// 在 3.4+ 中完整的 props 作為第二個參數傳入propG: {validator(value, props) {// The value must match one of these stringsreturn ['success', 'warning', 'danger'].includes(value)}},// 函數類型的默認值propH: {type: Function,// 不像對象或數組的默認,這不是一個// 工廠函數。這會是一個用來作為默認值的函數default() {return 'Default function'}}
})

vue3+TS時,語法如下:

export interface Props {msg?: stringlabels?: string[]
}const props = withDefaults(defineProps<Props>(), {msg: 'hello',labels: () => ['one', 'two']
})

Tips:

  • defineProps() 宏中的參數不可以訪問 <script setup> 中定義的其他變量,因為在編譯時整個表達式都會被移到外部的函數中
  • 所有 prop 默認都是可選的,除非聲明了 required: true
  • Boolean 外的未傳遞的可選 prop 將會有一個默認值 undefined
  • Boolean 類型的未傳遞 prop 將被轉換為 false。這可以通過為它設置 default 來更改——例如:設置為 default: undefined 將與非布爾類型的 prop 的行為保持一致。
  • 如果聲明了 default 值,那么在 prop 的值被解析為 undefined 時,無論 prop 是未被傳遞還是顯式指明的 undefined,都會改為 default 值

運行時類型檢查

Vue 主要通過 instanceof 來檢查類型是否匹配。

如果 type 僅為 null 而非使用數組語法,它將允許任何類型。

校驗中的type可以是哪些:

1、構造函數

  • String
  • Number
  • Boolean
  • Array
  • Object
  • Date
  • Function
  • Symbol
  • Error

2、type 也可以是自定義的類或構造函數

例子:

class Person {constructor(firstName, lastName) {this.firstName = firstNamethis.lastName = lastName}
}
defineProps({author: Person
})

Boolean 類型轉換

聲明為 Boolean 類型的 props 有特別的類型轉換規則。

例子:

defineProps({disabled: Boolean
})
// 應用
<!-- 等同于傳入 :disabled="true" -->
<MyComponent disabled />
<!-- 等同于傳入 :disabled="false" -->
<MyComponent />

當prop被聲明為多種類型,并且類型中有String時,Boolean放置的位置會影響Boolean 的轉換規則應用。

// disabled 將被轉換為 true
defineProps({disabled: [Boolean, Number]
})// disabled 將被轉換為 true
defineProps({disabled: [Boolean, String]
})// disabled 將被轉換為 true
defineProps({disabled: [Number, Boolean]
})// disabled 將被解析為空字符串 (disabled="")
defineProps({disabled: [String, Boolean]
})

組件事件

觸發與監聽事件

子組件在模板表達式中,可以直接使用 $emit 方法觸發自定義事件:

<!-- MyComponent -->
<button @click="$emit('someEvent')">Click Me</button>

父組件可以通過 v-on (縮寫為 @) 來監聽事件(組件的事件監聽器也支持 .once 修飾符):

<MyComponent @some-event="callback" />

Tips:

和原生 DOM 事件不一樣,組件觸發的事件沒有冒泡機制。你只能監聽直接子組件觸發的事件。平級組件或是跨越多層嵌套的組件間通信,應使用一個外部的事件總線,或是使用一個狀態管理 | Vue.js。

帶參數事件

有時候我們會需要在觸發事件時附帶一個特定的值。

子組件中使用$emit 方法觸發自定義事件,提供一個額外的參數:

<button @click="$emit('increaseBy', 1)">Increase by 1
</button>

父組件接收:

// 方法一
<MyButton @increase-by="(n) => count += n" />// 方法二
<MyButton @increase-by="increaseCount" />
function increaseCount(n) {count.value += n
}

Tips:

所有傳入 $emit() 的額外參數都會被直接傳向監聽器。舉例來說,$emit('foo', 1, 2, 3) 觸發后,監聽器函數將會收到這三個參數值。

用defineEmits()聲明觸發的事件

組件可以顯式地通過 defineEmits() 宏來聲明它要觸發的事件:

<script setup>
defineEmits(['inFocus', 'submit'])
</script>

<template> 中使用的 $emit 方法不能在組件的 <script setup> 部分中使用,但 defineEmits() 會返回一個相同作用的函數供我們使用:

<script setup>
const emit = defineEmits(['inFocus', 'submit'])function buttonClick() {emit('submit')
}
</script>

defineEmits() 宏不能在子函數中使用。如上所示,它必須直接放置在 <script setup> 的頂級作用域下。

使用選項式setup的寫法:

export default {emits: ['inFocus', 'submit'],setup(props, ctx) {ctx.emit('submit')}
}
// ctx支持解構
export default {emits: ['inFocus', 'submit'],setup(props, { emit }) {emit('submit')}
}

emits 選項和 defineEmits() 宏還支持對象語法。通過 TypeScript 為參數指定類型,它允許我們對觸發事件的參數進行驗證:

<script setup lang="ts">
const emit = defineEmits({submit(payload: { email: string, password: string }) {// 通過返回值為 `true` 還是為 `false` 來判斷驗證是否通過}
})
</script>

完整版:

<script setup lang="ts">
const emit = defineEmits({// 沒有校驗click: null,// 校驗 submit 事件submit: (payload: { email: string, password: string }) => {if (email && password) {return true} else {console.warn('Invalid submit event payload!')return false}}
})function submitForm(email: string, password: string) {emit('submit', { email, password })
}
</script>

也可以使用純類型標注來聲明觸發的事件:

<script setup lang="ts">
const emit = defineEmits<{(e: 'change', id: number): void(e: 'update', value: string): void
}>()// 3.3+: 可選的、更簡潔的語法
const emit = defineEmits<{change: [id: number]update: [value: string]
}>()
</script>

Tips:

如果一個原生事件的名字 (例如 click) 被定義在 emits 選項中,則監聽器只會監聽組件觸發的 click 事件而不會再響應原生的 click 事件。

組件v-model

基本用法

v-model 可以在組件上使用以實現雙向綁定。

Vue 3.4 開始,推薦的實現方式是使用 defineModel() 宏:

<!-- Parent.vue -->
<Child v-model="countModel" /><!-- Child.vue -->
<script setup>
const model = defineModel()function update() {model.value++
}
</script><template><div>Parent bound v-model is: {{ model }}</div>
</template>

defineModel() 返回的值是一個 ref。它可以像其他 ref 一樣被訪問以及修改,不過它能起到在父組件和當前變量之間的雙向綁定的作用:

  • 它的 .value 和父組件的 v-model 的值同步;
  • 當它被子組件變更了,會觸發父組件綁定的值一起更新。

底層機制:

defineModel 是一個便利宏。編譯器將其展開為以下內容:

  • 一個名為 modelValue prop,本地 ref 的值與其同步;
  • 一個名為 update:modelValue 的事件,當本地 ref 的值發生變更時觸發。

defineModel 的實現原理如下:

子組件

<!-- Child.vue -->
<script setup>
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
</script><template><input:value="props.modelValue"@input="emit('update:modelValue', $event.target.value)"/>
</template>

父組件

<!-- Parent.vue -->
<Child:modelValue="foo"@update:modelValue="$event => (foo = $event)"
/>

未使用defineModel 的代碼顯得十分冗長,使用defineModel 后可簡潔如下:

子組件

<!-- Child.vue -->
<script setup>
const model = defineModel()
</script><template><span>My input</span> <input v-model="model">
</template>

父組件

<!-- Parent.vue -->
<script setup>
import Child from './Child.vue'
import { ref } from 'vue'const msg = ref('Hello World!')
</script><template><h1>{{ msg }}</h1><Child v-model="msg" />
</template>

因為 defineModel 相當于在底層聲明了一個 prop,你可以通過給 defineModel 傳遞選項,來聲明底層 prop 的選項:

// 使 v-model 必填
const model = defineModel({ required: true })// 提供一個默認值
const model = defineModel({ default: 0 })

注意:

如果為 defineModel prop 設置了一個 default 值且父組件沒有為該 prop 提供任何值,會導致父組件與子組件之間不同步。在下面的示例中,父組件的 myRef 是 undefined,而子組件的 model 是 1:

// 子組件:
const model = defineModel({ default: 1 })// 父組件
const myRef = ref()
<Child v-model="myRef"></Child>

v-model 的參數

組件上的 v-model 也可以接受一個參數:

<MyComponent v-model:title="bookTitle" />

在子組件中,我們可以通過將字符串作為第一個參數傳遞給 defineModel() 來支持相應的參數:

<!-- MyComponent.vue -->
<script setup>
const title = defineModel('title')
</script><template><input type="text" v-model="title" />
</template>

如果需要額外的 prop 選項,應該在 model 名稱之后傳遞:

const title = defineModel('title', { required: true })

3.4 之前的用法

<!-- MyComponent.vue -->
<script setup>
defineProps({title: {required: true}
})
defineEmits(['update:title'])
</script><template><inputtype="text":value="title"@input="$emit('update:title', $event.target.value)"/>
</template>

多個v-model的使用方法

<!-- Parent.vue -->
<UserNamev-model:first-name="first"v-model:last-name="last"
/>
<!-- Child.vue -->
<script setup>
const firstName = defineModel('firstName')
const lastName = defineModel('lastName')
</script><template><input type="text" v-model="firstName" /><input type="text" v-model="lastName" />
</template>

3.4 之前的用法

<script setup>
defineProps({firstName: String,lastName: String
})defineEmits(['update:firstName', 'update:lastName'])
</script><template><inputtype="text":value="firstName"@input="$emit('update:firstName', $event.target.value)"/><inputtype="text":value="lastName"@input="$emit('update:lastName', $event.target.value)"/>
</template>

處理 v-model 修飾符

如下所示,capitalize(將輸入的字符串值第一個字母轉為大寫)為自定義的修飾符:

<MyComponent v-model.capitalize="myText" />

解構?defineModel() 的返回值,可以在子組件中訪問添加到組件 v-model 的修飾符:


<script setup>
const [model, modifiers] = defineModel()console.log(modifiers) // { capitalize: true }
</script><template><input type="text" v-model="model" />
</template>

?defineModel() 中傳入 getset 這兩個選項,在從模型引用中讀取或設置值時會接收到當前的值,并且它們都應該返回一個經過處理的新值。下面是一個例子,展示了如何利用 set 選項來應用 capitalize (首字母大寫) 修飾符:

<script setup>
const [model, modifiers] = defineModel({set(value) {if (modifiers.capitalize) {return value.charAt(0).toUpperCase() + value.slice(1)}return value}
})
</script><template><input type="text" v-model="model" />
</template>

3.4 之前的用法

<script setup>
const props = defineProps({modelValue: String,modelModifiers: { default: () => ({}) }
})const emit = defineEmits(['update:modelValue'])function emitValue(e) {let value = e.target.valueif (props.modelModifiers.capitalize) {value = value.charAt(0).toUpperCase() + value.slice(1)}emit('update:modelValue', value)
}
</script><template><input type="text" :value="modelValue" @input="emitValue" />
</template>

使用多個不同參數的 v-model 時使用修飾符:

<!-- Parent.vue -->
<UserNamev-model:first-name.capitalize="first"v-model:last-name.uppercase="last"
/><!-- Child.vue -->
<script setup>
const [firstName, firstNameModifiers] = defineModel('firstName')
const [lastName, lastNameModifiers] = defineModel('lastName')console.log(firstNameModifiers) // { capitalize: true }
console.log(lastNameModifiers) // { uppercase: true }
</script>

透傳 Attributes

Attributes 繼承

“透傳 attribute”指的是傳遞給一個組件,卻沒有被該組件聲明為 props emits attribute 或者 v-on 事件監聽器。最常見的例子就是 class、style 和 id及其他傳遞了但沒有聲明使用的prop

如下例子,一個組件以單個元素為根作渲染時,透傳的 attribute 會自動被添加到根元素上。

<!-- <MyButton> -->
<button>Click Me</button><!-- Parent.vue -->
<MyButton class="large" /><!-- 最后渲染出的 DOM 結果 -->
<!-- 父組件中的class透傳到了MyButton組件的根元素button 上 -->
<button class="large">Click Me</button>

對 class 和 style 的合并

如果一個子組件的根元素已經有了 class 或 style attribute,它會和從父組件上繼承的值合并。

<!-- <MyButton> -->
<button class="btn">Click Me</button><!-- Parent.vue -->
<MyButton class="large" /><!-- 最后渲染出的 DOM 結果 -->
<button class="large btn">Click Me</button>

v-on 監聽器繼承

規則同上,而且事件也會合并。如果原生 button 元素自身也通過 v-on 綁定了一個事件監聽器,則這個監聽器和從父組件繼承的監聽器都會被觸發

深層組件繼承

如果一個組件 (甲) 的根節點是另一個組件 (乙) ,甲組件接收的透傳 attribute 會直接繼續傳給乙組件。

注意:

  • 透傳的 attribute 不會包含?甲組件?上聲明過的 props 或是針對 emits 聲明事件的 v-on 偵聽函數,換句話說,聲明過的 props 和偵聽函數被 甲組件?“消費”了。
  • 透傳的 attribute 若符合聲明,也可以作為 props 傳入 乙組件

禁用 Attributes 繼承

如果要禁止一個組件自動繼承attribute,可以在組件選項中設置 inheritAttrs: false

Vue3.3+的使用方法,直接在 <script setup> 中使用 defineOptions

<script setup>
defineOptions({inheritAttrs: false
})
// ...setup 邏輯
</script>

最常見的需要禁用 attribute 繼承的場景就是 attribute 需要應用在根節點以外的其他元素上。通過設置 inheritAttrs 選項為 false,你可以完全控制透傳進來的 attribute 被如何使用。
這些透傳進來的 attribute 可以在模板的表達式中直接用 $attrs 訪問到。

<span>Fallthrough attribute: {{ $attrs }}</span>

注意:

  • 和 props 有所不同,透傳 attributes 在 JavaScript 中保留了它們原始的大小寫,所以像 foo-bar 這樣的一個 attribute 需要通過 $attrs['foo-bar'] 來訪問。
  • @click 這樣的一個 v-on 事件監聽器將在此對象下被暴露為一個函數 $attrs.onClick

如下例,如果我們要想在 <MyButton> 中的button接收透傳進來的 attribute,而不是外層div上

<!-- <MyButton> -->
<div class="btn-wrapper"><button class="btn">Click Me</button>
</div><!-- Parent.vue -->
<MyButton class="large" />

則需要將?<MyButton> 改為:

<script setup>
defineOptions({inheritAttrs: false
})
</script><div class="btn-wrapper"><button class="btn" v-bind="$attrs">Click Me</button>
</div>

多根節點的 Attributes 繼承

和單根節點組件有所不同,有著多個根節點的組件沒有自動 attribute 透傳行為如果 $attrs 沒有被顯式綁定,將會拋出一個運行時警告

如下例中,子組件中因為有多個根節點,并且沒有顯式綁定$attrs,控制臺就會拋出一個警告。

<!-- Parent.vue -->
<CustomLayout id="custom-layout" @click="changeValue" /><!-- Child.vue -->
<header>...</header>
<main>...</main>
<footer>...</footer>

需要在子組件中綁定$attrs,警告就會消失:

<!-- Child.vue -->
<header>...</header>
<main v-bind="$attrs">...</main>
<footer>...</footer>

在 JavaScript 中訪問透傳 Attributes

如果需要,你可以在 <script setup> 中使用 useAttrs() API 來訪問一個組件的所有透傳 attribute:

<script setup>
import { useAttrs } from 'vue'const attrs = useAttrs()
</script>

如果使用的setup選項:

export default {setup(props, ctx) {// 透傳 attribute 被暴露為 ctx.attrsconsole.log(ctx.attrs)}
}

注意:

????????雖然這里的 attrs 對象總是反映為最新的透傳 attribute,但它并不是響應式的 (考慮到性能因素)。你不能通過偵聽器去監聽它的變化。如果你需要響應性,可以使用 prop。或者你也可以使用 onUpdated() 使得在每次更新時結合最新的 attrs 執行副作用

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

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

相關文章

11、“十四五”大數據產業發展規劃

數據是新時代重要的生產要素, 是國家基礎性戰略資源。 大數據是數據的集合, 以容量大、 類型多、 速度快、 精度準、 價值高為主要特征, 是推動經濟轉型發展的新動力,是提升政府治理能力的新途徑, 是重塑國家競爭優勢的新機遇。 大數據產業是以數據生成、 采集、 存儲、 加…

QT C++ QTableWidget 表格合并 setSpan 簡單例子

這里說的合并指的是單元格&#xff0c;不是表頭。span的意思是跨度、寬度、范圍。 setSpan函數需要設定行、列、行跨幾格&#xff0c;列跨幾格。 //函數原型如下 void QTableView::setSpan(int row, i nt column, 、 int rowSpanCount,/*行跨過的格數*/ int columnSpanCount…

【算法無用系列】電影推薦——余弦相似度計算用戶相似度原理

【算法無用系列】通過余弦相似度計算電影、用戶相似度 話不多說&#xff0c;本文通過電影推薦系統中&#xff0c;基于余弦相似度算法計算出用戶相似和電影相似原理。希望可以幫助一些代碼不懂的同學一些思路。 記錄用戶電影評分數據 一般情況來說&#xff0c;會根據用戶的行為…

什么是數字化轉型?

作者&#xff1a; 峽山老曹 數字神化 ”企業如何實現數字化轉型“是擺在現代企業面前一個無法回避的問題&#xff0c;數字化轉型的重要性不容忽視&#xff0c;它不僅是企業適應數字化時代的必然要求&#xff0c;更是提升競爭力、實現可持續發展的關鍵。隨著科技的飛速發展和市場…

學會spring boot 的這些技巧,編程瞬間變得簡單了,效率也提高了!

在Spring Boot應用中,斷言主要用于測試環境中驗證代碼行為是否符合預期。雖然Spring Boot自身不直接包含斷言庫,但通常我們會使用JUnit(一個廣泛應用于Java的單元測試框架)來進行測試,其中包含了豐富的斷言方法來幫助我們進行各種條件驗證。下面通過一些具體的示例來詳細說…

二叉樹的層序遍歷-力扣

本題是二叉樹的層序遍歷&#xff0c;通過一個隊列來控制遍歷的節點&#xff0c;二叉樹每層的節點和上一層入隊的節點個數是相同的&#xff0c;根據這一點編寫循環條件。 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* …

八、C語言:操作符詳解

一、移位操作符 1.1左移操作 左邊丟棄&#xff0c;右邊補0 1.2右移操作 算數右移&#xff1a;右邊丟棄&#xff0c;左邊補原符號位 邏輯右移&#xff1a;右邊丟棄&#xff0c;左邊補0 int main() {int a -1;int b a >> 1;printf("b%d\n",b);return 0; } 原碼…

【Linux進程篇】Linux進程管理應用——虛假的shell腳本

W...Y的主頁 &#x1f60a; 代碼倉庫分享&#x1f495; 前言&#xff1a;我們已經了解了進程的工作原理&#xff0c;并且學習了進程創建、進程終止、進程等待以及進程程序替換。為了更好的鞏固這些知識&#xff0c;我們可以創建一個簡易的shell命令行。 目錄 做一個簡易的s…

GAT1399協議分析(六)--校時

一、官方消息定義 DeviceIDType &#xff1a;GA/T1400.1,采集設備、 卡口點位、 采集系統、分析系統、視圖庫、應用平臺等設備編碼規則 TimeCorrectModeType&#xff1a; dateTime時間格式&#xff1a; TimeZone&#xff1a;時區&#xff0c;GAT1400里面沒有找到具體內容&…

臥式攪拌機:一鍵自動稱重輕松搞定

在現代化工業生產中&#xff0c;G效、精準的設備是提高生產效率、降低生產成本。近年來&#xff0c;臥式攪拌機一鍵自動稱重包裝機的出現&#xff0c;無疑為眾多行業帶來了變革。這種集攪拌、稱重、包裝于一體的智能化設備&#xff0c;以其G效、便捷、精準的特點&#xff0c;迅…

六軸機器手臂運動控制——直流伺服反饋系統設計(比賽項目計劃書+設計總結+硬件+源代碼+上位機等)

TW的硬件一直很強&#xff0c;這是難得的硬件創新比賽的優秀作品&#xff0c;資料非常完整理。 硬件設計&#xff0c;源碼&#xff0c;項目計劃書&#xff0c;甚至包含了事后的復盤總結文檔。 是不可多得的好資料。 項目系統框架圖 1. 硬件系統框架圖 (請以方塊圖形式呈現) …

C#.net MassTransit和DotNetCore.CAP區別

MassTransit和DotNetCore.CAP對比 https://github.com/MassTransit/MassTransit https://github.com/dotnetcore/CAP MassTransit和DotNetCore.CAP是兩種不同的.NET庫&#xff0c;它們在核心概念、設計目的和技術實現等方面存在差異。具體分析如下&#xff1a; 核心概念 Mas…

idea的代碼沒有提交到倉庫怎么撤回到本地?

代碼已經提交到變更列表但是還沒有push推送到倉庫上&#xff0c;可以用這個方法 點擊日志-右鍵要撤回的記錄-選擇撤銷提交 撤銷的又回到本地變更 當然你只能撤銷自己提交的&#xff0c;別人的你撤銷不了

python-題庫篇-為什么數組下標從0 開始而不是 1

為什么很多編程語言要把 0 作為第一個下標索引&#xff0c;而不是直觀的 1 呢&#xff1f; 這個問題 Dijkstra 已經解答過了&#xff0c;沒錯&#xff0c;就是你知道的 Dijkstra&#xff0c;Dijkstra 最短路徑算法&#xff0c;荷蘭語全名是 Edsger Wybe Dijkstra&#xff0c;于…

定制高溫隧道爐,如何判斷質量好壞

在現代工業生產中&#xff0c;高溫隧道爐扮演著不可或缺的角色。對于特定工藝要求&#xff0c;如陶瓷燒制、金屬熱處理等&#xff0c;定制化的高溫隧道爐更是不可或缺。然而&#xff0c;面對市場上琳瑯滿目的產品&#xff0c;如何判斷高溫隧道爐的質量好壞成為了企業決策者面臨…

js終止遞歸

終止遞歸 1. 實現目標&#xff1a;js 編寫遞歸方法 查找指定節點&#xff1b; 2. 需解決問題&#xff1a;找到所需節點后&#xff0c;遞歸不會終止&#xff0c;直到所有節點遍歷完成后才會停止&#xff0c;會消耗性能 3. 解決方案&#xff1a;優化遞歸方法&#xff0c;在找到…

解決vscode終端不顯示conda環境變量名稱問題【詳細步驟!實測可行!!】

最近在使用Visual Studio Code (VSCode) 時候&#xff0c;發現終端沒有正確顯示激活的conda環境名稱&#xff0c;搜了一下&#xff0c;找到原因&#xff0c;記錄一下&#xff0c;如果有人也遇到同樣的問題&#xff0c;可以收藏一下。 ??分別兩種情況&#xff0c;一是windows系…

一周學會Django5 Python Web開發 - Django5內置Auth認證系統-用戶登錄實現

鋒哥原創的Python Web開發 Django5視頻教程&#xff1a; 2024版 Django5 Python web開發 視頻教程(無廢話版) 玩命更新中~_嗶哩嗶哩_bilibili2024版 Django5 Python web開發 視頻教程(無廢話版) 玩命更新中~共計57條視頻&#xff0c;包括&#xff1a;2024版 Django5 Python we…

JVM學習-內存泄漏

內存泄漏的理解和分類 可達性分析算法來判斷對象是否是不再使用的對象&#xff0c;本質都是判斷一上對象是否還被引用&#xff0c;對于這種情況下&#xff0c;由于代碼的實現不同就會出現很多內存泄漏問題(讓JVM誤以為此對象還在引用&#xff0c;無法回收&#xff0c;造成內存泄…

旭日X3與英偉達Orin NX通過TCP傳輸圖片

觀前提醒&#xff1a;本文主要內容為使用Python在局域網內建立TCP連接并傳輸圖片信息&#xff0c;計算機為一塊旭日X3和一塊英偉達Orin NX。 一、什么是TCP TCP&#xff08;傳輸控制協議&#xff09;是一種可靠的、面向連接的協議&#xff0c;它確保數據包的順序傳輸和完整性…