前言:
這篇文章我希望可以快速帶大家了解一下近幾年前端發生的變化,那怕只有一點點,希望大家可以整理出一些頭緒,因為小編真的很不會教學= =
這篇文章全程將以Vue2.0(以下簡稱Vue)做為開發範例,依照之前我跟團隊提起這個名詞的經驗,很多人會問說這是啥洨,為什麼等問題,這很正常,小編會一一跟大家做解答。不過小編所學有限,大家想要有更詳細的了解,還是自行上網google一下比較好
在本文的一開始,必須重申,本篇的重點不是要教會大家一門技術,是希望帶給大家一些觀念,告訴大家現在前端正在流行的開發方式,只是藉由 Vue這個框架來達成這個目的。因為小編在摸完這麼多框架後發現,概念是一樣的,只是用的方法與語言不一樣。那既然是這幾年的新技術,那不免俗地有一拖拉庫的名詞必須解釋,那我們開始吧。
究竟什麼是Vue呢?
Vue(讀音聽起來像是view),這是一套前端JS的微型框架,比起有名的React & Angular算是後起之秀,他的開發者 尤雨溪,沒錯,看到這名子就知道他是個非常牛逼的中國人,他在美國讀研究所,畢業後曾任職於GOOGLE,不過現在已經離職(推測他的年紀好像跟小編差不多就是了),整個框架主打輕量化,所以每個套件都各司其職,因為程式全部由他一個人開發,所以修BUG也非常快,檔案非常小,相對加載速度也就快,且沒有相依。據官方數據,Vue在render的效能上是遠超過React跟NG2的(僅限2.0)。
隨著日漸穩定,也推出了 VueRouter(Router) & Vuex(Flux),甚至是 Vux(針對ui進行操作的涵式庫) 等套件,Vue日前幾乎跟NG2差不多時間推出了2.0,但不同於NG>NG2幾乎就是個打掉重寫的工程,兩個版本相似程度高達90%,甚至推出了升級工具 "Vue migration helper",裝完套件後,只要下一行指令,就可以照著他給你的提示一一做出修改,實在時非常便利。
小編之所以選擇 Vue的原因,是因為它開發模式偏向於NG(注重model),但他入門程度甚至比React還要低,而且非常低耦合,跟任何框架在一起都可以運作,也可以在專案開發中隨時導入,不一定要侷限於SPA或模塊式的開發。然後對於model的控制,你可以隨時改變model,甚至用第三方程式去改變都可以(例:jQuery ajax),自由度相當高。所以小編用完有點回不了頭。
Vue還有個最大的優點,因為作者是中國人,所以文件都是中文版!!!!(我葳葳中華,堂堂炎黃子孫,憑什麼叫我去學番邦語言!!),不過作者還是會先推出英文文件,才會逐漸翻譯成中文就是了。(人家畢竟在GOOGLE待過咩~是有世界觀的男人~)
官方說法,有基礎的工程師都可以在三天之後駕馭這套框架大半,可見這個框架真的不難,本篇重點是希望藉由這套框架讓大家知道這些年前端流行的開發趨勢,所以在環境架設開始之前,還有幾個技術名詞要了解一下
二話不說先附上官網了
為什麼不選React or Angular2?
針對這三套框架的比較網路上文章一大堆,硬是要講原因就是
第一:vue夠簡單,隨時可以上手,輔助套件也相當充足穩定了現在
第二:相較React的learn once, write anywhere的jsx語法,專注於model的vue跟ng2寫法上算相當直覺
第三:它夠快,網路上也有很多效能比較的數據,大家可以自己GOOGLE看看。
第四:相依性超級低,我寫不下去的時候隨時可以回到jQuery繼續開發,等我哪天心情爽了之後再改回來。
第五:更新速度也夠快,因為程式全部是作者一個人包,所以他承諾修BUG速度絕對比GOOGLE團隊修BUG速度快上許多(大家使用上有問題也可以去github上面反映issue,作者曾嗆angular2上面的 issue太多且很難關閉,另外,事實上有個團隊在維護拉,所以大家不用怕尤大如果萬一怎麼辦之類的事情發生)
它唯一的缺點:社群依然不夠龐大,使用者相較下是比較少的,在我今天介紹之前有人有聽過Vue的嗎?光看FB上 ReactJS .vs. Angular JS User Group Taiwan .vs. Vue.js台灣 三個社群人數比例是8000:5000:2000,React支持者一大堆我也不知道為什麼,明明就很難寫啊!!人數多少的影響應該是提問得到答案的速度,我初估大概差了五倍吧,不過都會在一天之內得到答案,所以都還可以接受。而且 Vue社群人數少,所以很團結跟友好,你有問題都會非常熱心回答(好吧~小編曾在ng社群提問被直接忽視= =)。另外你上百度發問還時不時會遇到作者出來幫你做專業的解答,作者在身邊,感覺就好像志玲姊姊坐在你隔壁上班,好像很厲害!(從小編撰寫這篇文章,人數只有1500至今短短兩個月,人數已上升了500,不塊是未來的新星)
就算你上面幾點通通都不認同,也沒有關係,小編就是愛用 Vue,你可以咬我,或者右上角有叉叉,君子請自重阿~~
那會碰到那些技術名詞呢?
Component:
大家可以把網頁上的任何一個tag都視為是一個元件(包含內部的其他子tag),至於這個元件要大到多大,要小到多小,並沒有明文規範,需要開發者憑經驗去判斷這個元件有沒有"必要"被寫成元件而已。
大家可以用mvc的技術去想像,這就像view裡面的layout一樣。
另外,在 Vue裡面的component跟ng2的component很像,有自己的html, css, js,只是它全部都寫在一起,並給予它副檔名為.vue的檔案,你會說這是什麼沒看過, 沒關係,你看不看得懂無所謂,不過webpack看得懂就好了。在檔案數量上,小編也比較喜歡 Vue的編制,不然ng2一個comonent就三個檔案,加上測試檔就四個了,這還讓不讓人生存阿。
模塊式開發:
為了避免所有程式碼都寫在同一頁,所以可以藉由 import 或 required 把原本要開發的程式拆成許多小塊(component, store.....)後引入,但browser 是看不懂 import 的,所以需要藉由 Browserify or systemJS or webpack or 百度的fis 和 支付寶的spm ......等套件做預處理,所謂預處理就是在borwser 讀取頁面之前,先做的處理。
開始體會到什麼叫做到名詞地獄了吧。就是很多的套件都在做相同的事情,不過雖然做的事情類似,卻還是有些許的不同,但那等我們有用到再討論吧,這種情況我們一般我們會選用最大宗去做,雖然不保證它不會被取代,但至少確保它會持續地更新,所以小編推薦使用webpack 做預處理工具。
webpack 非常強大,我覺得可以再寫一篇文章專門在介紹這套工具了,大家可以把他理解成為一套 打包 與 編譯 的工具就可以了(剛剛提到的.vue或是.css .sass .less或是ES6的js等檔案也是在這裡做重新編譯),他可以把入口檔開始所import的所有檔案,包含CSS跟圖片檔,通通打包成 "1" 個JS檔,最後使用者只須要引入這個JS檔,網站就會開始運作了~是不是很利害呢。讓大家可以只專注在js的開發。
依照個人需求,webpack也可以把所有引入的css另外合併成一個css,不過必須透過外掛處理,預設式全部寫在js中的。
Router:
有開發過.NET的人,應該對這個名詞不陌生,就是藉由網址路徑導道不同的controller & action 去引入不同的View,在前端也是一樣的,不過不是導到不同的Controller,而是在指定的tag中引入不同的Component,且頁面不會重新刷新面。
ps. 大家在裝 "vue-router" 的時候記得不要打成 "vue-route",這是完全不同的套件,小編曾經因為這個r卡了一整天。
一般在前端也有router的狀態下會建議前後端拆開,但就真的沒有預算或專案沒這麼大不需要拆開的狀況,遇到後端的router跟前端的router衝突怎麼辦呢?小編也還在研究,不多說直接附上網址
SPA:
我也很喜歡洗SPA,那寫SPA呢? SPA全文(Single Page Application),單頁應用程式,就是藉由Router引入不同的子頁面,達到不刷新頁面而局部更新的效果,以達到省流量,快速,還有局部開發的優勢。看一下示意圖
Flux:
關於這個名詞最早是由FB為了處理React資料流所提出來的一個設計模式。後來被廣泛開發成一許多套件,在Vue之中落實Flux設計模式的套件就叫做Vuex,大家可以直接理解為Vue之於Vuex就好像React之於Redux,一樣很多人會問Flux是做什麼的用的呢?大家想像一個三角形,每個節點都想像成一個Component,每個Component都有自己template, model, style, sub component.......,那元件之間該如何溝通呢? 答案就是藉由發射器 $emit,這個名詞有開發過nodejs的人應該不陌生,父層可以藉由屬性可以把物件或字串數值傳給sub component,而sub component可以藉由$emit可以把值再向上傳給父層,在vue之中還可以特別透過BusEvent物件,大家可以想像它就像個廣播器,讓這專案下的component都可以接收到事件觸發。只是如果component越來越多,或頁面一多,事件的處理就越來越繁瑣,所以最好的方法就是統一交由Store管理,每個component需要資料時統一跟Store存取,要變更資料時也統一直接對Store變更,接收到變更後,Store就會主動去通知所有有用到這個欄位的component更新顯示。
大家把剛剛的三角形壓成平面,把原本需要上上下下傳遞的事件全部弄成平面,這樣資料在傳遞上似乎就通暢多了。就好像員工電腦壞掉大家不用藉由MAIL向上司報告上司再向部門主管報告........這樣傳遞下去非常消耗時間成本。所以最好就是有位專員負責處理這些大小事務,員工(component) 直接去請(dispatch) IT(store) 來維修電腦(model),修好之後員工就可以直接用更新後的電腦上班了,這樣不是很棒嗎?
小結:
每個語言及框架,沒有對錯,只有其適合與不適合的地方,例如用傳統的寫法搭配jQuery不是沒辦法做到SPA,也不是沒辦法做到render跟two-way-binding,但就是撰寫起來會非常繁瑣,要綁定許多事件,外加問題可能會存在非常多,還有無論是開發或是渲染速度都會相對上較慢。
另外這邊要來小小澄清一下,React & NG2 也是可以做到非SPA的開發,只是因為撰寫語言或框架太大關係,要進入個人覺得綁手綁腳,所以儘管小編是先接觸這兩個技術,卻也還沒完全研究成功~
網路上曾經看過一篇文章,作者只是想要寫個AJAX,卻必須學會一拖拉庫的技術,就因為現在是2016年,用 jQuery已經是非常不潮的行為了。所以必須花上大把時間,學習一堆技術,最後達成我想要AJAX的這個需求。當然,這是個笑話,如果你只是想要個 ajax當然用 jQuery是最快的,但這也是個不爭的事實,確實,好的工程師必須要可以用最小的舉動達成最終的目的,但不懂得考量團隊合作與日後可維護性的工程師只是個自私的渾蛋,這也就是為什麼前端技術一直推出新技術,難道真的是吃飽沒事幹嗎? 當然是為了開發速度,效能,好維護,關注點分離,等因素被創造出來的。所以小編不希望各位看完這篇文章只是為了去寫個AJAX功能出來,而是希望各位抱持著擁抱學習,提升自己的想法看完這篇文章。
當然小編也不認為 jQuery已死,也不認為他在短時之內會死,你大可繼續使用你苦練了好幾年的技術繼續開發,只是現在前端的世界進步很快,沒有拋頭顱灑熱血的決心真的不適合待在這裡,據傳每18個月,技術就會困難一倍,所以不再是不進則退,進步得太慢也是退步!而且當我告訴你,學完這些技術之後你月薪起碼可以提升5000塊,儘管學習曲線陡峭,那你學不學呢?
不過很殘酷的是,用新技術開發完,就是開發者自己心裡覺得很屌,老闆覺得省了很多人事成本而已,就使用者的體驗上,並不會差太多,當然這是在 0 BUG的情況下比較。
環境架設:
相信我,這絕對是所有語言都會到遇到,且是最麻煩的部分,這也是讓許多人不得其門而入的高牆,很多人學完 npm後打開 package.json看到一大堆沒看過的套件就繳械了,所以在外圍觀望了很久,小編就是個活生生的例子,但相信我,只要你勇敢踏出一步,你會發現其實沒有這麼難,很多東西只要配置好就可以一路順暢開發無阻礙,而且官方還推出 vue-cli或 angular2-cli之類的命令式語法,更加降低建置環境與開發的困難度。
不過我剛剛也說了 vue可以做到隨時導入,就算只學一點點也可以開發出簡易的data-flow,所以我這邊有兩種開發方式可以任君選擇,一種是無痛開發,另外一種是先苦後甘開發,大家可以依需求選擇
無痛開發:
只需要引用這麼一行,就可以開始寫vue程式了
優點:不需要經過太多手續,用傳統的方式引入library即可,對於要即時導入data-flow的專案有非常大的效果
缺點:如果引入的檔案過多效能差,且須留意引入順序,會在專案開發過程綁手綁腳,專案越大越明顯
先苦後甘開發:
附上我已經寫好的程式,各位只需要做好下面幾個步驟專案就可以運作了。
step1.
step2.
cd vue_practice
step3.
npm install
step4.
npm start
step5.
裡面有個非常陽春的畫面,雖然是練習用,卻包含了上面我所陳述的所有技術,而且這個專案是我從無到全部有自己建置的,所以不會用到什麼深不可測的技術跟配置,畢竟小編也是魯蛇一條,所以一定很好懂,不懂也一定GOOGLE得到。
大家也可以直接透過vue-cli建置專案,免去環境建置的麻煩。
setp1.
npm install vue-cli -g
setp2.
vue init webpack project_name
step3.
cd project_name
step4.
npm run dev // dev是開發模式,待開發結束可以下npm run build就會產出最終檔案到 /dist資料夾,在把資料夾下的檔案放到伺服器即可執行
step5.
http://127.0.0.1:8080
既然有巨人的肩膀,就不要猶豫快站上去吧。當然如果大家想站在魯蛇的肩膀上也是可以拉。不過後面的範例說明都會用cli建立的專案說明喔。想要自學的人在用我建立的專案慢慢學習吧。
優點:可以真正達成模塊式開發,無須擔心引入的部分,速度快,適合團隊開發,落實關注點分離,適用於所有伺服器(但開發中仍是以nodejs為主),而且還有hot reload(熱加載,元件編輯完自動刷先新)
缺點:如果重頭開始件建置專案,第一次確實會頭很大,不過建置專案的重點都放在webpack即可,另外如果對建置環境不熟悉,就很難做到要從已開發專案中插入的需求,這也是為什麼一般人都會先選用無痛開發起步的原因
特別強調一下,為避免低級錯誤,用vue-cli建專案會引入 eslint, editorconfig套件,會特別強調撰寫風格,多一個空格少一個空格什麼的,這也會導致大家程式碼直接複製貼上卻run不出來的原因,沒關係大家改久就習慣了。或者大家可以自行修改 .editorconfig、.eslintrc.js 這兩個檔案,或直接刪掉。
程式開發:
下面程式所有的註解都是小編額外加上去的,如果有編譯失敗的情況記得要拿掉喔。
終於要進入我們的主題了,那主頁面index.html基本上我們只會動一行,程式碼如下
<!DOCTYPE html>
<html>
<head>
<meta charset= "utf-8" >
<title>clitest</title>
<script src= "src/main.js" ></script><!-- 加入入口檔案 -->
</head>
<body>
<div id= "app" ></div><!-- built files will be auto injected -->
</body>
</html>
|
我們來看一下主程式,小編會針對要講解的內容稍微做些簡化,未必會跟剛 init完的檔案一樣
import Vue from 'vue'
import App from './App'
new Vue({
el: '#app' ,
template: '<App/>' ,
components: { App }
})
|
我們來看一下App component
<template>
<div id= "app" >
<img src= "./assets/logo.png" >
<hello></hello>
</div>
</template>
<script>
import Hello from './components/Hello'
export default {
name: 'app' ,
components: {
Hello
}
}
</script>
<style>
#app {
font-family: 'Avenir' , Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
|
跟ng2不太一樣的是,ng2會用一個資料夾去包 .html, .js, .css, .spec.js四個檔案,但這樣讓開發者看起來會很阿雜,所以保哥上課時就說開發者必須自行判斷元件有沒有必要被開發為元件,因為拆太細,檔案可是會一拖拉庫的,而在vue裡面,就只會有一個 .vue 檔案,就算你拆得比ng2細四倍,檔案也才一樣多而已,哼~
接著我們來看一下Hello Component
<template>
<div class = "hello" >
<h1>{{ msg }}</h1><!-- 大家有沒有看到跟ng一樣的寫法, 這行render出來換變成 => <h1> Welcome to Your Vue.js App </h1>-->
<input type= "text" v-model= "msg" /><!-- vue跟ng1&ng2一樣,也充滿了語法糖,v-model,是要做到雙向綁定的意思,就是修改的同時,msg變數也會修改,那上面的這行字也會跟著修改,這就是雙向綁定神奇的地方啊 -->
<br>
<a v-bind:href= "href" >google</a><!-- 又是個語法糖,也可以簡化為:href,作用是用來綁定屬性,也可以藉由綁定屬性,component可以藉由prop取得資料或物件 -->
<!-- 這裡render完會變成 => <a href= "www.google.com" >google</a> ,也有人會寫<a href= "{{href}}" >google</a>這樣是也可以運作的,只是會有少部份情況會出現不是你希望看到的畫面,或是效果,待各位自行研究了-->
<br>
<button v-on:click= "onHandleClick" >+ 1 </button><!-- 又是個語法糖,也可以簡化為 @click ,作用是用來綁定事件 -->
<span v-text= "count" ></span><!-- 如果客戶非常龜毛,跟你反應頁面剛開起來會看到一堆{{adf}}之類的亂碼,可以透過這個語法糖,讓vue啟動之後再把變數render出來 -->
<h2 v- if = "count>0" >Hello Component</h2><!-- 如果不符合條件,tag將會被刪除,不是隱藏喔,隱藏要用v-show -->
<br>
<select v-model= "selector" >
<option v- for = "(val,index) in [1,2,3]" :value= "index" v-text= "val" ></option>
<!-- 今天講我們最後一個要說的語法糖v- for ,類似foreach的效果,是在show陣列或物件資料不可或缺的存在 -->
<!-- render完會變成如下
<option value= "0" > 1 </option>
<option value= "1" > 2 </option>
<option value= "2" > 3 </option>
-->
</select>
<!-- 當然還有v-once(只渲染一次) v-html(輸出內容是html格式,必須要這個語法) v- else ....很多語法糖有待各位自行發掘,這就不一一展示 -->
</div>
</template>
<script>
export default {
name: 'hello' ,
data () {
return {
msg: 'Welcome to Your Vue.js App' ,
count: 0
}
},
methods: {
onHandleClick () {
this .count++
}
},
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0 ;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
|
Vue 的撰寫風格,有寫過 ng的人說應該會很熟悉,都是在 html語法中寫入一堆語法糖。
資料綁定跟畫面的花俏一點關係都沒有,只是讓大家可以把注意力放在model上面,以大幅減少data被複製出太多份,捉錯,或忘記render等 bug出現,所以這類框架就不適合形象網站,如果要動畫飛來飛去的你還是去找jQuery吧,不過如果你要寫的是系統,列表,後台,或是component會不斷重複利用的網站,例如社群網站,倒是會如魚得水。
這裡比起原始檔案,改了很多東西,因為我想把vue的基礎語法都在這裡說完。基礎就說到這了,接著我們來談談 router吧。
VueRouter
最直覺的想法就是router要寫在入口頁,也就是App component裡,那我們就來看一下要怎麼改吧。(下面的程式就完全都不一樣了,讀者可以參照著文章修改或加檔案)
首先在要在上層的 main.js Vue物件中增加 router設定,讓所有的 component都可以有自己的 router-view
import Vue from 'vue'
import App from './App'
import router from './router'
new Vue({
el: '#app' ,
template: '<App />' ,
components: { App },
router
})
|
<template>
<div id= "app" >
<router-link to= "/" >Hello</router-link> <!-- 會被編譯成為<a....> -->
<router-link to= "/bar/123" >Go to Bar</router-link>
<img src= "./assets/logo.png" >
<router-view></router-view> <!-- router完的component就會被丟到這裡 -->
</div>
</template>
<script>
export default {
name: 'app'
}
</script>
<style>.......</style>
|
這裡應該只有一個檔案有問題,就是router這個檔案,我們來看一下,設定檔怎麼寫吧
import Vue from 'vue'
import VueRouter from 'vue-router'
import Hello from 'component/Hello'
const Bar = {
template: `<div>bar {{ $route.params.id }}</div>`
}
const routes = [
{ path: '/' , component: Hello },
{ path: '/bar/:id' , component: Bar }
]
Vue.use(VueRouter)
const router = new VueRouter({
routes
})
export default router
|
在這樣就可以達成router了喔,且裡面也可以丟參數,可藉由$route.params取得,是不是很簡單呢 ~
router學完接著我們來學flux,那我們會用到vuex套件,沒有的人一樣,記得裝一下,裝完記得重新run專案。
另外來小小解釋一下 ` (模板字符 原文:template string)。這是ES6特有的符號 ,可以在裡面寫入多行的字串,不需要傳統的傳統的 結束字串符號,然後相加,然後在第二行.....,甚至可以寫入變數,(例如: var a=100; str = `a = ${a}` => b = "a = 100";) ,程式會經過 babel轉譯成 ES5 (傳統的雙引號字串相加),另外小編推薦用VSCode開發也不會出現令人惱怒的紅色蝌蚪,所以各位可以不用顧慮,大方使用。
VSCode裡面也有許多好用的套件,可以加速大家開發的速度與激情
便利性,等待大家去發掘喔~
Vuex
因為我們層數沒有很多,那我們資料就從最上層的App component塞,然後從Hello component取吧,來看一下程式該怎麼改。
一樣要在最上層的main.js加入vuex設定,確保所有的 component都可以吃到 store
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
new Vue({
el: '#app' ,
template: '<App />' ,
components: { App },
router,
store
})
|
<template>
<div id= "app" >
.....
<button @click = "countAdd" >+ 1 </button>
</div>
</template>
<script>
......
export default {
name: 'app' ,
methods:{
countAdd:function(){
this .$store.dispatch({
type: 'incrementAsync'
})
}
}
......
}
</script>
<style>.......</style>
|
那我們來看一下該怎麼接資料呢
<template>
<div class = "hello" >
<h1>{{ count }}</h1>
</div>
</template>
<script>
export default {
name: 'hello' ,
computed: {
count () {
return this .$store.state.count
}
}
}
</script>
<style scoped> ......</style>
|
跟React最大不同就是vue跟ng2都會有自己component的model,當template再取值的時候沒辦法直接取store中的值,必須靠計算屬性轉一手。
最後我們來看一下最重要的store怎麼設計
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
incrementAsync ({commit, state}, payload) {
commit( 'increment' )
}
}
})
|
大家應該一樣沒然為什麼這裡也要經過 action commit再到 mutations之後才去更新count,依據官方的說法,mutations才有資格去更改state的值,但是mutations是同步處裡的,所以如果需要異步處裡的功能需要藉由action來做到,這也就是為什麼我留了個setTimeout給大家參考的原因。
當然ditpatch也是可以待參數的。另外如果有接觸過redux的人也可能會問,有沒有類似 reducer的東西可以用,不然專案越來越大,會越來越亂,有!你要什麼都有!不過在vuex不叫 reducer,而叫 module,或者一個畫面想要兩個路由 component,或 router裡面還要有router可以嗎?可以!至於怎麼用呢?
這又是另外一個故事了(遠目~),不難拉 ~ 自己去查 ~
總結:以上就是vue的所有基礎知識,以及前端目前流行的開發方式,對各位來說可能會是個知識爆炸的一天,沒關係,小編也是過來人,I got you ~~ 不過程式這種東西還是要自己實做過一次,才就懂每一行程式到底都在做些什麼,特別是前端 JS,不經過自己手上實做出來,並看到變化,實在抽象到難以想像。沒關係大家可以慢慢消化,大家還有18個月再去迎接更難的程式。希望今天的課程內容可以帶著大家從 網站設計師 朝向 前端攻城屍 之路向前邁進一步!剩下的大家就自行研究了,希望大家可以享受開發的過程,有不懂的地方,或想要更加深入了解的地方,也歡迎隨時提問或直接敲我討論,以上謝謝大家。
終於打完了~比我以前寫的小說還長~好想哭阿~~~~
沒有留言:
張貼留言