CRUD x Vue.js x PHP x MYSQL PDO

更新 發佈閱讀 30 分鐘

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 - 刪除

raw-image


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();
}
});

原碼:https://reurl.cc/e3k8yL

給有需要的朋友~

謝謝~宅見~

留言
avatar-img
MJ的沙龍
43會員
136內容數
獨立遊戲開發紀錄
MJ的沙龍的其他內容
2025/04/12
🗓 Steam 上市日期:2025/4/28 | 🖤 加入願望清單:https://store.steampowered.com/app/3634400/Elara/ 「他們說我太敏感,說我不合群。 但我只是——不想學會沉默。」 —Elara Quinn 你是否曾經在工作時,感
Thumbnail
2025/04/12
🗓 Steam 上市日期:2025/4/28 | 🖤 加入願望清單:https://store.steampowered.com/app/3634400/Elara/ 「他們說我太敏感,說我不合群。 但我只是——不想學會沉默。」 —Elara Quinn 你是否曾經在工作時,感
Thumbnail
2025/03/05
在靈異頻發的醫院夜班,小護士林筱筱意外發現她的冷酷上司——蘇醫生,竟然早已死亡五年,從此她與這位神秘的「鬼醫生」攜手處理靈異事件,並在驚魂不斷的夜班中逐漸建立起一段超越生死的羈絆。
Thumbnail
2025/03/05
在靈異頻發的醫院夜班,小護士林筱筱意外發現她的冷酷上司——蘇醫生,竟然早已死亡五年,從此她與這位神秘的「鬼醫生」攜手處理靈異事件,並在驚魂不斷的夜班中逐漸建立起一段超越生死的羈絆。
Thumbnail
2025/02/24
這是一篇懸疑驚悚小說,描述女主角江語珊調查一起離奇命案的故事。死者林曦是一位心理學教授,死於自家公寓,現場佈滿鏡子,死者嘴角帶著詭異的微笑。語珊在調查過程中發現,此案與一種名為「鏡像侵蝕」的心理現象有關,並逐漸被捲入其中。
Thumbnail
2025/02/24
這是一篇懸疑驚悚小說,描述女主角江語珊調查一起離奇命案的故事。死者林曦是一位心理學教授,死於自家公寓,現場佈滿鏡子,死者嘴角帶著詭異的微笑。語珊在調查過程中發現,此案與一種名為「鏡像侵蝕」的心理現象有關,並逐漸被捲入其中。
Thumbnail
看更多
你可能也想看
Thumbnail
在 vocus 與你一起探索內容、發掘靈感的路上,我們又將啟動新的冒險——vocus App 正式推出! 現在起,你可以在 iOS App Store 下載全新上架的 vocus App。 無論是在通勤路上、日常空檔,或一天結束後的放鬆時刻,都能自在沈浸在內容宇宙中。
Thumbnail
在 vocus 與你一起探索內容、發掘靈感的路上,我們又將啟動新的冒險——vocus App 正式推出! 現在起,你可以在 iOS App Store 下載全新上架的 vocus App。 無論是在通勤路上、日常空檔,或一天結束後的放鬆時刻,都能自在沈浸在內容宇宙中。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
Vue3 學習筆記,專案建立與基礎響應式篇
Thumbnail
Vue3 學習筆記,專案建立與基礎響應式篇
Thumbnail
本篇純粹紀錄實作流程,以方便未來可以照此版繼續優化改進作法,這篇會使用Laravel 9版本並搭配Boostrap 5來做開發。 發現將每一次的實作作筆記,回頭再看的時候,就可以發現實作差異並進行改正,沒搞懂的底層操作也能在覆盤的時候理解,建議大家都要筆記自己的實作流程。
Thumbnail
本篇純粹紀錄實作流程,以方便未來可以照此版繼續優化改進作法,這篇會使用Laravel 9版本並搭配Boostrap 5來做開發。 發現將每一次的實作作筆記,回頭再看的時候,就可以發現實作差異並進行改正,沒搞懂的底層操作也能在覆盤的時候理解,建議大家都要筆記自己的實作流程。
Thumbnail
1. 安裝node.js 2. 建立專案: 接著會詢問一些初始化設定的東西,按照需求選擇即可: 3. 執行 打開http://localhost:3000/ 即可看到畫面。 pages Nuxt.js會自動配置pages中每一個.vue檔案的route。 假設在pages資料夾下新增一個如下內容的a
Thumbnail
1. 安裝node.js 2. 建立專案: 接著會詢問一些初始化設定的東西,按照需求選擇即可: 3. 執行 打開http://localhost:3000/ 即可看到畫面。 pages Nuxt.js會自動配置pages中每一個.vue檔案的route。 假設在pages資料夾下新增一個如下內容的a
Thumbnail
在寫頁面之前,先來介紹 Vue 頁面結構。 首先先在 src/components 底下建立一個 home.vue 跟寫一個 html 頁面很像,一樣是分成 寫網頁內容、script、style,三個部分,只是 html 標籤換成了 template。 template 就是相當於原生 html 檔
Thumbnail
在寫頁面之前,先來介紹 Vue 頁面結構。 首先先在 src/components 底下建立一個 home.vue 跟寫一個 html 頁面很像,一樣是分成 寫網頁內容、script、style,三個部分,只是 html 標籤換成了 template。 template 就是相當於原生 html 檔
Thumbnail
專案建好了,那先來講 Vue 的專案架構 詳細內容很多,所以我挑重點講 public index.html public/index.html 是 Vue 頁面的 entry point,進入一個 Vue 頁面會先進 public/index.html,再套用 App.vue,最後才是進入你寫的 .
Thumbnail
專案建好了,那先來講 Vue 的專案架構 詳細內容很多,所以我挑重點講 public index.html public/index.html 是 Vue 頁面的 entry point,進入一個 Vue 頁面會先進 public/index.html,再套用 App.vue,最後才是進入你寫的 .
Thumbnail
前言 Vue 在過去的一兩年內快速發展,寫法也一直改變,我在過去一年多也更改了兩次寫法,在這個系列中我將以最新的 composition api + typescript 寫法進行教學。 javascript 有兩大痛點,一個是異步問題,另一個是弱型別。要渲染畫面一定要多線程同時異步處理,不然真的一
Thumbnail
前言 Vue 在過去的一兩年內快速發展,寫法也一直改變,我在過去一年多也更改了兩次寫法,在這個系列中我將以最新的 composition api + typescript 寫法進行教學。 javascript 有兩大痛點,一個是異步問題,另一個是弱型別。要渲染畫面一定要多線程同時異步處理,不然真的一
Thumbnail
data() method 續上篇,這邊修改一下HomeView.vue的code。 Before: After: 在頁面最下方顯示 name: Vic,data method直接回傳name變數,在<template>中可以直接用{{ name }}將變數顯示出來。 結果如下: v-model
Thumbnail
data() method 續上篇,這邊修改一下HomeView.vue的code。 Before: After: 在頁面最下方顯示 name: Vic,data method直接回傳name變數,在<template>中可以直接用{{ name }}將變數顯示出來。 結果如下: v-model
Thumbnail
假設資料如下: local DB裡面的test Collection SELECT SELECT可以這樣寫: 由於config/database.php中設定的default DB_CONNECTION是mysql,所以這邊特別指定使用mongodb connection。 回傳結果如下: 軟刪除
Thumbnail
假設資料如下: local DB裡面的test Collection SELECT SELECT可以這樣寫: 由於config/database.php中設定的default DB_CONNECTION是mysql,所以這邊特別指定使用mongodb connection。 回傳結果如下: 軟刪除
Thumbnail
S1.建立資料庫 user S2.建立 index.htm a.載入 vue.js、jquery、bootstrap b.版面建立 S3.vue.js程式 新增、查看列表、互動視窗、修改、刪除 index.htm VueControl.js 原碼:https://reurl.cc/e3k8yL
Thumbnail
S1.建立資料庫 user S2.建立 index.htm a.載入 vue.js、jquery、bootstrap b.版面建立 S3.vue.js程式 新增、查看列表、互動視窗、修改、刪除 index.htm VueControl.js 原碼:https://reurl.cc/e3k8yL
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News