【Vue-組件】學習筆記

目錄

  • <<回到導覽
  • 組件
    • 1.項目
      • 1.1.Vue Cli
      • 1.2.項目目錄
      • 1.3.運行流程
      • 1.4.組件的組成
      • 1.5.注意事項
    • 2.組件
      • 2.1.組件注冊
      • 2.2.scoped樣式沖突
      • 2.3.data是一個函數
      • 2.4.props詳解
      • 2.5.data和prop的區別
    • 3.組件通信
      • 3.1.父子通信
        • 3.1.1.父傳子(props)
        • 3.1.2.子傳父($emit)
      • 3.2.非父子通信
        • 3.2.1.事件總線
        • 3.2.2.provide-inject
      • 3.3.v-model詳解
      • 3.4.sync修飾符(已廢棄)
      • 3.5.(重點)ref和$refs
      • 3.6.ref和$refs選擇器
      • 3.7.$nextTick
    • 4.自定義指令
      • 4.1.指令的值
      • 4.2.封裝v-loading指令
    • 5.插槽
      • 5.1默認插槽
      • 5.2.后備內容
      • 5.3.具名插槽
      • 5.4.作用域插槽
    • 6.my-tag組件封裝

<<回到導覽

組件

1.項目

1.1.Vue Cli

官方提供的一個全局命令工具,可以快速生成vue項目的標準化基礎架子(集成webpack),開箱即用

使用步驟:

  1. 全局安裝(安裝一次即可)

    yarn global add @vue/cli// 或者
    npm i @vue/cli -g
    
  2. 查看vue/cli版本:

    vue --version
    
  3. 創建項目架子:

    vue create project-name
    
  4. 啟動項目:

     yarn serve// 或者npm run serve
    

啟動項目的命令并不固定,其取決于package.json文件
在這里插入圖片描述

1.2.項目目錄

在這里插入圖片描述

  • 第三包文件夾(依賴)被刪除,只要package.json還存在,就可以安裝回來

    npm i --force 或者 npm i --legacy-peer-deps

1.3.運行流程

在這里插入圖片描述

1.4.組件的組成

  • 語法高亮插件

在這里插入圖片描述

  • 三部分構成

    • template:結構 (有且只能一個根元素),在template中,最外層標簽只能為div盒子
    • script: js邏輯
    • style: 樣式 (可支持less,需要裝包)
  • 讓組件支持less

    1. style標簽,lang=“less” 開啟less功能
    2. 裝包:
      yarn add less less-loader -D 
      // 或者
      npm i less less-loader -D
      

1.5.注意事項

  1. 在組件的template中,最外面必須有一個div盒子

  2. 組件名稱最好采用大駝峰命名法,且至少兩個駝峰

  3. 有時候有些錯誤改正后依舊報錯(列如上面第二個報錯),重新啟動項目即可

  4. 啟動項目時在項目的根目錄下啟動(我們項目根目錄叫luyou)

2.組件

2.1.組件注冊

  • 局部注冊

    1. 在components文件夾創建組件 xxx.vue

    2. 在根組件App.vue導入

      // 導入組件
      // import xxx from 'xxx.vue的文件路徑'
      import HmHeader from './components/HmHeader'export default{// 局部注冊components:{// '組件名':組件對象,// HmHeader:HmHeader  同名可簡寫HmHeader}
      }
      
  • 全局注冊

    1. 在components文件夾創建組件 xxx.vue

    2. 在main.js進行全局注冊

      // 導入組件
      // import xxx from 'xxx.vue的文件路徑'
      import HmHeader from './components/HmHeader'// 調用Vue.component進行全局注冊
      // Vue.component('組件名',組件對象)
      Vue.component('HmHeader',HmHeader)
      

    一般都用局部注冊,如果發現是通用組件,再注冊為全局

2.2.scoped樣式沖突

  • 默認組件中的樣式會全局生效

  • 可以給組件加上scoped屬性,可以讓樣式只作用于當前組件

    <style scoped></style>
    

scoped的原理:

  1. 組件被都添加 data-v-hash (添加自定義屬性)
  2. css選擇器添加 [data-v-hash] (添加自定義屬性的屬性選擇器)

2.3.data是一個函數

在最開始的vue基本語法學習中,data被寫為data: {},鍵值(值為對象,對象又嵌套鍵值數據)

但在組件開發中,data選項必須是一個函數

data(){return {// 數據}
}
  • 這是因為組件具有復用性,在同一個組件的復用過程中,data里的數據應該不一樣,且數據不相互影響

  • 將data設置為一個函數,將數據寫進return返回值中,每次創建組件都會調用data函數,返回一個獨立數據對象,這些獨立的對象分別用于保存同一組件的不同次使用的數據。
    在這里插入圖片描述

2.4.props詳解

  • 定義:在組件使用時,注冊的一些自定義屬性

  • 作用:向子組件傳遞數據

  • 示例

    export default {props: ['w'],
    }
    

    在為子組件傳遞數據時,我們應該為組件的 prop 指定驗證要求

    props: {校驗的屬性名: {type: 類型,  // Number String Boolean ...required: true, // 是否必填default: 默認值, // 默認值validator (value) {// 自定義校驗邏輯return 是否通過校驗}}
    },
    
    • default和required一般不同時寫
    • default后面如果是復雜類型,則需要以函數的形式return一個默認值

    示例

    props: {w: {type: Number,//required: true,default: 0,validator(val) {if (val >= 100 || val <= 0) {console.error('傳入的范圍必須是0-100之間')return false} else {return true}},},},
    

2.5.data和prop的區別

  • data 的數據是自己的 → 隨便改
  • prop 的數據是外部的 → 不能直接改,要遵循 單向數據流

單向數據流:父級props 的數據更新,會向下流動,影響子組件。這個數據流動是單向的

3.組件通信

上面講到,data是一個函數,同一組件的不同的使用之間數據獨立,同樣,不同組件之間數據也不共享
在這里插入圖片描述

3.1.父子通信

在這里插入圖片描述

3.1.1.父傳子(props)
  • 父組件通過 props 將數據傳遞給子組件

    1. 在父組件中的子組件標簽添加動態屬性(App.vue)

      <MySon :title="say"></MySon>
      
    2. 子組件通過props進行接收

      export default {data() {return {};},props: ["title"],
      };
      
3.1.2.子傳父($emit)
  • 子組件利用 $emit 通知父組件修改更新

    1. 給父組件元素添加事件和處理方法

      <button @click="changeFn">say</button>
      
      changeFn() {// change為后面為子組件添加的事件名// "Hello"為要修改的值,也就是后面的形參newSay// 并不一定要傳字符串,也可以將"Hello"改為變量傳遞this.$emit("change", "Hello");
      },
      
    2. 觸發事件后,利用$emit將父組件發送改變數據的通知

    3. 在父組件中的子組件標簽添加事件,調用修改屬性的方法

      <MySon :title="say" @change="changeFn"></MySon>
      
      // 形參newSay為傳遞過來的值"Hello"
      changeFn(newSay) {this.say = newSay;
      },
      

3.2.非父子通信

3.2.1.事件總線

概念:創建創建一個都能訪問的事件總線,發送方向事件總線發送,

接收方向事件總線發送監聽

  1. 在src文件夾下創建一個utils文件夾,在該文件夾下創建一個js文件

  2. 創建一個空Vue實例(事件總線)

    import Vue from 'vue'
    const Bus = new Vue()
    export default Bus
    
  3. 接受方和發送方都將數據總線引入

    import Bus from '../utils/EventBus'
    
  4. A組件(發送方),觸發Bus的$emit事件

    // 'sendMsg為發送的數據的標識
    Bus.$emit('sendMsg', '這是一個消息')
    
  5. B組件(接受方),監聽Bus的 $on事件

    created () {// 形參msg為傳遞的信息('這是一個消息')Bus.$on('sendMsg', (msg) => {this.msg = msg})
    }
    
3.2.2.provide-inject

作用:跨層級共享數據
在這里插入圖片描述

  1. 父組件 provide提供數據

    export default {provide () {return {// 普通類型【非響應式】color: this.color, // 復雜類型【響應式】userInfo: this.userInfo, }}
    }
    
  2. .子/孫組件 inject獲取數據

    export default {inject: ['color','userInfo'],created () {console.log(this.color, this.userInfo)}
    }
    
  • provide提供的簡單類型的數據不是響應式的,復雜類型數據是響應式。(推薦提供復雜類型數據
  • 子/孫組件通過inject獲取的數據,不能在自身組件內修改

3.3.v-model詳解

  • v-model本質上是一個語法糖。例如應用在輸入框上,就是value屬性 和 input事件 的合寫

    <template><div id="app" ><input v-model="msg" type="text"><!-- 等價于 --><!-- 數據變,視圖跟著變 :value --><!-- 視圖變,數據跟著變 @input --><input :value="msg" @input="msg = $event.target.value" type="text"></div>
    </template>
    
  • $event 用于在模板中,獲取事件的形參

  • $event.target.value即獲取輸入框的值

  • 將輸入框的值賦值給data里的數據msg,再將msg通過:value賦值給輸入框,從而實現數據的雙向綁定。

注意

  1. 不同的表單元素, v-model在底層的處理機制是不一樣的。

    比如給checkbox使用v-model,底層處理的是:checked屬性和@change事件。

  2. v-model不能直接綁定父組件傳過來的數據,因為父組件通過prop屬性傳過來的數據不能直接修改。

3.4.sync修飾符(已廢棄)

  • 在上面的父子通信中,子組件不能直接修改父組件數據,而是通過$emit間接修改

  • 通過sync修飾符,子組件可以修改父組件傳過來的props值

  • 以上面的父子通信為例

    父組件

    <!-- 完整寫法 -->
    <MySon :title="say"  @update:title="isShow = $event" ></MySon><!-- 簡寫 -->
    <MySon :title.sync="say"></MySon>
    

    子組件

    props: {title: Boolean
    },
    this.$emit('update:title', 'Hello')
    

3.5.(重點)ref和$refs

  • 利用ref 和 $refs 可以用于 獲取 dom 元素組件實例(要在dom渲染完后才能獲取)

  • 獲取元素還可以通過document.querySeletctor()獲取,但是此方法是從整個頁面開始獲取

    • 類名問題:比如我們在子組件中獲取類名為app的元素,如果在此組件之前還有類名為app的元素,則會獲取之前的類名為app的元素
    • 解決方法:如果我們利用ref 和 $refs 可以用于 獲取 dom 元素,則會從當前組件開始獲取,避免類名問題。
  • 示例

    1. 給要獲取的盒子添加ref屬性

      <div ref="demo">我是渲染圖表的容器</div>
      
    2. 通過 this.$refs.demo 獲取

      mounted(){console.log(this.$refs.demo)
      }
      

3.6.ref和$refs選擇器

  • 利用ref 和 $refs 還可以用于 組件實例

    1. 在組件示例上,添加ref屬性

      <MySon ref="demo" ></MySon>
      
    2. 通過 this.$refs.demo 獲取,控制臺會打印組件對象

      mounted(){console.log(this.$refs.demo)// 控制臺// VueComponent {_uid: 2, _isVue: true, __v_skip: true, _scope: EffectScope, $options: {…}, …}
      }
      
    3. 我們可以通過this.$refs.demo.子組件方法名調用子組件方法,或者訪問子組件屬性,實現組件通信。

      注意:這種組件通信只是調用了子組件方法或者訪問子組件屬性,沒有實現雙向綁定

3.7.$nextTick

  • $nextTick用于實現vue的異步更新

  • 應用案例:編輯標題, 編輯框自動聚焦

    1. 效果:點擊編輯,顯示編輯框,并且讓編輯框,立刻獲取焦點

    2. 預想代碼

      this.isShowEdit = true		// 顯示輸入框
      this.$ref.input.focus()		// 獲取焦點
      
    3. 預想代碼并不能實現該效果,因為:

      • 當執行顯示輸入框代碼后,沒等dom渲染出顯示框,就執行到獲取焦點的代碼了(因為dom是異步更新),我們可以用$nextTick用于實現vue的異步更新。
      • vue異步更新的原因是提高性能,當點擊編輯按鈕的@click綁定的事件執行完畢后,才會更新視圖,這樣避免每執行完一行代碼就更新一次視圖。
    4. 利用$nextTick實現以上代碼的異步更新

      this.isShowEdit = true		// 顯示輸入框
      this.$nextTick(() => {this.$refs.inp.focus()	// 獲取焦點
      })
      
      • 當執行到$nextTick時,會更新渲染一次dom,輸入框渲染出來,再向下執行代碼
      • 說到dom異步更新,很多人想到利用延時器實現,但是延時器延遲時間是固定的,而執行到dom渲染的時間并不固定(和網絡、設備性能有關)。

    注意:

    ? $nextTick 內的函數體 一定是箭頭函數,這樣才能讓函數內部的this指向Vue實例

4.自定義指令

  • 與$nextTick類似,inserted會在指令所在元素被插入頁面時觸發
  • 全局注冊(下面以注冊實現上面點擊聚焦功能為例)

    //在main.js中
    Vue.directive('focus', {// el為指令綁定的元素 "inserted" (el) {el.focus()}
    })
    
  • 局部注冊

    //在Vue組件的配置項中
    directives: {"focus": {inserted (el) {el.focus()}}
    }
    
  • 指令使用

    <input v-focus ref="inp" type="text">
    

4.1.指令的值

與vue內置指令相同,我們也可以為自定義指令設置值

  • 示例:我們定義一個v-color指令,v-color的值變化時,帶有v-color指令的標簽也會變化

  • 指令注冊(局部注冊)

    directives: {color: {inserted (el, binding) {el.style.color = binding.value},update (el, binding) {el.style.color = binding.value}}
    }
    
    1. binding.value為指令值
    2. 指令值修改會觸發update函數(update也是一個生命周期鉤子)
    3. 我們指令的值可以設置為變量,這時我們就需要設置update函數

4.2.封裝v-loading指令

  • 在加載時,頁面通常會有一個loading動畫效果

  • 這個效果通常為一個蒙層(蒙層一般為偽元素)

  • loading的開啟和關閉只需要添加移除類即可(因為偽元素是css生成的,自然也可以通過操作css移除)

    示例

    <template><div class="main"><div class="box" v-loading = "isLoading"><ul><li v-for="item in list" :key="item.id" class="news"><div class="left"><div class="title">{{ item.title }}</div><div class="info"><span>{{ item.source }}</span><span>{{ item.time }}</span></div></div><div class="right"><img :src="item.img" alt=""></div></li></ul></div></div>
    </template><script>import axios from 'axios'export default {data () {return {list: [],isLoading: true}},async created () {const res = await axios.get('http://hmajax.itheima.net/api/news')setTimeout(() => {this.list = res.data.data// 移除蒙層this.isloading = false}, 2000)},// 定義指令directives: {loading: {inserted (el, binding) {binding.value?el.classList.add('loading'):el.classList.remove('loading')},update (el, binding) {binding.value?el.classList.add('loading'):el.classList.remove('loading')}}}}
    </script><style>/* 偽元素 */.loading:before {content: '';position: absolute;left: 0;top: 0;width: 100%;height: 100%;background: #fff url('./loading.gif') no-repeat center;}.box2 {width: 400px;height: 400px;border: 2px solid #000;position: relative;}.box {width: 800px;min-height: 500px;border: 3px solid orange;border-radius: 5px;position: relative;}.news {display: flex;height: 120px;width: 600px;margin: 0 auto;padding: 20px 0;cursor: pointer;}.news .left {flex: 1;display: flex;flex-direction: column;justify-content: space-between;padding-right: 10px;}.news .left .title {font-size: 20px;}.news .left .info {color: #999999;}.news .left .info span {margin-right: 20px;}.news .right {width: 160px;height: 120px;}.news .right img {width: 100%;height: 100%;object-fit: cover;}
    </style>
    

    知識點:

    • 安裝axios yarn add axios npm i axios

    • 定義指令部分:

      directives: {loading: {inserted (el, binding) {// 如果加載,顯示蒙層(移除loading類),否則,顯示蒙層binding.value?el.classList.add('loading'):el.classList.remove('loading')},update (el, binding) {binding.value?el.classList.add('loading'):el.classList.remove('loading')}}
      }
      
  • v-loading工作流程:有些同學看到這里可能有些疑問,組件定義里面的函數是什么時候執行的?

    1. 上面有提到,inserted會在指令所在元素被插入頁面時觸發
    2. 在上面示例中,先執行created生命周期鉤子,向服務器發送獲取數據請求,然后再將返回數據更新到 list 中,并改變isLoading

5.插槽

5.1默認插槽

  • 讓組件內部的一些 結構 支持 自定義

  • 語法

    1. 組件內需要定制的結構部分,改用<slot></slot>占位
    2. 給插槽傳入內容時,可以傳入純文本、html標簽、組件
    3. 在標簽內部, 傳入結構替換slot
  • 示例:彈框插槽

    在這里插入圖片描述

    在這里插入圖片描述

5.2.后備內容

上面示例中,如果不傳內容,則會不會顯示

在這里插入圖片描述

我們可以為插槽設置默認顯示內容,如果不傳內容,則會顯示默認顯示內容

  • 我們只需要在封裝組件時,為預留的 <slot> 插槽提供后備內容即可(默認內容)

在這里插入圖片描述

5.3.具名插槽

一個組件中,很多時候不單單只有一個插槽,這時我們需要使用name屬性區分不同插槽。

  • 使用name屬性區分不同插槽。

  • template配合v-slot:名字來分發對應標簽

  • 為方便書寫,上面可以將 v-slot: 替換為 #

    在這里插入圖片描述

示例

  1. 根組件(App.vue)

    <div id="app"><HelloWorld><template #age>年齡</template><template #name>姓名</template><template #gender>性別</template></HelloWorld>
    </div>
    
  2. 子組件(HelloWorld.vue)

    <div><slot name="name"></slot><hr /><slot name="age"></slot><hr /><slot name="gender"></slot>
    </div>
    

    顯示順序取決于子組件的插槽位置

5.4.作用域插槽

  • 作用域插槽不屬于插槽的一種分類

  • 定義slot插槽的同時,可以傳值,給插槽綁定數據,這些數據與插槽綁定的組件也可以使用

    1. 給 slot 標簽, 以 添加屬性的方式傳值(組件中)

      <slot :id="item.id" msg="測試文本"></slot>
      
    2. 在template中, 通過 #插槽名= "obj" 接收,默認插槽名為 default(根組件中)

      <MyTable :list="list"><template #default="obj"><button @click="del(obj.id)">刪除</button></template>
      </MyTable>
      
  • 所有添加的屬性, 都會被收集到一個對象中,我們也可以將這個對象結構來使用

    <MyTable :list="list"><template #default="{id, msg}"><button @click="del(id)">刪除</button></template>
    </MyTable>
    

6.my-tag組件封裝

實現功能

  1. 雙擊顯示,自動聚焦
  2. 失去焦點,隱藏輸入框
  3. 回顯標簽內容
  4. 內容修改,回車,修改標簽信息

代碼

  1. MyTag

    <template><div class="my-tag"><inputv-if="isEdit"	v-focusclass="input"type="text"placeholder="輸入標簽":value="value"@blur="isEdit = false"@keyup.enter="handleEnter"/><div v-else@dblclick="handleClick"class="text">{{ value }}</div></div>
    </template><script>
    export default {props: {value: String},data () {return {isEdit: false}},methods: {handleClick () {// 雙擊后,切換到顯示狀態 (Vue是異步dom更新)this.isEdit = true},handleEnter (e) {// 非空處理if (e.target.value.trim() === '') return alert('標簽內容不能為空')// 由于父組件是v-model,觸發事件,需要觸發 input 事件this.$emit('input', e.target.value)// 提交完成,關閉輸入狀態this.isEdit = false}}
    }
    </script><style lang="less" scoped>
    .my-tag {cursor: pointer;.input {appearance: none;outline: none;border: 1px solid #ccc;width: 100px;height: 40px;box-sizing: border-box;padding: 10px;color: #666;&::placeholder {color: #666;}}
    }
    </style>
    
  2. App.vue

    <template><div><MyTag v-model="item.tag"></MyTag>     </div>
    </template><script>
    import MyTag from './components/MyTag.vue'export default {name: 'TableCase',components: {MyTag,},data () {return {// 測試組件功能的臨時數據tempText: '水杯',    }}
    }
    </script><style lang="less" scoped>
    .table-case {width: 1000px;margin: 50px auto;img {width: 100px;height: 100px;object-fit: contain;vertical-align: middle;}
    }</style>
    
  3. main.js

    import Vue from 'vue'
    import App from './App.vue'
    Vue.config.productionTip = false// 封裝全局指令 focus
    Vue.directive('focus', {// 指令所在的dom元素,被插入到頁面中時觸發inserted (el) {el.focus()}
    })new Vue({render: h => h(App),
    }).$mount('#app')
    

知識點

  • 雙擊觸發事件:@dblclick

  • 兩種自動聚焦方法

    在實現點擊盒子切換為inpu標簽并自動聚焦時,我們可以通過ref和refs操作dom,再配合$nextTick異步實現,不過為了提高復用性,我們通過自定義指令,封裝到mian.js實現該功能

  • 指令修飾符實現回車事件監聽,@keyup.enter,由于該案例數據是由父組件傳遞過來的,所以還要將該值發送給父組件

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

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

相關文章

【Kafka基礎】單機安裝與配置指南,從零搭建環境

學習Kafka&#xff0c;掌握Kafka的單機部署是理解其分布式特性的第一步。本文將手把手帶你完成Kafka單機環境的安裝、配置及基礎驗證&#xff0c;涵蓋常見問題排查技巧。 1 環境準備 1.1 系統要求 操作系統&#xff1a;CentOS 7.9依賴組件&#xff1a;JDK 8&#xff08;Kafka …

OpenCV 圖形API(21)逐像素操作

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 在OpenCV的G-API模塊中&#xff0c;逐像素操作指的是對圖像中的每個像素單獨進行處理的操作。這些操作可以通過G-API的計算圖&#xff08;Graph …

CubeMX配置STM32VET6實現網口通信(無操作系統版-附源碼)

下面是使用CubeMX配置STM32F407VET6,實現以太網通訊(PHY芯片為LAN8720)的具體步驟總結: 一、硬件連接方式: 硬件原理圖: 使用外部晶振為PHY芯片提供時鐘。 STM32F407VET6 與 LAN8720 采用 RMII 模式連接。STM32F407VET6引腳功能(RMII)LAN8720引腳PA1ETH_REF_CLKREF_CL…

Android Compose 中獲取和使用 Context 的完整指南

在 Android Jetpack Compose 中&#xff0c;雖然大多數 UI 組件不再需要直接使用 Context&#xff0c;但有時你仍然需要訪問它來執行一些 Android 平臺特定的操作。以下是幾種在 Compose 中獲取和使用 Context 的方法&#xff1a; 1. 使用 LocalContext 這是 Compose 中最常用…

在VMware下Hadoop分布式集群環境的配置--基于Yarn模式的一個Master節點、兩個Slaver(Worker)節點的配置

你遇到的大部分ubuntu中配置hadoop的問題這里都有解決方法&#xff01;&#xff01;&#xff01;&#xff08;近10000字&#xff09; 概要 在Docker虛擬容器環境下&#xff0c;進行Hadoop-3.2.2分布式集群環境的配置與安裝&#xff0c;完成基于Yarn模式的一個Master節點、兩個…

PID燈控算法

根據代碼分析&#xff0c;以下是針對PID算法和光敏傳感器系統的優化建議&#xff0c;分為算法優化、代碼結構優化和系統級優化三部分&#xff1a; 一、PID算法優化 1. 增量式PID 輸出平滑 // 修改PID計算函數 uint16_t PID_calculation_fun(void) {if(PID_Str_Val.Tdata >…

文件映射mmap與管道文件

在用戶態申請內存&#xff0c;內存內容和磁盤內容建立一一映射 讀寫內存等價于讀寫磁盤 支持隨機訪問 簡單來說&#xff0c;把磁盤里的數據與內存的用戶態建立一一映射關系&#xff0c;讓讀寫內存等價于讀寫磁盤&#xff0c;支持隨機訪問。 管道文件&#xff1a;進程間通信機…

在 Java 中調用 ChatGPT API 并實現流式接收(Server-Sent Events, SSE)

文章目錄 簡介OkHttp 流式獲取 GPT 響應通過 SSE 流式推送前端后端代碼消息實體接口接口實現數據推送給前端 前端代碼創建 sseClient.jsvue3代碼 優化后端代碼 簡介 用過 ChatGPT 的伙伴應該想過自己通過調用ChatGPT官網提供的接口來實現一個自己的問答機器人&#xff0c;但是…

硬盤分區格式之GPT(GUID Partition Table)筆記250407

硬盤分區格式之GPT&#xff08;GUID Partition Table&#xff09;筆記250407 GPT&#xff08;GUID Partition Table&#xff09;硬盤分區格式詳解 GPT&#xff08;GUID Partition Table&#xff09;是替代傳統 MBR 的現代分區方案&#xff0c;專為 UEFI&#xff08;統一可擴展固…

Vite環境下解決跨域問題

在 Vite 開發環境中&#xff0c;可以通過配置代理來解決跨域問題。以下是具體步驟&#xff1a; 在項目根目錄下找到 vite.config.js 文件&#xff1a;如果沒有&#xff0c;則需要創建一個。配置代理&#xff1a;在 vite.config.js 文件中&#xff0c;使用 server.proxy 選項來…

交換機與ARP

交換機與 ARP&#xff08;Address Resolution Protocol&#xff0c;地址解析協議&#xff09; 的關系主要體現在 局域網&#xff08;LAN&#xff09;內設備通信的地址解析與數據幀轉發 過程中。以下是二者的核心關聯&#xff1a; 1. 基本角色 交換機&#xff1a;工作在 數據鏈…

【Spring】小白速通AOP-日志記錄Demo

這篇文章我將通過一個最常用的AOP場景-方法調用日志記錄&#xff0c;帶你徹底理解AOP的使用。例子使用Spring BootSpring AOP實現。 如果對你有幫助可以點個贊和關注。謝謝大家的支持&#xff01;&#xff01; 一、Demo實操步驟&#xff1a; 1.首先添加Maven依賴 <!-- Sp…

git功能點管理

需求&#xff1a; 功能模塊1 已經完成&#xff0c;已經提交并推送到遠程&#xff0c;準備交給測試。功能模塊2 已經完成&#xff0c;但不提交給測試&#xff0c;繼續開發。功能模塊3 正在開發中。 管理流程&#xff1a; 創建并開發功能模塊1&#xff1a; git checkout main…

QGIS實戰系列(六):進階應用篇——Python 腳本自動化與三維可視化

歡迎來到“QGIS實戰系列”的第六期!在前幾期中,我們從基礎操作到插件應用逐步提升了 QGIS 技能。這一篇,我們將邁入進階領域,探索如何用 Python 腳本實現自動化,以及如何創建三維可視化效果,讓你的 GIS 項目更高效、更立體。 第一步:Python 腳本自動化 QGIS 內置了 Py…

高德地圖 3D 渲染-區域紋理圖添加

引入-初始化地圖&#xff08;關鍵代碼&#xff09; // 初始化頁面引入高德 webapi -- index.html 文件 <script src https://webapi.amap.com/maps?v2.0&key您申請的key值></script>// 添加地圖容器 <div idcontainer ></div>// 地圖初始化應該…

ffmpeg視頻轉碼相關

ffmpeg視頻轉碼相關 簡介參數 實戰舉栗子獲取視頻時長視頻轉碼mp4文件轉為hls m3u8 ts等文件圖片轉視頻抽取視頻第一幀獲取基本信息 轉碼日志輸出詳解轉碼耗時測試 簡介 FFmpeg 是領先的多媒體框架&#xff0c;能夠解碼、編碼、 轉碼、復用、解復用、流、過濾和播放 幾乎所有人…

【ISP】HDR技術中Sub-Pixel與DOL的對比分析

一、原理對比 Sub-Pixel&#xff08;空間域HDR&#xff09; ? 核心機制&#xff1a;在單個像素內集成一大一小兩個子像素&#xff08;如LPD和SPD&#xff09;&#xff0c;利用其物理特性差異&#xff08;靈敏度、滿阱容量&#xff09;同時捕捉不同動態范圍的信號。 ? 大像素&…

Vulnhub-IMF靶機

本篇文章旨在為網絡安全滲透測試靶機教學。通過閱讀本文&#xff0c;讀者將能夠對滲透Vulnhub系列IMF靶機有一定的了解 一、信息收集階段 靶機下載地址&#xff1a;https://www.vulnhub.com/entry/imf-1,162/ 因為靶機為本地部署虛擬機網段&#xff0c;查看dhcp地址池設置。得…

Linux內核中TCP協議棧的實現:tcp_close函數的深度剖析

引言 TCP(傳輸控制協議)作為互聯網協議族中的核心協議之一,負責在不可靠的網絡層之上提供可靠的、面向連接的字節流服務。Linux內核中的TCP協議棧實現了TCP協議的全部功能,包括連接建立、數據傳輸、流量控制、擁塞控制以及連接關閉等。本文將深入分析Linux內核中tcp_close…

java+postgresql+swagger-多表關聯insert操作(七)

入參為json&#xff0c;然后根據需要對多張表進行操作&#xff1a; 入參格式&#xff1a; [{"custstoreName":"swagger-測試經銷商01","customerName":"swagger-測試客戶01","propertyNo":"swaggertest01",&quo…