# 健行科技大學 網頁全端養成班 上課筆記 ## 專題 #### 第一組 組長: 09田秉弘 組員: 23卓子坤 24鄭皓陽 13游玄安 12楊亞承 #### 第二組 組長: 袁達新 組員: 鄭郁珊 組員: 徐晟詠 組員: 李宜璋 #### 第三組 主題:3C購物網站 08:高宏溢-組長 04:王弘毅 #### 第四組 主題: 旅行社RWD動態網頁 組長: 29 楊明璋 組員: 29 楊明璋 #### 第五組 ##### 組長 20.鍾鴻見 ##### 組員名單: 25. 王楷仁 02. 陳正沛 20. 鍾鴻見 10. 林彥廷 11. 葉政豪 #### 第六組 組長:楊芸軒 #### 第七組 組長:林均 組員:呂旻玲 組員:方聖傑 組員:陳廷銘 組員:彭信淵 組員:李文伶 #### 第八組 主題: 露營用品專賣店網頁 組長: 21 蔡文瑞 組員: 21 蔡文瑞 #### 第九組 專題: 3C購物網站 22:汪世傑組長 ## 2024-09-05 #### 將後端以系統服務的方式執行 編寫: /etc/systemd/system/my-backend.service ```bash= [Unit] Description=my-backend [Service] WorkingDirectory=/var/www/my-backend ExecStart=/var/www/my-backend/my-backend Restart=always RestartSec=10 KillSignal=SIGINT SyslogIdentifier=my-backend [Install] WantedBy=multi-user.target ``` #### 讓系統認識你的服務 ```bash= $ systemctl daemon-reload ``` #### 讓服務生效 ```bash= $ systemctl enable my-backend ``` #### 啟動服務 ```bash= $ systemctl start my-backend ``` #### 停止服務 ```bash= $ systemctl stop my-backend ``` #### 重新啟動服務 ```bash= $ systemctl restart my-backend ``` #### 查詢Console.WriteLine()輸出的訊息 ```bash= $ journalctl -u my-backend ``` #### 查詢服務狀態 ```bash= $ systemctl status my-backend ``` #### GCP GCE免費的條件: https://cloud.google.com/free/docs/free-cloud-features#compute #### MacOS產生金鑰方式 ``` $ ssh-keygen -t rsa -f ~/.ssh/user -C user ``` #### ssh連線到雲端 1. 打開putty 2. Host name: {username}@{public IP} 3. 設定Private Key: Connection->SSH->Auth->Credintals->第一個框要選擇剛剛儲存的Private Key #### MacOS ssh連線 ``` $ chmod 600 ~/.ssh/{account} $ ssh -r -i ~/.ssh/{account} {account}@{ip} ``` #### SCP前端 ```bash= $ scp -i C:\Users\User\Documents\gcp.pem dist/* aaron@34.168.94.105:/var/www/html ``` > 下這行指令之前請記得先`chmod 777 /var/www/html` #### SCP後端 ```bash= $ scp -i C:\Users\User\Documents\gcp.pem bin\Release\net8.0\linux-x64\publish\* aaron@34.168.94.105:/var/www/my-backend ``` #### Database Dump ```sql= -- MySQL dump 10.13 Distrib 5.5.62, for Win64 (AMD64) -- -- Host: 192.168.77.128 Database: shop -- ------------------------------------------------------ -- Server version 8.0.39-0ubuntu0.24.04.2 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -- -- Table structure for table `account` -- DROP TABLE IF EXISTS `account`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `account` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(32) DEFAULT NULL, `phone` varchar(32) DEFAULT NULL, `create_date` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `account` -- LOCK TABLES `account` WRITE; /*!40000 ALTER TABLE `account` DISABLE KEYS */; INSERT INTO `account` VALUES (1,'aaron','0987654321','2024-09-04 01:56:53'),(2,'apple','0912345678','2024-09-04 00:00:00'); /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; -- Dump completed on 2024-09-04 14:58:35 ``` ## 2024-09-04 #### 安裝mySQL Ubuntu官方文件: https://ubuntu.com/server/docs/install-and-configure-a-mysql-server 1. 安裝mysql ``` $ sudo apt install mysql-server ``` > root密碼請設複雜一點,因為如果開放到網路會很容易被駭客入侵 2. 確認mysql狀態 ``` $ sudo service mysql status ``` 3. 檢查mySQL使用了那些port ``` $ sudo netstat -tulpn | grep LISTEN ``` > **備註:** > 這個指令需要先安裝: `sudo apt install net-tools` 4. 建立遠端連線帳號 ```bash= $ sudo mysql -u root -p ``` ```sql= mysql> CREATE USER 'aaron'@'%' IDENTIFIED BY '0000'; mysql> GRANT ALL PRIVILEGES ON *.* TO 'aaron'@'%' WITH GRANT OPTION; ``` 確認帳號是否有建立: ```sql= mysql> select user from mysql.user; ``` 5. 將mySQL綁定到public ip 編輯`/etc/mysql/mysql.conf.d/mysqld.cnf` 修改`bind-address`為你的public IP: ``` bind-address = 192.168.0.5 ``` 重新啟動mysql: ```sql= # systemctl restart mysql ``` 參考內容: ``` # # The MySQL database server configuration file. # # One can use all long options that the program supports. # Run program with --help to get a list of available options and with # --print-defaults to see which it would actually understand and use. # # For explanations see # http://dev.mysql.com/doc/mysql/en/server-system-variables.html # Here is entries for some specific programs # The following values assume you have at least 32M ram [mysqld] # # * Basic Settings # user = mysql # pid-file = /var/run/mysqld/mysqld.pid # socket = /var/run/mysqld/mysqld.sock # port = 3306 # datadir = /var/lib/mysql # If MySQL is running as a replication slave, this should be # changed. Ref https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_tmpdir # tmpdir = /tmp # # Instead of skip-networking the default is now to listen only on # localhost which is more compatible and is not less secure. bind-address = 192.168.77.128 mysqlx-bind-address = 127.0.0.1 # # * Fine Tuning # key_buffer_size = 16M # max_allowed_packet = 64M # thread_stack = 256K # thread_cache_size = -1 # This replaces the startup script and checks MyISAM tables if needed # the first time they are touched myisam-recover-options = BACKUP # max_connections = 151 # table_open_cache = 4000 # # * Logging and Replication # # Both location gets rotated by the cronjob. # # Log all queries # Be aware that this log type is a performance killer. # general_log_file = /var/log/mysql/query.log # general_log = 1 # # Error log - should be very few entries. # log_error = /var/log/mysql/error.log # # Here you can see queries with especially long duration # slow_query_log = 1 # slow_query_log_file = /var/log/mysql/mysql-slow.log # long_query_time = 2 # log-queries-not-using-indexes # # The following can be used as easy to replay backup logs or for replication. # note: if you are setting up a replication slave, see README.Debian about # other settings you may need to change. # server-id = 1 # log_bin = /var/log/mysql/mysql-bin.log # binlog_expire_logs_seconds = 2592000 max_binlog_size = 100M # binlog_do_db = include_database_name # binlog_ignore_db = include_database_name ``` > **補充:** > 免密碼進入mysql > a. 建立mysql目錄: `sudo mkdir -p /var/run/mysqld` > b. 將目錄所有權改為mysql: `sudo chown mysql:mysql /var/run/mysqld` > c. 以安全模式執行mysql: `sudo mysqld_safe --skip-grant-tables &` > d. 以root身分進入mysql: `mysql -u root` #### 安裝dbeaver 官網: https://dbeaver.io/ ![allowPublicKeyRetrival](https://hackmd.io/_uploads/SkTTSHBnR.png) #### 建立.NET API後端專案 ``` $ dotnet new webapi -minimal -n my-backend ``` #### 一個簡單的RESTFul 風格API ```csharp= app.MapGet("/v1/my-first-api", () => { // API要做的事情寫在這裡 return new { Code = 0, Message = "成功", Data = "這是給你的資料" }; }); ``` #### 本地端測試API ```bash= $ curl -s http://localhost:5000/v1/my-first-api | jq ``` #### .NET部署到Ubuntu 官方文件: https://learn.microsoft.com/en-us/dotnet/core/deploying/ 建置.NET ```bash= $ dotnet publish -c Release -r linux-x64 --self-contained -p:PublishSingleFile=true ``` 到server建立新的目錄: ```bash= $ cd /var/www $ mkdir my-backend $ chmod 777 my-backend ``` 透過scp複製剛剛建置好的.NET程式 ```bash= scp bin\Release\net8.0\linux-x64\publish\* aaron@192.168.77.128:/var/www/my-backend ``` #### 讓.NET後端綁定所有IP ###### Program.cs ```bash= ... app.Run("http://*:5000"); ``` > 在Program.cs最後一行 #### .NET連接資料庫 1. 安裝MySqlConnector ```csharp= $ dotnet add package MySqlConnector.DependencyInjection ``` 2. 將MySql加入DI Container ```csharp= builder.Services.AddMySqlDataSource("Server=192.168.77.128;User ID=aaron;Password=3939889;Database=shop"); ``` 3. 加上using MySqlConnector ```csharp= using MySqlConnector; ``` > 加在Program.cs第一行 4. 將MySqlConnection注入API參數 ``` app.MapGet("/v1/my-first-api", (MySqlConnection connection) => { // API要做的事情寫在這裡 return new { Code = 0, Message = "成功", Data = "這是給你的資料" }; }); ``` #### 後端最終版 ```csharp= using MySqlConnector; var builder = WebApplication.CreateBuilder(args); // 將MySql加入DI Container builder.Services.AddMySqlDataSource("Server=192.168.77.128;User ID=aaron;Password=3939889;Database=shop"); // Add services to the container. // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; app.MapGet("/weatherforecast", () => { var forecast = Enumerable.Range(1, 5).Select(index => new WeatherForecast ( DateOnly.FromDateTime(DateTime.Now.AddDays(index)), Random.Shared.Next(-20, 55), summaries[Random.Shared.Next(summaries.Length)] )) .ToArray(); return forecast; }) .WithName("GetWeatherForecast") .WithOpenApi(); app.MapGet("/v1/my-first-api", (MySqlConnection connection) => { // 連線資料庫 connection.Open(); // 準備SQL指令 using var command = new MySqlCommand("SELECT * FROM account;", connection); // 執行SQL指令 using var reader = command.ExecuteReader(); List<dynamic> allData = new List<dynamic>(); // 讀出每一筆資料 while (reader.Read()) { var value1 = reader.GetValue(0); var value2 = reader.GetValue(1); var value3 = reader.GetValue(2); var value4 = reader.GetValue(3); Console.WriteLine($"{value1}|{value2}|{value3}|{value4}"); // 將資料新增到List allData.Add(new { Id = value1, Name = value2, Phone = value3, CreateData = value4 }); } // API要做的事情寫在這裡 return new { Code = 0, Message = "成功", Data = allData }; }); app.Run("http://*:5000"); record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary) { public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); } ``` > **注意:** > 如果你發生Authentication plugin 'caching_sha2_password' cannot be loaded錯誤。 > 修改使用者密碼認證方式: > ```sql= > ALTER USER 'aaron'@'%' IDENTIFIED WITH mysql_native_password BY '3939889'; > ``` #### 前端串接API ##### 1. NET後端設設定跨域CORS ```csharp= var builder = WebApplication.CreateBuilder(args); // 跨域存取設定 builder.Services.AddCors(options => { options.AddPolicy("CorsPolicy", policy => { policy.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod(); }); }); ``` 第二段: ```csharp= var app = builder.Build(); // 使用CORS跨預設定 app.UseCors("CorsPolicy"); ``` ##### 2. Vue專案安裝axios套件 ```bash= $ yarn add axios ``` > axios官網: https://axios-http.com/docs/intro ##### 3. 在需要呼叫api的地方引入axios ```javascript= import axios from 'axios' import { ref, onMounted } from 'vue' ``` ##### 4. 在需要呼叫api的地方使用axios.get() ```javascript= const el = ref(); // 網頁載入時會觸發的方法 onMounted(() => { console.log("test"); // Make a request for a user with a given ID axios.get('http://localhost:5000/v1/my-first-api') .then(function (response) { // handle success // console.log(response); el.value = response.data.data; console.log(el.value); }) .catch(function (error) { // handle error console.log(error); }) .finally(function () { // always executed }); }); ``` ##### 5. 把收到的資料從response.data拿出來render到網頁上 ```javascript= el.value = response.data.data; ``` 範例: ```javascript= <div class="container"> <div class="table"> <div class="table-header"> <div class="header__item"><a id="name" class="filter__link" href="#">ID</a></div> <div class="header__item"><a id="wins" class="filter__link filter__link--number" href="#">Name</a></div> <div class="header__item"><a id="draws" class="filter__link filter__link--number" href="#">Phone</a></div> <div class="header__item"><a id="losses" class="filter__link filter__link--number" href="#">Create Date</a> </div> </div> <div class="table-content"> <div v-for="value in el" class="table-row"> <div class="table-data">{{ value.id }}</div> <div class="table-data">{{ value.name }}</div> <div class="table-data">{{ value.phone }}</div> <div class="table-data">{{ value.createData }}</div> </div> </div> </div> </div> ``` 樣式: ```css= @import url("https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700"); *, *:before, *:after { box-sizing: border-box; } body { padding: 24px; font-family: "Source Sans Pro", sans-serif; margin: 0; } h1, h2, h3, h4, h5, h6 { margin: 0; } .container { max-width: 1000px; margin-right: auto; margin-left: auto; display: flex; justify-content: center; align-items: center; min-height: 100vh; } .table { width: 100%; border: 1px solid #EEEEEE; } .table-header { display: flex; width: 100%; background: #000; padding: 18px 0; } .table-row { display: flex; width: 100%; padding: 18px 0; } .table-row:nth-of-type(odd) { background: #EEEEEE; } .table-data, .header__item { flex: 1 1 20%; text-align: center; } .header__item { text-transform: uppercase; } .filter__link { color: white; text-decoration: none; position: relative; display: inline-block; padding-left: 24px; padding-right: 24px; } .filter__link::after { content: ""; position: absolute; right: -18px; color: white; font-size: 12px; top: 50%; transform: translateY(-50%); } .filter__link.desc::after { content: "(desc)"; } .filter__link.asc::after { content: "(asc)"; } ``` ## 2024-09-02 #### 將身分提升為root系統管理者 ```bash= $ sudo su ``` #### 更新套件管理系統 ```bash= # apt-get update ``` #### 安裝nginx ```bash= # apt-get install nginx ``` #### 檢查Nginx的服務狀態 ```bash= # systemctl status nginx ``` #### 切換到根目錄 ```bash= # cd / ``` #### 切換到nginx的網頁目錄 ```bash= # cd /var/www/html ``` #### 建立新的目錄 ```bash= # mkdir assets ``` #### 回到上一層目錄 ```bash= # cd .. ``` #### 建立vue專案 1. yarn開發、預覽網頁 2. vite建立專案: https://vitejs.dev/guide/ ```bash= yarn create vite my-vue-app --template vue ``` 3. 進入剛建立的專案目錄: `cd my-vue-app` 4. 初始化專案: `yarn` 5. 啟動開發伺服器: `yarn dev` #### 佈署vue專案到nginx ##### 1. 建置vue專案 ```bash= $ yarn build ``` > **注意:** > 1. 必須在vue專案目錄下下指令 > 2. 建置完會產生dist目錄 ##### 2. 將dist目錄下的檔案scp到遠端 ```bash= $ scp -r dist aaron@192.168.77.128:~ ``` > **補充:** > 1. 該指令會連同dist目錄一起複 > 製過去 > 2. `-r` 代表連同子目錄一起複製過去 ##### 3. 將遠端的dist目錄下檔案和子目錄複製到`/var/www/html`下 使用root權限並`cd到`/var/www/html`目錄下: ```bash= $ sudo su # cd /var/www/html # cp -r /home/aaron/dist/* . ``` > **備註:** > 該指令會將dist目錄下的所有檔案和子目錄複製過去,但是dist目錄本身不會複製過去 ##### 4. 完成 到瀏覽器打開網頁就可以看到vue專案建置出來的網頁 ## 檔案系統權限介紹 #### 第一個字元代表這個檔案是『目錄、檔案或連結檔等等』: - d: 目錄。 - -: 檔案。 - l: 連結檔(link file); - b: 裝置檔裡面的可供儲存的周邊設備(可隨機存取裝置); - c: 裝置檔裡面的序列埠設備,例如鍵盤、滑鼠(一次性讀取裝置)。 接下來的字元中,以三個為一組,且均為『rwx』 的三個參數的組合。 - r: 代表可讀(read) - w: 代表可寫(write) - x: 代表可執行(execute)。 > 這三個權限的位置不會改變,如果沒有權限,則會出現減號。 第一組為『檔案擁有者可具備的權限』。 第二組為『加入此群組之帳號的權限』。 第三組為『非本人且沒有加入本群組之其他帳號的權限』。 #### `chgrp` :改變檔案所屬群組 ``` $ chgrp {新的群組名稱} {檔案名稱} ``` #### `chown` :改變檔案擁有者 ``` $ chown {新的擁有者名稱} {檔案名稱} ``` #### `chmod` :改變檔案的權限 ``` $ chmod 777 {檔案名稱} ``` 例如: ```bash= # chmod 777 html ``` #### `chomd -R`可以遞迴修改權限 ```bash= # chmod -R 777 * ``` ### vue-router SPA虛擬出網址的元件 #### 1. 安裝vue-router ```bash= $ yarn add vue-router@4 ``` > **參考:** > https://router.vuejs.org/installation #### 2. 修改App.vue ```html= <script setup> </script> <template> <RouterView /> </template> <style scoped> </style> ``` #### 3. 建立HomeView.vue ```html= <template> <div> <a href="https://vitejs.dev" target="_blank"> <img src="/vite.svg" class="logo" alt="Vite logo" /> </a> <a href="https://vuejs.org/" target="_blank"> <img src="./assets/vue.svg" class="logo vue" alt="Vue logo" /> </a> </div> <HelloWorld msg="我的Vue專案你好" /> <div>Hello</div> </template> <script setup> import HelloWorld from './components/HelloWorld.vue' </script> <style scoped> .logo { height: 6em; padding: 1.5em; will-change: filter; transition: filter 300ms; } .logo:hover { filter: drop-shadow(0 0 2em #646cffaa); } .logo.vue:hover { filter: drop-shadow(0 0 2em #42b883aa); } </style> ``` #### 4. 建立CardView.vue ```html= <template> <div class="body"> <div class="container"> <div class="wrapper"> <div class="banner-image"> </div> <h1> Toyota Supra</h1> <p>Lorem ipsum dolor sit amet, <br /> consectetur adipiscing elit.</p> </div> <div class="button-wrapper"> <button class="btn outline">DETAILS</button> <button class="btn fill">BUY NOW</button> </div> </div> </div> </template> <script setup> </script> <style scoped> @import url('https://fonts.googleapis.com/css2?family=Righteous&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Lato:wght@300&display=swap'); .body { /* solid background */ background: rgb(0, 212, 255); /* gradient background*/ background: linear-gradient(45deg, rgba(0, 212, 255, 1) 0%, rgba(11, 3, 45, 1) 100%); /* photo background */ background-image: url(https://images.unsplash.com/photo-1619204715997-1367fe5812f1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1889&q=80); background-size: cover; background-position: center; display: flex; align-items: center; justify-content: center; height: 100vh; } .container { backdrop-filter: blur(16px) saturate(180%); -webkit-backdrop-filter: blur(16px) saturate(180%); background-color: rgba(17, 25, 40, 0.25); border-radius: 12px; border: 1px solid rgba(255, 255, 255, 0.125); padding: 38px; filter: drop-shadow(0 30px 10px rgba(0, 0, 0, 0.125)); display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; } .wrapper { width: 100%; height: 100%; } .banner-image { background-image: url(https://images.unsplash.com/photo-1641326201918-3cafc641038e?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1887&q=80); background-position: center; background-size: cover; height: 300px; width: 100%; border-radius: 12px; border: 1px solid rgba(255, 255, 255, 0.255) } h1 { font-family: 'Righteous', sans-serif; color: rgba(255, 255, 255, 0.98); text-transform: uppercase; font-size: 2.4rem; } p { color: #fff; font-family: 'Lato', sans-serif; text-align: center; font-size: 0.8rem; line-height: 150%; letter-spacing: 2px; text-transform: uppercase; } .button-wrapper { margin-top: 18px; } .btn { border: none; padding: 12px 24px; border-radius: 24px; font-size: 12px; font-size: 0.8rem; letter-spacing: 2px; cursor: pointer; } .btn+.btn { margin-left: 10px; } .outline { background: transparent; color: rgba(0, 212, 255, 0.9); border: 1px solid rgba(0, 212, 255, 0.6); transition: all .3s ease; } .outline:hover { transform: scale(1.125); color: rgba(255, 255, 255, 0.9); border-color: rgba(255, 255, 255, 0.9); transition: all .3s ease; } .fill { background: rgba(0, 212, 255, 0.9); color: rgba(255, 255, 255, 0.95); filter: drop-shadow(0); font-weight: bold; transition: all .3s ease; } .fill:hover { transform: scale(1.125); border-color: rgba(255, 255, 255, 0.9); filter: drop-shadow(0 10px 5px rgba(0, 0, 0, 0.125)); transition: all .3s ease; } </style> ``` #### 5. 建立router規則 ```javascript= import { createWebHistory, createRouter } from 'vue-router' import HomeView from './pages/HomeView.vue' import CardView from './pages/CardView.vue' const routes = [ { path: '/', component: HomeView }, { path: '/card', component: CardView }, ] const router = createRouter({ history: createWebHistory(), routes, }); // 將router export出去 export default { router } ``` > **參考:** > https://router.vuejs.org/guide/ #### 6. 將router設定給vue main.js ```javascript= import { createApp } from 'vue' import './style.css' import App from './App.vue' import router from './router' createApp(App).use(router.router).mount('#app') ``` #### 7. 調整nginx ```bash= # cd /etc/nginx/sites-available # vim default ``` 找到`location {`這行,然後將裡面的設定替換成: ```bash= try_files $uri $uri/ /index.html; ``` > **參考:** > https://router.vuejs.org/guide/essentials/history-mode.html#nginx #### 8. 重新啟動nginx ```bash= # systemctl restart nginx ``` #### deploy.bat ```bash= yarn build & scp -r dist/* aaron@192.168.77.128:/var/www/html ``` ## 2024-08-30 1. Install OpenSSH Server用來遠端連線用,安裝時必須打勾 #### 檔案與目錄管理指令 - ls: 列出檔案 > -a :全部的檔案,連同隱藏檔( 開頭為 . 的檔案) 一起列出來(常用) > -A :全部的檔案,連同隱藏檔,但不包括 . 與 .. 這兩個目錄 > -d :僅列出目錄本身,而不是列出目錄內的檔案資料(常用) > -f :直接列出結果,而不進行排序 (ls 預設會以檔名排序!) > -F :根據檔案、目錄等資訊,給予附加資料結構,例如: > *:代表可執行檔; /:代表目錄; =:代表 socket 檔案; |:代表 FIFO 檔案; > -h :將檔案容量以人類較易讀的方式(例如 GB, KB 等等)列出來; > -l :長資料串列出,包含檔案的屬性與權限等等資料;(常用) >-r :將排序結果反向輸出,例如:原本檔名由小到大,反向則為由大到小; > -R :連同子目錄內容一起列出來,等於該目錄下的所有檔案都會顯示出來; > -S :以檔案容量大小排序,而不是用檔名排序; > -t :依時間排序,而不是用檔名。 > --color=never:不要依據檔案特性給予顏色顯示; > --color=always:顯示顏色 > --color=auto:讓系統自行依據設定來判斷是否給予顏色 > --full-time:以完整時間模式 (包含年、月、日、時、分) 輸出 > --time={atime,ctime} :輸出 access 時間或改變權限屬性時間 (ctime) 而非內容變更時間 (modification time) - touch: 建立檔案 例如: ```bash= $ touch test.txt ``` 會建立`test.txt`檔案 - vim: 打開檔案並編輯 例如: ```bash= $ vim test.txt ``` 打開`test.txt`檔案 > vim打開檔案預設會在命令模式(command mode) > `i`或`o`進入插入模式(insert mode) > `ESC`離開編輯模式回到命令模式(command mode) > `:`進入底線命令模式(last line mode) > 在底線命令模式輸入`wq`+`Enter`儲存並離開vim - cat: 檢視檔案內容 例如: ```bash= $ cat test.txt ``` 會顯示`test.txt`檔案內容 - exit: 登出或離開 - ip: 查看電腦的IP 例如: ```bash= $ ip a ``` - 遠端登入Linux Server 1. 打開命令提示字元 2. 輸入: `ssh {帳號}:{server ip}` 例如: ``` $ ssh aaron@113.12.9.1 ``` 3. 第一次登入會詢問是否要紀錄憑證,輸入: yes 4. 輸入你的密碼 5. 完成 - `>`重新導向(覆蓋原始內容) 例如: ```bash= $ cat > aaron.txt ``` 可以在畫面上輸入文字,最後會存到aaron.txt檔案,如果檔案存在,會覆蓋 - `>>`重新導向(在原始內容最後面新增) 例如: ```bash= $ cat >> aaron.txt ``` 可以在畫面上輸入文字,最後會存到aaron.txt檔案,如果檔案存在,會從最後面新增 - `tr`刪除內容 例如: ``` $ cat > a.txt aaron test1 aaron test2 aaron test3 aaron test4 aaron test5 ``` 新增一個a.txt檔案 ```bash= $ cat a.txt | tr -d "aaron " > b.txt ``` 將a.txt內容透過管線給tr將`aaron `文字刪除後再存到b.txt - `cp`檔案複製 例如: ```bash= $ cp a.txt b.txt ``` 將檔案a.txt複製為b.txt - `scp`遠端複製 例如: ```bash= $ scp a.txt aaron@172.19.115.40:~ ``` 將檔案a.txt複製到遠端的Home目錄下 ```bash= $ scp aaron@172.19.115.40:~/aaron.txt aaron.txt ``` 將遠端Home目錄檔案a.txt複製到本地端的目前路徑下 > Windows下可以安裝WinSCP圖形化工具來作為遠端檔案交換的工具 > https://winscp.net/eng/download.php