Vue腳手架搭建項目+基礎知識

1. 使用腳手架創建項目

1.1 準備工作

  • ? ? ? ? win+R,在彈出的數據框中輸入cmd,數據命令查看node以及npm版本?

  • ? ? ? ? 下載vue cli

1.2 創建項目

1.2.1 創建一個英文目錄文件夾,cmd打開命令命令提示符

1.2.2 vue ui命令打開控制臺

1.2.3 創建項目

? ? ? ? 創建成功

?1.3 項目結構

1.4 將項目在VSCode打開,終端運行頁面

? ? ? ? ?使用命令npm run serve命令打開

1.5 修改服務端口號

? ? ? ? 在vue.config.js中修改服務端口號,防止與后端tomcat端口沖突

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({transpileDependencies: true,devServer:{port: 7070}
})

? ? ? ? ?保存文件,重啟項目端口號修改完畢

2. vue基礎回顧

2.1 文本插值

<template><div class="hello">{{ name }}</div>
</template><script>
export default {data() {return {name: 'I LOVE YOU'}}
}
</script><!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

2.2 屬性綁定

? ? ? ? 為標簽的屬性綁定data方法中返回的屬性

<template><div class="hello">{{ name }}<input type="name" :value="age"></div>
</template><script>
export default {data() {return {name: 'I LOVE YOU',age: 18}}
}
</script><!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

2.3 事件綁定

<template><div class="hello">{{ name }}<input type="name" :value="age"><!-- 點擊事件 --><button @click="dianji()">點擊</button></div>
</template><script>
export default {data() {return {name: 'I LOVE YOU',age: 18}},methods: {dianji() {alert('點擊了')}}
}
</script><!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

2.4 雙向綁定

? ? ? ? 通過v-model將數據區的數據與輸入框數據雙向綁定

<template><div class="hello">{{ name }}<input type="name" :value="age"><!-- 點擊事件 --><button @click="dianji()">點擊</button><input type="text" v-model="name"></div>
</template><script>
export default {data() {return {name: 'I LOVE YOU',age: 18}},methods: {dianji() {alert('點擊了')}}
}
</script><!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

2.5 條件渲染

<template><div class="hello"><div v-if="sex==1">男</div><div v-else-if="sex==2">女</div><div v-else>未知</div></div>
</template><script>
export default {data() {return {sex:2}},methods: {}
}
</script><!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

2.6 axios

? ? ? ? Axios是一個基于promise的網絡請求庫,作用于瀏覽器和node.js中,用于發ajax異步請求,實現前后端交互

2.6.1 下載axios

npm install axios

2.6.2 在項目中使用axios

2.6.3 axios的API

  • url:請求路徑
  • data:請求體數據,最常見的是JSON格式
  • config:配置對象,可以設置查詢參數,請求頭信息

?2.6.4 axios請求的跨域問題

? ? ? ? 正常情況下,前端數據一個服務,后端屬于一個服務,在不同的域里,所以會出現跨域問題,解決方法就是在vue.config.js文件中配置代理

<template><button @click="request11()"></button></div>
</template><script>
// 導入axios
import axios from 'axios'export default {data() {return {sex:2}},methods: {request11(){axios.post('http://localhost:8080/user/login',{username:'admin', // json數據password:'123456'}).then(res=>{ // 成功回調console.log(res.data)}).catch(err=>{ // 錯誤回調console.log(err)})}}
}
</script>
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({transpileDependencies: true,devServer:{port: 7070,proxy:{// 配置請求代理,用于將特定請求轉發到后端服務器,解決跨域問題'/api':{// 將請求轉發到的目標服務器地址target:'http://localhost:8080',changeOrigin:true, // 是否更改請求的來源,通常用于處理虛擬主機的情況pathRewrite:{'^/api':'' // 移除請求路徑中的 '/api' 前綴,以便目標服務器正確處理請求}}}}
})

2.6.5 發送請求

  • 方式一
<template><div class="hello"><div v-if="sex==1">男</div><div v-else-if="sex==2">女</div><div v-else>未知</div><button @click="request11()">按鈕</button></div>
</template><script>
// 導入axios
import axios from 'axios'export default {data() {return {sex:2}},methods: {request11(){  axios.post('http://localhost:8080/user/login',{username:'admin', // json數據password:'123456'}).then(res=>{ // 成功回調console.log(res.data)}).catch(err=>{ // 錯誤回調console.log(err)})},req(){axios.get('http://localhost:8080/user/getUserById',{// 攜帶請求頭headers:{token:'xxxxxxxxxxxxxxxxxxxxxxxxxx'}}).then(res=>{console.log(res.data)}).catch(err=>{console.log(err)})}}
}
</script><!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
  • 方式二
<button @click="handleSend()"></button>handleSend(){axios({url:'http://localhost:8080/user/login',method:'post',data:{username:'admin',password:'<PASSWORD>'}}).then(res=>{console.log(res.data)axios({url:'http://localhost:8080/user/info',method:'get',headers:{token:res.data.data.token}})}).catch(err=>{console.log(err)})}

3. 路由Vue-Router

? ? ? ? vue屬于單頁面應用,路由的作用就是根據瀏覽器路徑不同,用不同的視圖組件替換掉這個頁面內容。實現不同的路徑,對應不同的頁面展示

3.1 創建帶有路由的項目

? ? ? ? 創建好之后,package.json中有vue-router的依賴

? ? ? ? main.js中引入了router,說明這個項目具備了路由功能

3.2 路由配置

路由組成:

  • VueRouter:路由器,根據路由請求在路由視圖中動態渲染對應的視圖組件
  • <router-link>:路由鏈接組件,瀏覽器會解析成<a>
  • <router-view>:路由視圖組件,用來展示與路由路徑匹配的視圖組件

  • index.js中維護路由

  • ?App.vue,<router-link>標簽生成超鏈接

  • <router-view>:路由視圖組件不能刪掉!!!

???????路由視圖組件起到的是占位符的作用

3.3 路由跳轉

有兩種方式:

  • 標簽式
  • 編程式

標簽式就是上面演示的那種,編程式如下:

<template><div id="app"><nav><router-link to="/">Home</router-link> |<router-link to="/about">About</router-link><input type="button" value="編程式跳轉" @click="jump()"></nav><!-- <router-view>:路由視圖組件 --><router-view/></div>
</template><script>
export default {methods: {jump() {this.$router.push('/about')}}
}
</script><style>
#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;
}nav {padding: 30px;
}nav a {font-weight: bold;color: #2c3e50;
}nav a.router-link-exact-active {color: #42b983;
}
</style>

? ? ? ? 當用戶輸入的路徑不對時,都會重定向到404頁面,一張圖告訴你如何重定向到不存在的頁面:

4. 嵌套路由

? ? ? ? 嵌套路由是組件內要切換內容,就需要用到嵌套路由(子路由)

4.1 案例

????????以以下這個案例給大家分析:

實現步驟:

1)安裝并導入elementui,實現頁面布局(container布局容器)--ContainerView.vue

  • 下載

使用命令下載elementui:npm i element-ui -S

  • 在main.js中導入elementui
import Vue from 'vue'
import App from './App.vue'
import router from './router'
// 導入elementui
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';Vue.config.productionTip = false
// 全局使用elementui
Vue.use(ElementUI);new Vue({router,render: h => h(App)
}).$mount('#app')
  • ?創建視圖組件
<template><el-container><el-header>Header</el-header><el-container><el-aside width="200px">Aside</el-aside><el-main>Main</el-main></el-container>
</el-container>
</template><script>
export default {}
</script><style>.el-header, .el-footer {background-color: #B3C0D1;color: #333;text-align: center;line-height: 60px;}.el-aside {background-color: #D3DCE6;color: #333;text-align: center;line-height: 200px;}.el-main {background-color: #E9EEF3;color: #333;text-align: center;line-height: 160px;}body > .el-container {margin-bottom: 40px;}.el-container:nth-child(5) .el-aside,.el-container:nth-child(6) .el-aside {line-height: 260px;}.el-container:nth-child(7) .el-aside {line-height: 320px;}
</style>
  • 在main.js中配置路由跳轉

2)提供子視圖組件,用于效果展示

  • P1View.vue
<template><div>這是P1View</div>
</template><script>
export default {}
</script><style>
</style>
  • ?P2View.vue
<template><div>這是P2View</div>
</template><script>
export default {}
</script><style>
</style>
  • ?P3View.vue
<template><div>這是P3View</div>
</template><script>
export default {}
</script><style>
</style>

3)在src/router/index.js中配置路由映射規則(嵌套路由配置)

import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue'Vue.use(VueRouter)const routes = [// 維護路由表,某個路由路徑對應哪個視圖組件{path: '/',name: 'home',// 靜態加載component: HomeView},{path: '/about',name: 'about',// route level code-splitting// this generates a separate chunk (about.[hash].js) for this route// which is lazy-loaded when the route is visited.// 懶加載component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')},{path: '/test',component: () => import( '../views/404View.vue')},{path: '/c',component: () => import( '../views/container/containerView.vue'),// 重定向到p1redirect: '/c/p1',children:[{path: '/c/p1',component: () => import( '../views/container/P1View.vue')},{path: '/c/p2',component: () => import( '../views/container/P2View.vue')},{path: '/c/p3',component: () => import( '../views/container/P3View.vue')}]},{path:"*",redirect: '/404'}
]const router = new VueRouter({routes
})export default router

4)在布局容器視圖中添加<router-view>,實現子視圖組件展示

<template><el-container><el-header>Header</el-header><el-container><el-aside width="200px">Aside</el-aside><el-main><!-- 占位符 --><router-view/></el-main></el-container>
</el-container>
</template>

5)在布局容器視圖中添加<router-link>,實現路由請求

<template><el-container><el-header>Header</el-header><el-container><el-aside width="200px"><!-- 路由請求:生成超鏈接 --><router-link to="/c/p1">P1</router-link><br><router-link to="/c/p2">P2</router-link><br><router-link to="/c/p3">P3</router-link></el-aside><el-main><!-- 占位符 --><router-view/></el-main></el-container>
</el-container>
</template><script>
export default {}
</script><style>.el-header, .el-footer {background-color: #B3C0D1;color: #333;text-align: center;line-height: 60px;}.el-aside {background-color: #D3DCE6;color: #333;text-align: center;line-height: 200px;}.el-main {background-color: #E9EEF3;color: #333;text-align: center;line-height: 160px;}body > .el-container {margin-bottom: 40px;}.el-container:nth-child(5) .el-aside,.el-container:nth-child(6) .el-aside {line-height: 260px;}.el-container:nth-child(7) .el-aside {line-height: 320px;}
</style>

5. 狀態管理vuex

5.1 介紹

  • vuex是一個專門為Vue.js應用程序開發的狀態管理庫
  • vuex可以在多個組件之間共享數據,并且共享的數據是響應式的,即數據的變更能即使渲染到模板
  • vuex采用集中式存儲管理所有組件的狀態

5.2 vuex核心概念

5.3 使用方式

5.3.1 創建攜帶vuex的項目

  • index.js
import Vue from 'vue'
import Vuex from 'vuex'Vue.use(Vuex)// 集中管理多個組件共享的數據
export default new Vuex.Store({state: {},getters: {},mutations: {},actions: {},modules: {}
})
  • main.js
import Vue from 'vue'
import App from './App.vue'
import store from './store'Vue.config.productionTip = falsenew Vue({store, // 創建vuex實例render: h => h(App)
}).$mount('#app')

5.3.2 定義展示共享數據

5.3.3 在mutations中定義函數,修改共享數據

5.3.4 在actions中定義函數,用于調用mutation

// import { set } from 'core-js/core/dict'
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'Vue.use(Vuex)// 集中管理多個組件共享的數據
export default new Vuex.Store({// 共享數據state: {name:'未登錄游客'},getters: {},// 修改共享數據只能通過mutation實現,必須是同步操作mutations: {setName(state, name){state.name = name}},// 封裝異步操作,不能直接修改共享數據,只能通過mutation來實現actions: {setNameByAxios(context){axios({url:"/api/getUserInfo",method:"POST",data:{username:"admin",password:"123456"}}).then(res=>{if(res.data.code == 1){// 異步請求后,需要修改共享數據,只能通過mutation來實現// 在action中調用mutation中定義的setName方法context.commit("setName",res.data.username)}})}},modules: {}
})

? ? ? ?在vue.config.js 配置重定向

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({transpileDependencies: true,devServer: {port: 8081,proxy: {// 將含有/api的字段重定向成 http://localhost:8080'/api': {target: 'http://localhost:8080',changeOrigin: true,pathRewrite: {// 重寫路徑,將含有/api的字段替換成 (空)'^/api': ''}}}}
})

6. TypeScript

6.1 TypeScript介紹

  • TypeScript是微軟推出的開源語言

  • TypeScript是JavaScript的超集(js有的ts都有)

  • TypeScript在js基礎上做了類型支持

  • TypeScript文件擴展名為ts

  • TypeScript可編譯成標準的JavaScript,并且在編譯時進行類型檢查

6.2 TypeScript常用類型

6.2.1 創建攜帶TypeScripe的項目

????????類型標注的位置:

  • 標注變量
  • 標注參數
  • 標注返回值

6.2.2 字符串類型、數據類型、布爾類型

// 字符串類型
let str: string = 'I LOVE YOU 1314';// 數字類型
let num: number = 1314;// 布爾類型
let bool: boolean = true;console.log(str, num, bool);console.log("-------------------------");// 字面量類型
function printTest(s:string,alignment:'left'|'center'|'right'){console.log(s,alignment)
}
// 調用函數
printTest('I LOVE YOU 1314','left');console.log("-------------------------");// interface 接口類型
interface Cat{name:string;// ? 可選屬性age?:number;
}
// 定義變量,并且指定為Cat類型
const c1:Cat = {name:'Tom',age:10}
const c2:Cat = {name:'Tom'}console.log("-------------------------");// class類 - 基本使用
class User{name:string;constructor(name:string){this.name = name;}study(){console.log('I am '+this.name);}
}
// 使用User類型
const user = new User('Tom');// 輸出類中的屬性
console.log(user.name);// 調用類中的方法
user.study();console.log("-------------------------");// class類 - 實現接口
interface Animal{name:string;eat():void;
}// 定義一個類實現Animal接口
class Bird implements Animal{name:string;constructor(name:string){this.name = name;}eat():void{console.log('I am eating');}
}
//  創建類型為Bird的對象
const bird = new Bird('小鳥');
console.log(bird.name);
bird.eat();// class類 - 繼承Bird類
class Parrot extends Bird{say(){console.log(this.name+' can say');}
}
const parrot = new Parrot('鸚鵡');
console.log(parrot.name);
parrot.eat();
parrot.say();

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

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

相關文章

微信小程序下單頁—地址列表頁—新增地址頁 頁面交互

新增地址流程&#xff1a; 下單頁 → 地址列表頁 (1次跳轉)地址列表頁 → 新增地址頁 (1次跳轉)保存地址 → 返回地址列表頁 (1次返回&#xff0c;自動刷新列表) 選擇地址流程&#xff1a; 地址列表頁 → 選中地址 → 返回下單頁 (1次返回) 更換地址&#xff1a; 下單頁 → 地址…

JVM與JMM

為了更清晰地對比JVM和JMM&#xff0c;我們可以采用表格形式&#xff0c;從定義、功能、結構、與多線程關系等方面進行詳細比較&#xff1a; 對比項JVM&#xff08;Java Virtual Machine&#xff09;JMM&#xff08;Java Memory Model&#xff09;定義一種虛構的計算機&#x…

【Docker基礎】Docker數據卷管理:docker volume rm及其參數詳解

目錄 1 引言&#xff1a;Docker Volume 的生命周期管理 2 docker volume rm命令基礎 2.1 命令作用 2.2 命令語法 3 參數深度解析 3.1 基礎參數表 3.2 高級參數詳解 3.2.1 --force&#xff08;-f&#xff09; 4 Volume刪除前置條件 4.1 可刪除狀態判斷 4.2 常見報錯處…

嵌入式系統內核鏡像相關(十)

文章目錄 前言一、點亮多個led燈的基礎實驗以及其中的問題1.1 基礎流程1.1.1 alinx教程的問題1.1.1.1 驅動程序中的亮/滅邏輯修改&#xff01;1.1.1.1.1 邏輯錯誤的修改1.1.1.1.2 多燈亮/滅 1.1.1.2 驅動程序中引腳的問題以及與裸機開發的區別&#xff08;重要&#xff09;1.1.…

Word和Excel批量轉PDF新方法,操作簡單

PDF是一種跨平臺的文檔格式&#xff0c;無論在任何設備上查看&#xff0c;其排版、字體和圖像都不會發生變化。這確保了文檔的一致性&#xff0c;避免了由于不同軟件版本或操作系統引起的顯示問題。這款小巧的工具大小不到2MB&#xff0c;使用起來異常簡單。只需要把需要轉換的…

AI搜索 MCP最佳實踐

背景 那些 LLM 不知道的事 嘗試直接詢問LLM“今天天氣如何”時&#xff0c;會發現LLM無法回答——它既不知道“今天”是哪天&#xff0c;也無法獲取地理位置信息。這揭示了LLM的局限&#xff1a;缺乏與外部工具和實時數據的交互能力。 為解決這一問題&#xff0c;MCP&#x…

JVM 簡介與作用

&#x1f680; JVM 簡介與作用 &#x1f4da; 深入理解 Java 虛擬機的核心概念與重要作用 &#x1f4d6; 目錄 &#x1f914; 什么是 Java 虛擬機&#xff08;JVM&#xff09;&#x1f310; JVM 在 Java 生態中的核心地位&#x1f500; JVM 跨平臺原理剖析&#x1f4dd; 總結 …

? OpenAudio S1:影視級文本轉語音與語音克隆Mac整合包

? OpenAudio S1&#xff1a;影視級文本轉語音與語音克隆Mac整合包 &#x1f680; OpenAudio S1 簡介 OpenAudio S1 是由 Fish Audio 開發的 Fish Speech 系列的最新一代人工智能語音生成模型。該模型旨在大幅提升 AI 語音生成的技術水平&#xff0c;為用戶提供更加自然、富有表…

spring加載外部properties文件屬性時,讀取到userName變量值和properties文件的值不一致

問題 使用spring DI注入外部properties文件屬性時&#xff0c;讀取到userName變量值和properties文件的值不一致。 bean屬性注入&#xff1a; <!--加載配置文件--> <context:property-placeholder location"classpath:*.properties"/><bean id"…

黑馬點評系列問題之基礎篇p7 06初識redis無法在虛擬機查到圖形化界面存進去的鍵

問題描述 在RESP中輸入了一些鍵(name,age等這些) 但是在圖形化界面里面輸入的&#xff0c;在非圖形化界面就找不到&#xff0c;在非圖形化界面里輸入的&#xff0c;在圖形化界面里就可以查到。 原因分析及解決 經過多次實驗&#xff0c;發現是因為在添加鍵名的時候&#xff0…

在VMware虛擬機中安裝Windows 98時,Explorer提示“該程序執行了非法操作,即將關閉”的解決辦法

在使用iso文件&#xff08;MD5: 0E496B5DCC519F550AAF0BCFBB4A11EA&#xff09;安裝Windows98時&#xff0c;遇到此提示。 雖然原因未知&#xff0c;也無需深入探究&#xff0c;但是根據網友在 https://www.bilibili.com/opus/435866522585702782 中給出的相似經驗&#xff…

在瀏覽器中使用SQLite(官方sqlite3.wasm)

有人可能會問&#xff1a;既然瀏覽器里又內置得IndexedDB&#xff0c;而且在IndexedDB里存數據&#xff0c;關了瀏覽器數據也不會丟&#xff0c;為什么還要在瀏覽器里用SQLite? 實際上&#xff0c;當 IndexedDB 內的數據量增多&#xff0c;數據和數據之間的關系變得復雜&…

數據結構(Java)--位運算

前言 本文為本小白學習數據結構的筆記&#xff0c;將以算法題為導向&#xff0c;向大家更清晰的介紹數據結構相關知識&#xff08;算法題都出自B站馬士兵教育——左老師的課程&#xff0c;講的很好&#xff0c;對于想入門刷題的人很有幫助&#xff09; 為什么要使用為位運算 位…

秋招Day14 - Redis - 應用

Redis如何實現異步消息隊列&#xff1f; List配合LPUSH和RPOP。 另外就是用 Redis 的 Pub/Sub 來實現簡單的消息廣播和訂閱。 但是這兩種方式都是不可靠的&#xff0c;因為沒有 ACK 機制所以不能保證訂閱者一定能收到消息&#xff0c;也不支持消息持久化。 Redis如何實現延時…

因果語言模型、自回歸語言模型、僅解碼器語言模型都是同一類模型

因果語言模型、自回歸語言模型、僅解碼器語言模型都是同一類模型 flyfish 因果語言模型&#xff08;causal Language Models&#xff09; 自回歸語言模型&#xff08;autoregressive language models&#xff09; 僅解碼器語言模型&#xff08;decoder-only language models&am…

jvm架構原理剖析篇

簡單題&#xff08;5道&#xff09; 考查內容&#xff1a;JVM運行時數據區域 題干&#xff1a;Java虛擬機棧的主要作用是&#xff1f; A. 存儲對象實例 B. 存儲方法調用和局部變量 C. 存儲靜態字段 D. 存儲字節碼指令 正確答案&#xff1a;B 解析&#xff1a;虛擬機棧用于存儲方…

智鏈萬物:人工智能驅動的產業智能化革命

當生成式AI在藝術與創意領域掀起風暴&#xff0c;大型語言模型重塑信息交互方式時&#xff0c;一場更為基礎、影響更為深遠的變革&#xff0c;正在全球實體經濟的根基處悄然發生并加速推進——這就是產業智能化。它并非簡單的“機器換人”&#xff0c;而是人工智能&#xff08;…

python中上下文管理器 與 try finally有什么區別

目錄 主要區別代碼對比何時使用哪種方式 主要區別 語法簡潔性 上下文管理器使用 with 語句&#xff0c;語法更簡潔優雅try-finally 需要顯式編寫異常處理代碼&#xff0c;更冗長 代碼復用性 上下文管理器可以封裝為類或函數&#xff0c;便于在多處復用try-finally 通常需要在每…

人體屬性識別+跌倒檢測:兒童行為監測與安全升級

智慧幼兒園的AI智能檢測盒應用實踐 背景&#xff1a;傳統園區管理的三大痛點 傳統幼兒園管理長期面臨三大核心挑戰&#xff1a;一是安全監控依賴人工巡查&#xff0c;存在視覺盲區與響應延遲&#xff0c;如某連鎖幼兒園曾因人工巡查疏漏&#xff0c;導致3起兒童跌倒事故未能及…

【ESP32-IDF筆記】09-UART配置和使用

環境配置 Visual Studio Code &#xff1a;版本1.98.2 ESP32&#xff1a;ESP32-S3 ESP-IDF&#xff1a;V5.4 支持型號&#xff1a;ESP32、ESP32-C2、ESP32-C3、ESP32-C5、ESP32-C6、ESP32-C61、ESP32-H2、ESP32-P4、 ESP32-S2、ESP32-S3 簡介 通用異步接收器/發送器 (UART) …