CRUD x Vue.js x PHP x MYSQL PDO

閱讀時間約 1 分鐘
S1.建立資料庫 user
 -
-- 資料表結構 `users`
--
CREATE TABLE `users` (
  `name` varchar(20) NOT NULL,
  `email` text NOT NULL,
  `password` text NOT NULL,
  `id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
S2.建立 index.htm
a.載入 vue.js、jquery、bootstrap
b.版面建立
S3.vue.js程式
新增、查看列表、互動視窗、修改、刪除
S4.PHP程式 x CRUD
增刪查改(CRUD)
Create - 建立
Read -讀取、查詢
Update - 更新
Delete - 刪除
vue.js 生命週期
index.htm
<!-- 
20201031 by JokerWu
20220527 新修-步驟拆解 & 加註版
_1=建立資料
_2=建立列表
_3=互動視窗
_4=完整
-->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Vue.js PHP MYSQL</title>
</head>
<!-- 
程式中 變數、函式命名有
駝峰式命名法
每一個單字的首字母都採用大寫字母
例如:FirstName、LastName、CamelCase
也被稱為Pascal命名法
-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="http://code.jquery.com/jquery-3.6.0.min.js"></script>
<!--
jquery 可以改成 axios套件來處理AJAX
Axios是很輕量的套件,只有約13kb
jQuery比較笨重 主要是用來處理AJAX
所以axios 在vue.js 來說是較好的選擇
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
 -->
 
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
<style>
	table, th, td {
		border: 1px solid black;
		border-collapse: collapse;
	}
	th, td {
		padding: 25px;
	}
</style>
<body>
<!-- 版面 -->
<div id="myApp"> <!-- 此處的 id 跟 vue.js //el: 互動 -->
	<div class="container"><!--  .container 是BS5的預設類別, 是一個RWD 固定寬度的內容容器 -->
		<h1 class="text-center">建立資料</h1>
		<div class="row">
			<div class="col-md-6">
				<form method="POST" action="create.php" v-on:submit.prevent="doCreate">
				<!-- 
				v-on:submit.prevent
				submit ->表單送出
				.prevent->不換頁刷新頁面
				doCreate->vue.js 自訂義函式 用來將表單資料 以JSON格式 送出至create.php
				
				v-on:submit.prevent可簡寫為
				@:submit.prevent
				-->
					<div class="form-group">
						<label>姓名</label>
						<input type="text" name="name" class="form-control" />
					</div>
					<div class="form-group">
						<label>Email</label>
						<input type="email" name="email" class="form-control" />
					</div>
					<div class="form-group">
						<label>密碼</label>
						<input type="password" name="password" class="form-control" />
					</div>
					<input type="submit" value="建立" class="btn btn-primary" />
				</form>
			</div>
		</div>
<!-- 版面 列表頁 -->
		<h1 class="text-center">列表</h1>
		<table class="table">
			<tr>
				<th>排序ID</th>
				<th>姓名</th>
				<th>Email</th>
				<th>管理</th>
			</tr>
<!-- 
以下為使用 vue.js for迴圈
參考範例 v04.html & v05.html
只要把 v-for 放在一個 <li> 上就有 for 的效果 
item 是參數(你也可為它取別的名字)用來表示陣列元素
list 指的是自定義的陣列名稱(陣列元素為數個物件)
in 也可以寫成 of,因為這樣更接近原生 JavaScript 疊代器的語法
v-for 還支援第二個參數 — — 索引值(index)
帶入索引值參數的方法是在原本 item 的位置改寫成 (item, index) 即可
此處 v-for 放在一個<tr>內使用 
陣列元素 以 user 命名 ->代表 資料表內的欄位名稱
索引值 以 index 命名 ->表示第幾筆資料
而 users 為 從 vue.js 收到JSON資料 解出後 的資料集名稱
-->
			<tr v-for="(user, index) in users"> 
				<td v-text="user.id"></td>
				<td v-text="user.name"></td>
				<td v-text="user.email"></td>
				<td>
					<button type="button" v-bind:data-id="user.id" v-on:click="showEditUserModal" class="btn btn-primary">編輯</button>
<!-- 
v-bind
v03.html範例
雙花括號 填資料的方法,不適用 HTML 屬性 因此應該把 v-bind: 加在 HTML 屬性前面,且在屬性對應的值中放置參數,在 Model 中定義要傳入的值。v-bind 的縮寫是去掉 v-bind、只留下一個冒號 : 
v-bind 是將狀態綁定到 HTML 元素上 
因此
v-bind:data-id="user.id"
此處可改為
:data-id="user.id"
v-bind:data-id 此處的data-id 是為了帶值到彈出視窗(互動視窗 或叫 Modal)內的 user.id 欄位
.getAttribute(''):取得屬性->DOM語法
選取元素時用元素的屬性去選 e.target.getAttribute('data-value')
btn-primary ->BS5 預設按鈕樣式
v-on:click 可參照 v06.html & v06_01.html
v-on: 事件 = "方法名稱()" 
v-on: 的縮寫是 @
-->
					<form method="POST" action="delete.php" v-on:submit.prevent="doDelete" style="display: contents;">
<!--
display: contents
此處使用暴力法 直接用 Style 處理
display->改變元素對外所參與的佈局環境 或 對內佈局環境,提供後面元素佈局的規則
也就是 這個form層 不套用CSS格式 但子層套用
詳細範例可參照 1.htm
-->
						<input type="hidden" name="id" v-bind:value="user.id" />
						<input type="submit" name="submit" class="btn btn-danger" value="刪除" />
					</form>
				</td>
			</tr>
<!-- vue.js for迴圈 End -->
		</table>
	</div>
<!-- 列表 END -->
	<!-- Modal 互動視窗-->
	<div class="modal fade" id="editUserModal">
		<div class="modal-dialog" role="document">
<!-- 
Bootstrap 一次只支援一個互動視窗。
role屬性的目的是識別解析軟件元素及其子元素
modal用法
modal.show() //顯示 modal
modal.hide() //隱藏 modal
modal.destroy() //移除 Modal 產生的 dom 元素與 event listeners
以下為 BS5 modal 結構
「data-backdrop="static"」 鎖定背景,點擊背景時不自動關閉視窗
「fade」 淡入、淡出的轉場效果
「modal-lg」視窗大小,如modal-lg、modal-md、modal-sm
「data-dismiss="modal"」 關閉視窗
「data-keyboard="true"」 是否用ESC鍵關閉,預設為true
-------
<div id="OOXX" class="modal fade"  tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static" data-keyboard="true">
  <div class="modal-dialog modal-lg" >
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal">
          <span>&times;</span>
-------
aria-label = alt (讀螢幕的軟體可以用 無障礙空間 就像 html 的 role屬性 
<a href="#" title="設置"><img src="gear.png"></a> => title="設置" 不會唸出
<a href="#" aria-label="設置"><img src="gear.png"></a> => aria-label="設置" 可唸出
詳細 可參照 WAI-ARIA W3C編撰的規格
&times; => X 符號
-->
			<div class="modal-content">
				<div class="modal-header">
					<h5 class="modal-title">修改資料</h5>
					<button type="button" class="close" data-dismiss="modal" aria-label="Close">
						<span aria-hidden="true">&times;</span>
					</button>
				</div>
				
				<div class="modal-body">
					<form method="POST" action="update.php" v-on:submit.prevent="doUpdate" id="form-edit-user" v-if="user != null">
<!--
v-if 請參照 v10.htm
-->
						<input type="hidden" name="id" v-bind:value="user.id" />
						<div class="form-group">
							<label>姓名</label>
							<input type="text" name="name" v-bind:value="user.name" class="form-control" />
						</div>
<!-- 
class="form-control" =>BS5 form表單控制 
可以使用 .form-control-lg 和 .form-control-sm 設置高度
不然就不要填 用預設
-->
						<div class="form-group">
							<label>Email</label>
							<input type="email" name="email" v-bind:value="user.email" class="form-control" />
						</div>
					</form>
				</div>
				<div class="modal-footer">
					<button type="button" class="btn btn-secondary" data-dismiss="modal">關閉</button>
					<button type="submit" name="submit" class="btn btn-primary" form="form-edit-user">確定修改</button>
				</div>
			</div>
		</div>
			<!-- Modal 互動視窗 END -->	
			
			
<!-- 下方是 頭myApp 跟 內容container 的 div-->
	</div>
</div>
<!-- 
直譯式程式
即時互動 如 BS.js 、 jQuery、Vue.js 
一般都放後面
-->
<script src="VueControl.js"></script> 
VueControl.js
	const myApp = new Vue({
		el: "#myApp", //el: HTML '元素 id'
		data: { //資料結構 版面要用的那些資料 從這來的
			users: [],//JSON讀取來的資料 或 view版面過來的 初始宣告 為空的 users
			user: null //初始宣告變數 user 主要是給互動視窗用
		},
		methods: {
//建立資料函式
			doCreate: function () {
				const self = this; //this 關鍵字使用 此處使用 this可方便使用且資料比較不會錯亂
				const form = event.target; //事件DOM元件 此處使用 可控制表單那些欄位
				const ajax = new XMLHttpRequest(); //AJAX 通訊初始
				ajax.open("POST", form.getAttribute("action"), true); 
				//使用AJAX 將 form 表單 的元素 action 建立
				//意思就是 以AJAX即時不刷新 POST的通訊方式 
				//將form表單資料傳輸至 action="create.php"
				ajax.onreadystatechange = function () {
					/*
					ajax.onreadystatechange
					當資料有變化時
					觸發事件AJAX
					XMLHttpRequest.readyState
					客戶端物件目前的狀態
					0	UNSENT	客戶端已被建立,但 open() 方法尚未被呼叫。
					1	OPENED	open() 方法已被呼叫。
					2	HEADERS_RECEIVED	send() 方法已被呼叫,而且可取得 header 與狀態。
					3	LOADING	回應資料下載中,此時 responseText 會擁有部分資料。
					4	DONE	完成下載操作。
					
					xmlhttp.status的值及解釋:可查表 較常遇到
					200——成功
					202——接受和處理、但處理未完成
					400——錯誤請求,如語法錯誤 
					401——請求授權失敗	
					404——沒有發現檔案、查詢或URl 
					*/
					if (this.readyState == 4) {
						if (this.status == 200) {
							// console.log(this.responseText);
							const user = JSON.parse(this.responseText);
							//JSON.parse() 方法把會把一個JSON字串轉換成JavaScript的數值或是物件。
							
							//資料處理
							self.users.unshift(user);
							/*
							陣列資料 原型:Array.prototype.unshift()
							將資料加到第一個 
							例如:
							array.unshift('老媽');
							console.log(array); // ["老媽", "小明", "杰倫", "漂亮阿姨", "小美"]
							與 push() 雷同
							*/
						}
					}
				};
				//建立form表單資料傳輸 使用 AJAX 即時刷新
				const formData = new FormData(form);
				ajax.send(formData);
			},
//-------建立資料函式 END
		
//取得所有資料 建立列表頁
			getData: function () {
				const self = this;
				const ajax = new XMLHttpRequest();
				ajax.open("POST", "read.php", true);
				ajax.onreadystatechange = function () {
					if (this.readyState == 4) {
						if (this.status == 200) {
							// console.log(this.responseText);
							const users = JSON.parse(this.responseText);
							self.users = users; //將取得的資料 帶進users 給vue.js data用
						}
					}
				};
				const formData = new FormData();
				ajax.send(formData);
			},
		//-------
//建立 互動視窗函式
			showEditUserModal: function () {
				const id = event.target.getAttribute("data-id");
				//使用AJAX 將 列表頁的 v-bind:data-id="user.id"
				//傳送接收過來
				
				//比對 users 陣列內 有沒有 傳送過來的 user.id 值
				//有的話 給互動視窗用的變數 user 改成這一個 
				for (var a = 0; a < this.users.length; a++) {
					if (this.users[a].id == id) {
						this.user = this.users[a];
						break;
					}
				}
				$("#editUserModal").modal("show"); //將互動視窗顯示
				/*
				modal用法
				modal.show() //顯示 modal
				modal.hide() //隱藏 modal
				modal.destroy() //移除 Modal 產生的 dom 元素與 event listeners
				*/
			},
//-------建立 互動視窗函式 END
//更新函式
			doUpdate: function () {
				const self = this;
				const form = event.target;
				const ajax = new XMLHttpRequest();
				ajax.open("POST", form.getAttribute("action"), true);
				//此處AJAX 取得來自互動視窗的 form表單
				//action="update.php" 從這一頁 產生的 JSON 資料
				
				//---資料改變 START --
				ajax.onreadystatechange = function () {
					if (this.readyState == 4) {
						if (this.status == 200) {
							// console.log(this.responseText);
							const user = JSON.parse(this.responseText);
							// console.log(user);
							//接下來要進行 原本資料排序的資料處理
							//因為資料更改後 原users陣列資料會與更新的不同
							//因此先找出來該筆資料 原理與line bot 範例同
							var index = -1; //為避免麻煩 直接使用本程式不可能出現的數字 如7秒魚範例手法
							for (var a = 0; a < self.users.length; a++) {
								if (self.users[a].id == user.id) {
									index = a;
									break;
								}
							}
							// 建立暫存陣列 準備進行陣列重整
							//宣告的暫存資料 等於 JSON來的 更新過陣列資料
							const tempUsers = self.users;
							//將取得有變化的陣列索引 改變成 互動視窗用的 user 變數
							tempUsers[index] = user;
							// update the local array by removing all old elements and inserting the updated users
							//清掉 users 成為空陣列 
							//在將 users 變成 暫存的陣列 也就是新的資料
							self.users = [];
							self.users = tempUsers;
						}
					}
				};
				//---資料改變 END --
				//表單資料 用AJAX 不跳轉頁面傳送
				const formData = new FormData(form);
				ajax.send(formData);
				//隱藏互動視窗
				$("#editUserModal").modal("hide");
			},
//更新函式 END
//刪除函式
			doDelete: function () {
				const self = this;
				const form = event.target;
				const ajax = new XMLHttpRequest();
				ajax.open("POST", form.getAttribute("action"), true);
				ajax.onreadystatechange = function () {
					if (this.readyState == 4) {
						if (this.status == 200) {
							// console.log(this.responseText);
							//移除 users 陣列的資料
							for (var a = 0; a < self.users.length; a++) {
								if (self.users[a].id == form.id.value) {
									self.users.splice(a, 1);
									/*
									使用arr.splice(要插入或刪除的索引位置, 要刪除的元素數量, 要插入的元素內容)
									此處我們使用 a = 位置 索引值 
									然後再用第二個參數 刪除的元素數量=1
									一次只刪一個
									*/
									break;
								}
							}
						}
					}
				};
				const formData = new FormData(form);
				ajax.send(formData);
			},
//刪除函式 END
		//-----
		},//方法結束
		//使用AJAX 進行監聽讀取資料 詳細請參照 vue.js 生命週期(lifecycle)圖 mounted
		mounted: function () {
			this.getData();
		}
	});
給有需要的朋友~
謝謝~宅見~
為什麼會看到廣告
avatar-img
40會員
130內容數
獨立遊戲開發紀錄
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
吳佳鑫的沙龍 的其他內容
「我的內衣呢!」我側過頭盯著子璇。 「啊!妳發現了呀!做檢查時,我幫妳脫的,放心,沒人看見。」子璇戲謔道。 「妳...」 「總算是回來了。」進房後,我走到床邊拿起一天未見的手機。 「蕾雅,和我們一起住嗎?」子璇在門邊問著。 砰~ 蕾雅狠狠的將門關上。 “順利?” “女鵝 發生什麼事?”
子璇離開床後,往門的方向走去,原本應該會自動感應亮起的燈光,此時竟無任何燈光發出,連原本床下的鵝黃色燈光也熄滅。靠著月光,我也摸下床並與子璇保持約五步的距離。此時,我聽到了那詭異的聲音,是從子璇手上發出。 “烏馬庫卡。嚕啊咪西。薩哩哎...” 「哇~」子璇在我身上醒了過來,並發出一聲慘叫。
「真是太幸福了。」我滿足的靠在椅背上說著。子璇則微醺的看著我。 「很高興今晚的餐點妳能滿意。」子璇的母親說著。 「鐘同學,很高興與妳一起用餐,等我回國後再聚。」說完,陳老大站了起來,侍女隨即將椅子往後微微移開。見此,我也連忙起身。 「是因為太早去機場無聊吧!」 「妳這孩子怎這樣說話。」 「是呀。」
「女兒~」 正當子璇剛開始要跟我介紹她家的發跡史時,忽然一道爽朗的聲音。 「老爺、夫人好。」眾侍女這時一致的將雙手放於腹前合攏,右手壓在左手上,頭與上身一同前曲並以約30度角行禮鞠躬齊聲說道。 「這應該是妳同學了,鐘同學好。」兩人在侍女的服務下落座後,其母首先開口說道。 「好的。」
來到校門後,已經可見小葉站在車旁等著我們到來。子璇走到車邊時,小葉隨即打開後座的車門,讓我倆上車。待我上車後,看到坐於前方副駕駛座上的人,心想這應該就是達哥。因其坐於我前方位置,從這角度難以看到其面孔。正當我還在挪動背包位置時,小葉上了車,車子也緩緩開動朝目的地出發。 「你好。」我隨著話尾回應著。
叮鈴鈴~清晨,睡意正濃的我還沉浸在甜甜的美夢中。突然的鈴響,我伸手四處找著聲音的來源。睜開慵懶的眼睛,撓了撓一頭亂髮,伸個懶腰,打個呵欠,滑過手機停止鬧鈴的滑桿按鈕,看著手機螢幕的時間,連忙一骨碌從床上滾下床。 「李姐早,剛下班呀!」 「走,去餐廳,我們老樣子去吃雞絲飯。」 「沒有。」 「這…」
「我的內衣呢!」我側過頭盯著子璇。 「啊!妳發現了呀!做檢查時,我幫妳脫的,放心,沒人看見。」子璇戲謔道。 「妳...」 「總算是回來了。」進房後,我走到床邊拿起一天未見的手機。 「蕾雅,和我們一起住嗎?」子璇在門邊問著。 砰~ 蕾雅狠狠的將門關上。 “順利?” “女鵝 發生什麼事?”
子璇離開床後,往門的方向走去,原本應該會自動感應亮起的燈光,此時竟無任何燈光發出,連原本床下的鵝黃色燈光也熄滅。靠著月光,我也摸下床並與子璇保持約五步的距離。此時,我聽到了那詭異的聲音,是從子璇手上發出。 “烏馬庫卡。嚕啊咪西。薩哩哎...” 「哇~」子璇在我身上醒了過來,並發出一聲慘叫。
「真是太幸福了。」我滿足的靠在椅背上說著。子璇則微醺的看著我。 「很高興今晚的餐點妳能滿意。」子璇的母親說著。 「鐘同學,很高興與妳一起用餐,等我回國後再聚。」說完,陳老大站了起來,侍女隨即將椅子往後微微移開。見此,我也連忙起身。 「是因為太早去機場無聊吧!」 「妳這孩子怎這樣說話。」 「是呀。」
「女兒~」 正當子璇剛開始要跟我介紹她家的發跡史時,忽然一道爽朗的聲音。 「老爺、夫人好。」眾侍女這時一致的將雙手放於腹前合攏,右手壓在左手上,頭與上身一同前曲並以約30度角行禮鞠躬齊聲說道。 「這應該是妳同學了,鐘同學好。」兩人在侍女的服務下落座後,其母首先開口說道。 「好的。」
來到校門後,已經可見小葉站在車旁等著我們到來。子璇走到車邊時,小葉隨即打開後座的車門,讓我倆上車。待我上車後,看到坐於前方副駕駛座上的人,心想這應該就是達哥。因其坐於我前方位置,從這角度難以看到其面孔。正當我還在挪動背包位置時,小葉上了車,車子也緩緩開動朝目的地出發。 「你好。」我隨著話尾回應著。
叮鈴鈴~清晨,睡意正濃的我還沉浸在甜甜的美夢中。突然的鈴響,我伸手四處找著聲音的來源。睜開慵懶的眼睛,撓了撓一頭亂髮,伸個懶腰,打個呵欠,滑過手機停止鬧鈴的滑桿按鈕,看著手機螢幕的時間,連忙一骨碌從床上滾下床。 「李姐早,剛下班呀!」 「走,去餐廳,我們老樣子去吃雞絲飯。」 「沒有。」 「這…」
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
藉由曾經閱讀過某影評介紹的「消除氣」以及對星際的想像寫下的唯美詩文
Thumbnail
水稻稻瘟病菌,是引起稻熱病的兇手。稻熱病在85個國家(包括台灣)都有發生,造成嚴重的經濟損失。 更可怕的是,在1985年,水稻稻瘟病菌把魔爪伸向小麥!後來科學家們發現小麥有個叫做Rmg8的基因,可以抵抗此病。 但是,這個基因到底怎麼出現在小麥中,又怎麼取得抗稻瘟病的技能的?
Thumbnail
半夜開起了炸雞炒飯餐車 延續了媽媽在我記憶裡的味道~
Thumbnail
對我而言,我就是一個「活動派」的代表人物。 這個「活動」指的是「要活就要動」,所以我每天手動寫作、彈鋼琴、彈吉他,腦動構思文章內容,腳動每天去走路,大概我身上能動的地方我都運動到了,這其中當然也包括閱讀文章和看一些知識性或趣味性的影片。 以前還在教書的時候,假日很喜歡往台北跑,從信義商圈、地下街
Thumbnail
陣列可以說是最常見的資料結構,LeetCode 裡的題目有過半都和 Array 有關,因此也通常是解題新手的第一站。在第一篇專文,我們就從它的操作方法講起。
Thumbnail
近日,谷阿莫式「X分鐘看完OO電影」的YouTube頻道在日本備受矚目。這類型的影片在日本稱之為「ファスト映画」、「ファストシネマ」或「あらすじ動画」,臺灣媒體直譯為「速食電影」或「快速電影」。
Thumbnail
Golf是一個玩不膩的運動。因為它對於不同時期的你有不同的挑戰和變化。而對我來說,X就是人本身,也是最重要的一個變數。再來就是球桿,代表Y。最後是球,就是X。這三個變數就變成最後高爾夫。當然,你是最大變數,也是最大挑戰。就如同我說的,人是一直在改變,所以也會影響到Y和Z。恭喜你來到最複雜的運動之一!
Thumbnail
大家好,我是威廉氏後人-李毅評醫師 透過門診及私訊的發問,我發現不少孕婦對於自費的脊髓肌肉萎縮症(SMA)和X染色體脆折症(Fragile-X)有許多疑問,今天就讓我用Q&A的方式,先提供大家X染色體脆折症常見的問題,以及相對應解答,為你們解開心中的疑惑吧!
Thumbnail
《獅子山上》是一部香港真人真事改編的電影,主要改編2016年香港攀石運動員黎志偉,因車禍雙腳癱瘓必須放棄大好的攀岩運動員人生在度過5年的低潮期時決定做出改變,要坐著輪椅攀上獅子山頂的人生故事。這項紀錄也被拍成紀錄片《結 · Crux》,事隔4年被再度改編成電影故事搬上大螢幕,但效果卻不如預期。
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
藉由曾經閱讀過某影評介紹的「消除氣」以及對星際的想像寫下的唯美詩文
Thumbnail
水稻稻瘟病菌,是引起稻熱病的兇手。稻熱病在85個國家(包括台灣)都有發生,造成嚴重的經濟損失。 更可怕的是,在1985年,水稻稻瘟病菌把魔爪伸向小麥!後來科學家們發現小麥有個叫做Rmg8的基因,可以抵抗此病。 但是,這個基因到底怎麼出現在小麥中,又怎麼取得抗稻瘟病的技能的?
Thumbnail
半夜開起了炸雞炒飯餐車 延續了媽媽在我記憶裡的味道~
Thumbnail
對我而言,我就是一個「活動派」的代表人物。 這個「活動」指的是「要活就要動」,所以我每天手動寫作、彈鋼琴、彈吉他,腦動構思文章內容,腳動每天去走路,大概我身上能動的地方我都運動到了,這其中當然也包括閱讀文章和看一些知識性或趣味性的影片。 以前還在教書的時候,假日很喜歡往台北跑,從信義商圈、地下街
Thumbnail
陣列可以說是最常見的資料結構,LeetCode 裡的題目有過半都和 Array 有關,因此也通常是解題新手的第一站。在第一篇專文,我們就從它的操作方法講起。
Thumbnail
近日,谷阿莫式「X分鐘看完OO電影」的YouTube頻道在日本備受矚目。這類型的影片在日本稱之為「ファスト映画」、「ファストシネマ」或「あらすじ動画」,臺灣媒體直譯為「速食電影」或「快速電影」。
Thumbnail
Golf是一個玩不膩的運動。因為它對於不同時期的你有不同的挑戰和變化。而對我來說,X就是人本身,也是最重要的一個變數。再來就是球桿,代表Y。最後是球,就是X。這三個變數就變成最後高爾夫。當然,你是最大變數,也是最大挑戰。就如同我說的,人是一直在改變,所以也會影響到Y和Z。恭喜你來到最複雜的運動之一!
Thumbnail
大家好,我是威廉氏後人-李毅評醫師 透過門診及私訊的發問,我發現不少孕婦對於自費的脊髓肌肉萎縮症(SMA)和X染色體脆折症(Fragile-X)有許多疑問,今天就讓我用Q&A的方式,先提供大家X染色體脆折症常見的問題,以及相對應解答,為你們解開心中的疑惑吧!
Thumbnail
《獅子山上》是一部香港真人真事改編的電影,主要改編2016年香港攀石運動員黎志偉,因車禍雙腳癱瘓必須放棄大好的攀岩運動員人生在度過5年的低潮期時決定做出改變,要坐著輪椅攀上獅子山頂的人生故事。這項紀錄也被拍成紀錄片《結 · Crux》,事隔4年被再度改編成電影故事搬上大螢幕,但效果卻不如預期。