症狀
原因
改善方法
症狀
原因
改善方法
改善方法
容易緊繃的肌肉
容易無力的肌肉
骨科的定義比較嚴重,通常是到老年才會比較明顯。趁早運動加強核心肌群。
骨頭歪掉
三招貼紮放鬆肩膀旋轉肌群
打羽球過度內旋產生的脊上肌、脊下肌、小圓肌放鬆與貼紮教學
告別上背痛,來看看什麼是「反向動作」
介紹放鬆動作和對應的肌肉
症狀
原因
改善方法
症狀
原因
改善方法
改善方法
容易緊繃的肌肉
容易無力的肌肉
骨科的定義比較嚴重,通常是到老年才會比較明顯。趁早運動加強核心肌群。
骨頭歪掉
三招貼紮放鬆肩膀旋轉肌群
打羽球過度內旋產生的脊上肌、脊下肌、小圓肌放鬆與貼紮教學
告別上背痛,來看看什麼是「反向動作」
介紹放鬆動作和對應的肌肉
今年做了一件特別的事情,申請擔任活動志工。
]]>今年做了一件特別的事情,申請擔任活動志工。
]]>介紹了兩個 CSS 框架的一些使用經驗
https://slides.com/mikecheng1208/deck-8db2a6
介紹了兩個 CSS 框架的一些使用經驗
https://slides.com/mikecheng1208/deck-8db2a6
看到這篇的你筆電可能正住在加護病房,留個言為他集氣ㄅ。
等他出院記得要更新一下。
在英國筆電灑到一點白開水實錄
看到這篇的你筆電可能正住在加護病房,留個言為他集氣ㄅ。
等他出院記得要更新一下。
在英國筆電灑到一點白開水實錄
你以為你在寫 Custom Hook,但其實只是在寫 utils | KK
之前好像有寫過筆記但不見了,重看一次...
小技巧
return { users }
,回傳 data 以外的資訊return users
{ users, error, loading, refetch }
常見錯誤:
都 2022 年了你可能還是不懂 useEffect | Zet
一開始有點雜音,後面有修掉。
Demo
this.props.user 是 mutable 的方式。他不會記得觸發拿時間的資料,會拿到三秒後的資料。所以觸發時間點的 this.props.user 要找個地方存起來。
Functional Component 每一次 render 都有他自己的連鎖資料流
class component 基於 OOP,以 mutable 的方式存取 this.props&this.state
functional component 基於 FP,每次都會重新執行函數並傳入獨立參數的方式來存取 props&state
每次 render 都有自己的資料狀態(props&state)、event hanler,不會互相影響
effect 也是屬於某次 render,effect 是利用 closures 的方式看到不一樣的原始資料
當依賴的值是常數 closures 好理解,但依賴的值是 mutible 時可能發生意外。
FP 好理解,但犧牲了效能,每次 render 都有自己獨立的資料。
clean up
https://slides.com/tz5514/useeffect-guide
strict mode + dev env
你以為你在寫 Custom Hook,但其實只是在寫 utils | KK
之前好像有寫過筆記但不見了,重看一次...
小技巧
return { users }
,回傳 data 以外的資訊return users
{ users, error, loading, refetch }
常見錯誤:
都 2022 年了你可能還是不懂 useEffect | Zet
一開始有點雜音,後面有修掉。
Demo
this.props.user 是 mutable 的方式。他不會記得觸發拿時間的資料,會拿到三秒後的資料。所以觸發時間點的 this.props.user 要找個地方存起來。
Functional Component 每一次 render 都有他自己的連鎖資料流
class component 基於 OOP,以 mutable 的方式存取 this.props&this.state
functional component 基於 FP,每次都會重新執行函數並傳入獨立參數的方式來存取 props&state
每次 render 都有自己的資料狀態(props&state)、event hanler,不會互相影響
effect 也是屬於某次 render,effect 是利用 closures 的方式看到不一樣的原始資料
當依賴的值是常數 closures 好理解,但依賴的值是 mutible 時可能發生意外。
FP 好理解,但犧牲了效能,每次 render 都有自己獨立的資料。
clean up
https://slides.com/tz5514/useeffect-guide
strict mode + dev env
補發
補發
React 官方教學區 https://react.dev/learn/describing-the-ui
State 的用途:
什麼是 Rendering?
每次的 Render 都有自己的輸入,我們希望輸入來自不變的值,或 function 內部的資料(state&ref),而不是依賴外部的值(=產生 side effect)
Good Side Effect:
Bad Side Effect:
Bad Case
let guest = 0;
function Cup() {
// Bad: changing a preexisting variable!
guest = guest + 1;
return <h2>Tea cup for guest #{guest}</h2>;
}
export default function TeaSet() {
return (
<>
<Cup />
<Cup />
<Cup />
</>
);
ref
保存 DOM Nodeeffect 可以放在哪?
基本 useEffect 用法
什麼東西要綁 dependency?
什麼東西要 cleanup?
沒 cleanup 會怎樣?
檢查 cleanup
state 依賴外部 props
// Better: Adjust the state while rendering
const [prevItems, setPrevItems] = useState(items);
if (items !== prevItems) {
setPrevItems(items);
setSelection(null);
}
// ...
如果 state 依賴外部 props 的做法,可以多用一個 if 判斷來做同步,不需要用到 effect。壹定要有 if,不然會變成 loop。
想要初始值
key={userId}
使用 key。當 key 改變 component 會回到預設值,不需要用寫 effect 依賴 userId。
React 官方教學區 https://react.dev/learn/describing-the-ui
State 的用途:
什麼是 Rendering?
每次的 Render 都有自己的輸入,我們希望輸入來自不變的值,或 function 內部的資料(state&ref),而不是依賴外部的值(=產生 side effect)
Good Side Effect:
Bad Side Effect:
Bad Case
let guest = 0;
function Cup() {
// Bad: changing a preexisting variable!
guest = guest + 1;
return <h2>Tea cup for guest #{guest}</h2>;
}
export default function TeaSet() {
return (
<>
<Cup />
<Cup />
<Cup />
</>
);
ref
保存 DOM Nodeeffect 可以放在哪?
基本 useEffect 用法
什麼東西要綁 dependency?
什麼東西要 cleanup?
沒 cleanup 會怎樣?
檢查 cleanup
state 依賴外部 props
// Better: Adjust the state while rendering
const [prevItems, setPrevItems] = useState(items);
if (items !== prevItems) {
setPrevItems(items);
setSelection(null);
}
// ...
如果 state 依賴外部 props 的做法,可以多用一個 if 判斷來做同步,不需要用到 effect。壹定要有 if,不然會變成 loop。
想要初始值
key={userId}
使用 key。當 key 改變 component 會回到預設值,不需要用寫 effect 依賴 userId。
10/15
標題看不出內容,其實是在講資安驗收與常見破口。
不小心聽到的一場,讚,實用!
https://github.com/ETCExtensions/Edit-This-Cookie
https://hackmd.io/@ModernWeb/MW21/%2F%40ModernWeb%2Fr1CO0upVK
10/19
分享 Google sheet 串 Figma 產圖的方法,讚,實用!
Medium 文章 -【INSIDE IG 設計幕後】用 Figma + Google Sheet 開啟合作的無限可能
10/21
網頁建構器 MVP 執行問題
ref
前端與設計的痛,切不出設計想要的版。
從剛入門到現在一直說要學,但一直沒好好學的選取器...
10/26
https://jamstack.org/headless-cms/
讚讚讚,很多小案子不想用 wordpress 又不想做後台,原來早就有這麼多解決方案了= =
https://blog.256pages.com/headless-cms-2018/
Directus
https://github.com/KdanMobile/directus_demo
Kdan Mobile
10/27
https://hackmd.io/@ModernWeb/MW21/%2F%40ModernWeb%2FB13PAdpNY
https://hackmd.io/@ModernWeb/MW21/%2F%40ModernWeb%2FS1xOR_6EK
]]>10/15
標題看不出內容,其實是在講資安驗收與常見破口。
不小心聽到的一場,讚,實用!
https://github.com/ETCExtensions/Edit-This-Cookie
https://hackmd.io/@ModernWeb/MW21/%2F%40ModernWeb%2Fr1CO0upVK
10/19
分享 Google sheet 串 Figma 產圖的方法,讚,實用!
Medium 文章 -【INSIDE IG 設計幕後】用 Figma + Google Sheet 開啟合作的無限可能
10/21
網頁建構器 MVP 執行問題
ref
前端與設計的痛,切不出設計想要的版。
從剛入門到現在一直說要學,但一直沒好好學的選取器...
10/26
https://jamstack.org/headless-cms/
讚讚讚,很多小案子不想用 wordpress 又不想做後台,原來早就有這麼多解決方案了= =
https://blog.256pages.com/headless-cms-2018/
Directus
https://github.com/KdanMobile/directus_demo
Kdan Mobile
10/27
https://hackmd.io/@ModernWeb/MW21/%2F%40ModernWeb%2FB13PAdpNY
https://hackmd.io/@ModernWeb/MW21/%2F%40ModernWeb%2FS1xOR_6EK
]]>會前
會議中你可以做的事
會後
會前
會議中你可以做的事
會後
今年因為疫情轉,大部分的技術年會都改為全線上。首發的 COSCUP 使用 Youtube 直播、Gather 互動。
線上年會優點是不用出門、可以直接開多個議程起來聽,甚至可以當 Hermione 倒回時間,但就少了一點大拜拜的感覺,像是這次應該是最快逛完攤位的一次。
以往逛實體攤位去湊熱鬧,有興趣的聽個三分鐘,沒興趣的就拿個小禮物閃人,不管有沒有興趣多少都有一點點小新知,例如被逼著下載新產品用用看或被逼著看他們在倡議的議題,這次有點可惜,想被強迫推銷qq
集滿所有贊助商攤位、社群攤位的通關密語,點數直接保留在你的 Email address 裡
下年度實體活動記得用 email address 登入 OPass, 兌換 2021 限量 商品.
一些筆記
區塊鍊快速入門
語速即快的一場,講解得算是好懂。
blocto dApp 簡單的實作教學,看完有空想做做看。
note
Laravel 自動測試的原始碼導讀。
簡易 CGI 入門 (但我不會 Ruby 後面的就沒聽了)。
CGI program
CGI 效能瓶頸
自己寫 CGI script 用 ENV 拿 request 太麻煩,用框架
CGI 流行於 1993 後起新秀:
技術小白如何找到適合自己的技術社群?
(小白:沒有工程師人脈網,也沒有參加什麼學生社團)
想參與不一定要聊技術,自嗨尬聊撐過去,想辦法裝熟。混熟後就可以請人家再推薦還有什麼可以參加、問自己能幫忙做什麼、或其它自己想做的事情(演講、發起活動...)。
在網路很方便的現代,社群不只是解決單一問題,更多好處是建立直接的人脈(直接跟套件作者對話),也可以拋出跟技術無關的問題(職涯問題),雖然是技術社群,只能聊技術也很無聊ㄅ!
今年因為疫情轉,大部分的技術年會都改為全線上。首發的 COSCUP 使用 Youtube 直播、Gather 互動。
線上年會優點是不用出門、可以直接開多個議程起來聽,甚至可以當 Hermione 倒回時間,但就少了一點大拜拜的感覺,像是這次應該是最快逛完攤位的一次。
以往逛實體攤位去湊熱鬧,有興趣的聽個三分鐘,沒興趣的就拿個小禮物閃人,不管有沒有興趣多少都有一點點小新知,例如被逼著下載新產品用用看或被逼著看他們在倡議的議題,這次有點可惜,想被強迫推銷qq
集滿所有贊助商攤位、社群攤位的通關密語,點數直接保留在你的 Email address 裡
下年度實體活動記得用 email address 登入 OPass, 兌換 2021 限量 商品.
一些筆記
區塊鍊快速入門
語速即快的一場,講解得算是好懂。
blocto dApp 簡單的實作教學,看完有空想做做看。
note
Laravel 自動測試的原始碼導讀。
簡易 CGI 入門 (但我不會 Ruby 後面的就沒聽了)。
CGI program
CGI 效能瓶頸
自己寫 CGI script 用 ENV 拿 request 太麻煩,用框架
CGI 流行於 1993 後起新秀:
技術小白如何找到適合自己的技術社群?
(小白:沒有工程師人脈網,也沒有參加什麼學生社團)
想參與不一定要聊技術,自嗨尬聊撐過去,想辦法裝熟。混熟後就可以請人家再推薦還有什麼可以參加、問自己能幫忙做什麼、或其它自己想做的事情(演講、發起活動...)。
在網路很方便的現代,社群不只是解決單一問題,更多好處是建立直接的人脈(直接跟套件作者對話),也可以拋出跟技術無關的問題(職涯問題),雖然是技術社群,只能聊技術也很無聊ㄅ!
前端
後端
雲端
從前端入門
從後端入門
從雲端入門
聽 Ant 講話,如沐春風。眼光在未來的人。
很多人是大部分是沒得選擇,大齡工程師的年代沒什麼前端。
如果你有得選的話,可以從入行成本與性格著手
Domain Know How vs 技術
技能樹怎麼那麼大棵,要怎麼點?
如何做"技術選型"決策
DB 選型:
https://pingcap.com/blog/how-to-efficiently-choose-the-right-database-for-your-applications
前端
後端
雲端
從前端入門
從後端入門
從雲端入門
聽 Ant 講話,如沐春風。眼光在未來的人。
很多人是大部分是沒得選擇,大齡工程師的年代沒什麼前端。
如果你有得選的話,可以從入行成本與性格著手
Domain Know How vs 技術
技能樹怎麼那麼大棵,要怎麼點?
如何做"技術選型"決策
DB 選型:
https://pingcap.com/blog/how-to-efficiently-choose-the-right-database-for-your-applications
只知道用靜態方法(官方文件也都用靜態方法)
TestService::getTest()
另一個選擇:依賴注入
在講 DI 之前,要先知道怎麼不 DI(就是 new 啦)
new TestService()->getTest()
依賴注入如何解決這個問題:
// 簡寫筆記
private $testService;
__construct(TestService $testService)
{
$this->testService = $testService;
// 依賴注入 建構子的注入
// Laravel 會在建立這個 controller 時幫你實例一個 TestServiece 參數放進去
}
這樣就是創建 controller 才會實例化這個 class,不會放一堆東西進記憶體。
還有什麼時候會用到依賴注入=>自動測試
原因:Service 應該要可以被隔離
因為可能在做單元測試,想控制變因。想隔離的服務可能是:接金流、讀 DB。靜態方法在測試可以用 alias 解決,但 DI 比較好
mock 會幫你用做一個假的 class。
測試時期宣告這段,就會創一個假 class 先把你後面的換掉,甚至在測試階段這個 getTest function 可以壞掉,還是會通過測試。
]]>this->mock 那一段 的意思,(在這一段測試程式裡面)之後遇到 TestService 都要換成 mockery 的 TestService
只知道用靜態方法(官方文件也都用靜態方法)
TestService::getTest()
另一個選擇:依賴注入
在講 DI 之前,要先知道怎麼不 DI(就是 new 啦)
new TestService()->getTest()
依賴注入如何解決這個問題:
// 簡寫筆記
private $testService;
__construct(TestService $testService)
{
$this->testService = $testService;
// 依賴注入 建構子的注入
// Laravel 會在建立這個 controller 時幫你實例一個 TestServiece 參數放進去
}
這樣就是創建 controller 才會實例化這個 class,不會放一堆東西進記憶體。
還有什麼時候會用到依賴注入=>自動測試
原因:Service 應該要可以被隔離
因為可能在做單元測試,想控制變因。想隔離的服務可能是:接金流、讀 DB。靜態方法在測試可以用 alias 解決,但 DI 比較好
mock 會幫你用做一個假的 class。
測試時期宣告這段,就會創一個假 class 先把你後面的換掉,甚至在測試階段這個 getTest function 可以壞掉,還是會通過測試。
]]>this->mock 那一段 的意思,(在這一段測試程式裡面)之後遇到 TestService 都要換成 mockery 的 TestService
https://laravel.com/docs/8.x#getting-started-on-macos 簡易版
https://laravel.com/docs/8.x/sail 詳細版
換電腦ㄌ~
終於有 mac 讓我裝 docker
mac 安裝步驟
docker --version
docker ps
列出所有 container確認 docker 成功運行後可以進去你的專案資料夾
cd codes
跑下載指令,後面是專案名稱
curl -s "https://laravel.build/新專案" | bash
可以用 ?with=mysql,redis"
去改預設的服務配置
https://laravel.com/docs/8.x#choosing-your-sail-services
linux 指令
laravel.build
我們從 https://laravel.build/新專案 這裡抓下來的東西是一段指令,laravel.build
是官方的網址,幫你產生一段 script。
例如:
cd 新專案
./vendor/bin/sail up
這邊差不多了,多做一個切換 PHP 版本,展現 sail 的厲害
https://laravel.com/docs/8.x#getting-started-on-macos 簡易版
https://laravel.com/docs/8.x/sail 詳細版
換電腦ㄌ~
終於有 mac 讓我裝 docker
mac 安裝步驟
docker --version
docker ps
列出所有 container確認 docker 成功運行後可以進去你的專案資料夾
cd codes
跑下載指令,後面是專案名稱
curl -s "https://laravel.build/新專案" | bash
可以用 ?with=mysql,redis"
去改預設的服務配置
https://laravel.com/docs/8.x#choosing-your-sail-services
linux 指令
laravel.build
我們從 https://laravel.build/新專案 這裡抓下來的東西是一段指令,laravel.build
是官方的網址,幫你產生一段 script。
例如:
cd 新專案
./vendor/bin/sail up
這邊差不多了,多做一個切換 PHP 版本,展現 sail 的厲害
自嗨的 check list:
ORM操作
資料庫觀念
N+1 是做關聯查詢的時候,先做一次查詢整個 model(1次 SQL 查詢),再逐步執行關聯查詢(N次 SQL 查詢)。
可以參考 Laravel 官網上 Eager Loading 的部分
官網上的範例是:
foreach (Book::all() as $book)
{
echo $book->author->name;
}
Book::all()
執行一次 SELECT * FROM book
$book->author->name
每一圈執行一次 SELECT name FROM author WHERE authors.book_id = (書本id)
因為程式不知道你查 Book 其實是想查 Author , 就一行一行執行(lazy loading)。
如果希望告訴程式第一次的查詢等下會用到,就要用 eager loading,可以用 with() 方法。
foreach (Book::with('author')->get() as $book)
{
echo $book->author->name;
}
Book::with('author')->get()
eager loading 知道你的 book 查詢是為了 author,就會把 author 的資料全倒出來,所以會幫你執行兩次 SQL:
select * from books
select * from authors where id in (1, 2, 3, 4, 5, ...)
總結
ORM 小心 N+1,解法要用 with
J:什麼時候用 eager loading,什麼時候用 join?
R:這個問題的本質是對 ORM 使用方式的問題。換個問題,如果用 Laravel ORM 要用 join 的方法,你會怎麼做?
$names = DB::table('books')
->join('authors', 'books.author_id', '=', 'authors.books_id')
->select('authors.name')
->get();
J:應該是這樣吧
R:你什麼時候會純用 ORM 什麼時候會願意參雜一些 query builder
J:orm 查不到。 只好用 query builder
結論
看了些討論,好像是說,如果比較重視可讀跟方便就用 orm,但本身熟悉 SQL 比較在意高效能可以用 query builder。
但用 orm,最基本常識就是不要寫出 n+1。
- If you are more aware of efficiency rather than ease of development, go for query builder.
- If you dealing with one entity go for ORM, (Eloquent).
- If you dealing with multiple entities it’s better to deal with query builder.
- If you are new to mysql or your application is not very complex, definitely choose ORM.
- If you need more complex query, I recommend to use query builder.
建議把 query Log 印出來
R:懷疑可能出現類似的效能問題 就把 query 印出來檢查確認 看有沒有特別多或者特別慢的 實際練習一下 印一次就會了
第一正規是單元值
第二正規是所有欄位要與主建相依
第三正規是與主建相依,欄位間不能相依
新手會名詞解釋和寫語法就好
名詞解釋:
語法:
transaction:
一串 SQL 可以組成交易,這一串都成功就 commit,中間有失敗 就 rollback。
laravel 可以用 try-catch 包住 beginTransaction() ,用 commit() / roallback() 來做
try {
DB::beginTransaction();
$member = member::create([]);
// $member->id 會是 null,因為 transaction 被卡住了
$memberData = new MemberDate();
$listUpdateLog->member_id = $member->id;
$listUpdateLog->save();
DB::commit();
} catch (\Exception $e) {
DB::rollback();
}
ACID,是指資料庫管理系統(DBMS)在寫入或更新資料的過程中,為保證事務(transaction)是正確可靠的,所必須具備的四個特性:原子性(atomicity,或稱不可分割性)、一致性(consistency)、隔離性(isolation,又稱獨立性)、持久性(durability)。
該怎麼記得這些東西,而不是背書,可以用想像一筆交易。
以為關聯式資料庫都支援 transaction,非關聯式資料庫都不支援。其實並不是,跟資料庫系統有關。ACID 也可以用來形容 NoSQL 的交易。
你可以討論 MongoDB 支援不支援 符合 ACID 特性的 transaction
如果不支援 那麼你可能不會用它做金流系統
如果資料庫的程式 你 rollback 完 有機會沒有完全恢復到交易前的狀況 那你怎麼寫還是沒法保證原子性 重點是他的 rollback 怎麼做
J:怎麼覺得 我只要知道有 begin transaction, commit, rollback,其他的都是資料庫設定
R:對呀 但是你要知道資料庫的特性 才能選擇跟使用這些事情
A&C
跟 rollback 有關
isolation
跟 lock 有關
surability
跟資料庫有沒有支援復原有關
自嗨的 check list:
ORM操作
資料庫觀念
N+1 是做關聯查詢的時候,先做一次查詢整個 model(1次 SQL 查詢),再逐步執行關聯查詢(N次 SQL 查詢)。
可以參考 Laravel 官網上 Eager Loading 的部分
官網上的範例是:
foreach (Book::all() as $book)
{
echo $book->author->name;
}
Book::all()
執行一次 SELECT * FROM book
$book->author->name
每一圈執行一次 SELECT name FROM author WHERE authors.book_id = (書本id)
因為程式不知道你查 Book 其實是想查 Author , 就一行一行執行(lazy loading)。
如果希望告訴程式第一次的查詢等下會用到,就要用 eager loading,可以用 with() 方法。
foreach (Book::with('author')->get() as $book)
{
echo $book->author->name;
}
Book::with('author')->get()
eager loading 知道你的 book 查詢是為了 author,就會把 author 的資料全倒出來,所以會幫你執行兩次 SQL:
select * from books
select * from authors where id in (1, 2, 3, 4, 5, ...)
總結
ORM 小心 N+1,解法要用 with
J:什麼時候用 eager loading,什麼時候用 join?
R:這個問題的本質是對 ORM 使用方式的問題。換個問題,如果用 Laravel ORM 要用 join 的方法,你會怎麼做?
$names = DB::table('books')
->join('authors', 'books.author_id', '=', 'authors.books_id')
->select('authors.name')
->get();
J:應該是這樣吧
R:你什麼時候會純用 ORM 什麼時候會願意參雜一些 query builder
J:orm 查不到。 只好用 query builder
結論
看了些討論,好像是說,如果比較重視可讀跟方便就用 orm,但本身熟悉 SQL 比較在意高效能可以用 query builder。
但用 orm,最基本常識就是不要寫出 n+1。
- If you are more aware of efficiency rather than ease of development, go for query builder.
- If you dealing with one entity go for ORM, (Eloquent).
- If you dealing with multiple entities it’s better to deal with query builder.
- If you are new to mysql or your application is not very complex, definitely choose ORM.
- If you need more complex query, I recommend to use query builder.
建議把 query Log 印出來
R:懷疑可能出現類似的效能問題 就把 query 印出來檢查確認 看有沒有特別多或者特別慢的 實際練習一下 印一次就會了
第一正規是單元值
第二正規是所有欄位要與主建相依
第三正規是與主建相依,欄位間不能相依
新手會名詞解釋和寫語法就好
名詞解釋:
語法:
transaction:
一串 SQL 可以組成交易,這一串都成功就 commit,中間有失敗 就 rollback。
laravel 可以用 try-catch 包住 beginTransaction() ,用 commit() / roallback() 來做
try {
DB::beginTransaction();
$member = member::create([]);
// $member->id 會是 null,因為 transaction 被卡住了
$memberData = new MemberDate();
$listUpdateLog->member_id = $member->id;
$listUpdateLog->save();
DB::commit();
} catch (\Exception $e) {
DB::rollback();
}
ACID,是指資料庫管理系統(DBMS)在寫入或更新資料的過程中,為保證事務(transaction)是正確可靠的,所必須具備的四個特性:原子性(atomicity,或稱不可分割性)、一致性(consistency)、隔離性(isolation,又稱獨立性)、持久性(durability)。
該怎麼記得這些東西,而不是背書,可以用想像一筆交易。
以為關聯式資料庫都支援 transaction,非關聯式資料庫都不支援。其實並不是,跟資料庫系統有關。ACID 也可以用來形容 NoSQL 的交易。
你可以討論 MongoDB 支援不支援 符合 ACID 特性的 transaction
如果不支援 那麼你可能不會用它做金流系統
如果資料庫的程式 你 rollback 完 有機會沒有完全恢復到交易前的狀況 那你怎麼寫還是沒法保證原子性 重點是他的 rollback 怎麼做
J:怎麼覺得 我只要知道有 begin transaction, commit, rollback,其他的都是資料庫設定
R:對呀 但是你要知道資料庫的特性 才能選擇跟使用這些事情
A&C
跟 rollback 有關
isolation
跟 lock 有關
surability
跟資料庫有沒有支援復原有關
前 Google 工程師/創業者 Andy 的建議
The MentorShip 曼陀號領航計畫 技術組第一次月會 心得筆記
第一次的月會,Andy 分享了 SWE Ladder 的概念,提醒我們不要太在意任何一間的職位 Ladder,應該專注在自己的技能 Ladder。
所謂 Tech Lead 往往是大家最不想做的(屎缺),或團隊裡沒有人能做的事情。但也不要因為被公司「升」到 Tech Lead 而灰心,建議是勇敢接受挑戰,讓這個經驗成為下一階段的養分。
比別人快速成長的方法,來自 Andy 的觀察與自身經驗:
不要急著排解掉問題,養成每次多花五到十分鐘多閱讀一點的習慣。
為什麼 1% 是那特別的 1%?
誰決定你的升職?
你有第一名的經驗嗎?
時間花在那裡,成就就會在哪裡。
知道自己的目標,才能規畫地圖。
可以用長期/中期/短期(三年)來規劃自己的人生目標(個人發展計畫 IDP):
可以用十年/五年/三年來做分段,但最短建議是三年。因為三年才會是累積出東西的一個時間點,此外 IDP 也不應該一直變動,如果只有一年很容易更改。
IDP 是可以修改的,未來發生什麼事情誰也不知道。要常常想到自己的人生規劃,是否目標改變了,修改的過程也是在跟自己溝通。
]]>前 Google 工程師/創業者 Andy 的建議
The MentorShip 曼陀號領航計畫 技術組第一次月會 心得筆記
第一次的月會,Andy 分享了 SWE Ladder 的概念,提醒我們不要太在意任何一間的職位 Ladder,應該專注在自己的技能 Ladder。
所謂 Tech Lead 往往是大家最不想做的(屎缺),或團隊裡沒有人能做的事情。但也不要因為被公司「升」到 Tech Lead 而灰心,建議是勇敢接受挑戰,讓這個經驗成為下一階段的養分。
比別人快速成長的方法,來自 Andy 的觀察與自身經驗:
不要急著排解掉問題,養成每次多花五到十分鐘多閱讀一點的習慣。
為什麼 1% 是那特別的 1%?
誰決定你的升職?
你有第一名的經驗嗎?
時間花在那裡,成就就會在哪裡。
知道自己的目標,才能規畫地圖。
可以用長期/中期/短期(三年)來規劃自己的人生目標(個人發展計畫 IDP):
可以用十年/五年/三年來做分段,但最短建議是三年。因為三年才會是累積出東西的一個時間點,此外 IDP 也不應該一直變動,如果只有一年很容易更改。
IDP 是可以修改的,未來發生什麼事情誰也不知道。要常常想到自己的人生規劃,是否目標改變了,修改的過程也是在跟自己溝通。
]]>2021/5/15
賺 10% 跑,賠 30% 腳麻不止損,目標設定錯誤長久下來當然賺小虧大。
]]>2021/5/15
賺 10% 跑,賠 30% 腳麻不止損,目標設定錯誤長久下來當然賺小虧大。
]]>大概知道有 OSI 七層架構和 TCP/IP 架構。
TCP 負責切割封包, IP 確認封包被傳送到正確位置。
TCP/IP 架構
(我對網路傳送的想像是一堆0101訊號在空中/電線裡飛舞)
TCP/IP 上的一種連線協議。
當發送 HTTP 協議的請求被伺服器端的軟體接收時,先透過透過三次握手、四次揮手建立連線。
再以及透過 HTTP 動詞來處理請求。
HTTP 請求會寫發送請求的 URL, 動詞, 接受的回應格式等
符合 W3C 標準的瀏覽器可以解析檔案的內容。
裡面跟畫面相關的定義應該是 HTML, CSS, SVG...
產生畫面的過程是解析 HTML 產生 DOM Tree,解析 CSS 產生 CSSOM Tree。
將 CSSOM 掛上去 DOM,然後做版面配置,最後 paiting。
DNS domain name system 是解析網址的系統,透過這個系統可以解析 domain name 變成 IP 位置。
因為電腦認識的是數字IP,人類記憶是英文網址,所以需要一個東西來記錄這兩個東西的對應關係。
早期網址不多可以用一個 host file 解決網址對應問題,當數量變多就需要一個系統。
從瀏覽器發送首先是會經過自己的 hosts 檔案。像是 localhost 或自己在 hosts 檔案裡設定的域名。
hosts 檔案找不到對應 IP 就會去找最近的 DNS 伺服器。
像是內網,公司的本地 DNS。
再來是地區 ISP 業者的 DNS,像是中華電信。
就這樣,如果查 domain name 查不到就會往上一級的 DNS 詢問。
(但還是不太清楚細節...)
domain name(英文) 就是 IP(數字) 比較好被記憶的方式。
例如 jing.com = 123.123.123.123
域名的語法是 子域名.頂級域名
頂級域名是用來分類的,跟前面 DNS 運作有關, jing.com 最上層的 DNS 伺服器就是 .com。
代管就是不要自己架主機管理。
DNS hosting (無概念,剛剛查的)
前面提過要讓購買的域名對應上 IP,要讓別人能用 DSN 查到。這時候就面臨要自架或是代管服務。
自架好像要去跟 ISP 業者登記(查鳥哥的網站,太複雜了先跳過)。
代管就是買網址的時候都會免費提供的服務,反正有個地方可以設定,設定完就會幫我通知全球的 DNS 說。(半知半解)
之前稍稍有在研究主機代管,起因是想架 wordpress,研究了一下才發現原來以前用的是 shared hosting,還有 VPS。
一堆廠商,看得頭昏眼花。
W3C 標準的文字結構標記語言。
讓瀏覽器該可以解析網頁檔案,例如超聯結,圖片影片資源,文字等等。
W3C 標準用來幫 HTML, XML 添加樣式美化的語言。
一種腳本語言。
發明時是希望讓網頁可以有動態效果,JS 可以被埋近 HTML 裡面,使用支援 JS 的瀏覽器就能執行 JS tag。
JS 壯大後有了規範(ECMAScript),也被納入 W3C 標準成為主流瀏覽器的支援語言。
大概知道有 OSI 七層架構和 TCP/IP 架構。
TCP 負責切割封包, IP 確認封包被傳送到正確位置。
TCP/IP 架構
(我對網路傳送的想像是一堆0101訊號在空中/電線裡飛舞)
TCP/IP 上的一種連線協議。
當發送 HTTP 協議的請求被伺服器端的軟體接收時,先透過透過三次握手、四次揮手建立連線。
再以及透過 HTTP 動詞來處理請求。
HTTP 請求會寫發送請求的 URL, 動詞, 接受的回應格式等
符合 W3C 標準的瀏覽器可以解析檔案的內容。
裡面跟畫面相關的定義應該是 HTML, CSS, SVG...
產生畫面的過程是解析 HTML 產生 DOM Tree,解析 CSS 產生 CSSOM Tree。
將 CSSOM 掛上去 DOM,然後做版面配置,最後 paiting。
DNS domain name system 是解析網址的系統,透過這個系統可以解析 domain name 變成 IP 位置。
因為電腦認識的是數字IP,人類記憶是英文網址,所以需要一個東西來記錄這兩個東西的對應關係。
早期網址不多可以用一個 host file 解決網址對應問題,當數量變多就需要一個系統。
從瀏覽器發送首先是會經過自己的 hosts 檔案。像是 localhost 或自己在 hosts 檔案裡設定的域名。
hosts 檔案找不到對應 IP 就會去找最近的 DNS 伺服器。
像是內網,公司的本地 DNS。
再來是地區 ISP 業者的 DNS,像是中華電信。
就這樣,如果查 domain name 查不到就會往上一級的 DNS 詢問。
(但還是不太清楚細節...)
domain name(英文) 就是 IP(數字) 比較好被記憶的方式。
例如 jing.com = 123.123.123.123
域名的語法是 子域名.頂級域名
頂級域名是用來分類的,跟前面 DNS 運作有關, jing.com 最上層的 DNS 伺服器就是 .com。
代管就是不要自己架主機管理。
DNS hosting (無概念,剛剛查的)
前面提過要讓購買的域名對應上 IP,要讓別人能用 DSN 查到。這時候就面臨要自架或是代管服務。
自架好像要去跟 ISP 業者登記(查鳥哥的網站,太複雜了先跳過)。
代管就是買網址的時候都會免費提供的服務,反正有個地方可以設定,設定完就會幫我通知全球的 DNS 說。(半知半解)
之前稍稍有在研究主機代管,起因是想架 wordpress,研究了一下才發現原來以前用的是 shared hosting,還有 VPS。
一堆廠商,看得頭昏眼花。
W3C 標準的文字結構標記語言。
讓瀏覽器該可以解析網頁檔案,例如超聯結,圖片影片資源,文字等等。
W3C 標準用來幫 HTML, XML 添加樣式美化的語言。
一種腳本語言。
發明時是希望讓網頁可以有動態效果,JS 可以被埋近 HTML 裡面,使用支援 JS 的瀏覽器就能執行 JS tag。
JS 壯大後有了規範(ECMAScript),也被納入 W3C 標準成為主流瀏覽器的支援語言。
@江湖人稱 S 姐 很精彩的分享,可以參考一下
Digital Skills/ Business Skills
Agile
Communication Skills
先比職位,再比產業,再比國家,比較不會眼高手低。
不要羨慕創業者的薪資,因為不見得是你想的。
你所待的產業,職位決定你的薪資天花板。
1.薪資
2.如何選擇
3.履歷
4.面試
5.跟對人
企業買你 = 專業 + 軟實力
現在的薪水 + 13.8 %
期望薪資 = 工作內容/整體福利/工時/產品趨勢/可存活多久
如果想透過獵頭篩選公司,可以把真正在意的離職原因告知
建議塊陶
可以的話從非一般求職管道還是最好
定義自己認知的 40 小時
一個人在工作的時間頂多五小時,一定有聊天/團購時間
判斷適合自己的公司
面試可以判斷的:
思考下一季要把時間專注度放在哪三件事
職場如果沒有目標,去哪都一樣
Q: 30 歲後轉職會困難嗎?
A: 不會,28-38 是超級黃金時期,好好打拼,跨職能、title、經驗。45 歲後還在求職才困難。
Q: 設計業慘嗎?
A: 設計的趨勢:web design 落伍,加深自己的技能,如果往 UIUX 方向,會寫一點 code 薪水很棒。很好接案,要了解自己的設計風格。
Q: 念在職專班?
A: No,請加強專業。
後記:
聽完講座後去找了他的 Youtube,看到 斜槓筆記本,激推。
如同 S 姐不斷說的「重要的是人生規劃」,這本筆記就是精練出他認為人生規劃裡重要的事,例如認識自己(興趣、專長)、心智圖設定目標、時間分配、金錢管理、建立人脈等等。
通常列出一堆年/月計畫,甚至一次列出三五年 IDP,這麼多事情要做、要規劃,想必是列出來之後就開始發散。所以 S 姐也規劃了心智圖的章節,提醒你要專注在時間內能關注的範圍內(或想辦法把這些東西圈成一件事)。
真的很讚,完全就是可以出成一本書的質量,但老實說市面上這種書,看過一次就不會想看,看完可能也沒有真的照著做。S 姐選擇做成筆記本工具 + 拍影片,真的是滿佛的。
@江湖人稱 S 姐 很精彩的分享,可以參考一下
Digital Skills/ Business Skills
Agile
Communication Skills
先比職位,再比產業,再比國家,比較不會眼高手低。
不要羨慕創業者的薪資,因為不見得是你想的。
你所待的產業,職位決定你的薪資天花板。
1.薪資
2.如何選擇
3.履歷
4.面試
5.跟對人
企業買你 = 專業 + 軟實力
現在的薪水 + 13.8 %
期望薪資 = 工作內容/整體福利/工時/產品趨勢/可存活多久
如果想透過獵頭篩選公司,可以把真正在意的離職原因告知
建議塊陶
可以的話從非一般求職管道還是最好
定義自己認知的 40 小時
一個人在工作的時間頂多五小時,一定有聊天/團購時間
判斷適合自己的公司
面試可以判斷的:
思考下一季要把時間專注度放在哪三件事
職場如果沒有目標,去哪都一樣
Q: 30 歲後轉職會困難嗎?
A: 不會,28-38 是超級黃金時期,好好打拼,跨職能、title、經驗。45 歲後還在求職才困難。
Q: 設計業慘嗎?
A: 設計的趨勢:web design 落伍,加深自己的技能,如果往 UIUX 方向,會寫一點 code 薪水很棒。很好接案,要了解自己的設計風格。
Q: 念在職專班?
A: No,請加強專業。
後記:
聽完講座後去找了他的 Youtube,看到 斜槓筆記本,激推。
如同 S 姐不斷說的「重要的是人生規劃」,這本筆記就是精練出他認為人生規劃裡重要的事,例如認識自己(興趣、專長)、心智圖設定目標、時間分配、金錢管理、建立人脈等等。
通常列出一堆年/月計畫,甚至一次列出三五年 IDP,這麼多事情要做、要規劃,想必是列出來之後就開始發散。所以 S 姐也規劃了心智圖的章節,提醒你要專注在時間內能關注的範圍內(或想辦法把這些東西圈成一件事)。
真的很讚,完全就是可以出成一本書的質量,但老實說市面上這種書,看過一次就不會想看,看完可能也沒有真的照著做。S 姐選擇做成筆記本工具 + 拍影片,真的是滿佛的。
起源
最初應該是看到大學的一位學姊在 Facebook 推薦這個活動,看起來還不錯就按了追蹤。
動機
想要在軟體開發領域更上一層樓:希望能透過社群提升技術與開拓眼界。
從二月底開放報名表單到截止大約有兩周,題目會列在文末,跟去年一樣。我有拍一小段自我介紹影片(就用手機自拍一小段對鏡頭講話的影片而已),聽說是今年才增加的。
原本覺得題目很多很麻煩想放棄報名,後來受到同事鼓勵才認真重寫,也找了學姊幫我看過,真的很謝謝他們的幫忙 >"<
據說今年是 500+ 人報名, 最後約 78 人錄取。
開幕式地點在 CC work 建北館,離捷運有一段距離。
當天有提供飲料,紅茶滿好喝的 ^_^
前半場是致辭,後半場是小組交流。
圍成一圈,自由向船長交流,之後由引水人丟一些破冰問題,印象中有:自我介紹、哪一種動物像自己、期待之後的月會可以聽到什麼。這個環節結束後再分成三組,跟三位引水人隨意交流。
我們的船長 Andy 分享了 Google 的求職與創業經驗。
自我介紹滿有趣的一點是在場的有好像有 3 位都提到潛水,導致後來大家自介都要提一下我會潛水/我不會潛水 XD
順帶一提,自介部分感受到了一些不作為的焦慮能量,don't do that,感覺好討厭 XD 多來點努力與積極上進能量分享吧!
整體而言,對後續的活動滿期待的。可以感受到參與的許多位學員都對於自己的職涯相當積極與負責。例如持續參與社群、或是分享自己如何進修,都讓人相當欣賞,希望之後可以多跟他們交流 >"<
--
都已經錄取了就講實話...開幕式還要海選這個流程我覺得滿沒意義的。
我不覺得海選可以看出熱於分享與求知的潛力。開開心心來交流,但時不時想到正在被觀察感覺很差。
ps 公告說每組最多 10 位水手,3 位航海士。當天稍微看了一下椅子,其實水手區椅子也只有排十張,但我沒有注意到是不是每一組都是這樣。
另外,聽說技術開發組報名的人很少。
報名表問題
起源
最初應該是看到大學的一位學姊在 Facebook 推薦這個活動,看起來還不錯就按了追蹤。
動機
想要在軟體開發領域更上一層樓:希望能透過社群提升技術與開拓眼界。
從二月底開放報名表單到截止大約有兩周,題目會列在文末,跟去年一樣。我有拍一小段自我介紹影片(就用手機自拍一小段對鏡頭講話的影片而已),聽說是今年才增加的。
原本覺得題目很多很麻煩想放棄報名,後來受到同事鼓勵才認真重寫,也找了學姊幫我看過,真的很謝謝他們的幫忙 >"<
據說今年是 500+ 人報名, 最後約 78 人錄取。
開幕式地點在 CC work 建北館,離捷運有一段距離。
當天有提供飲料,紅茶滿好喝的 ^_^
前半場是致辭,後半場是小組交流。
圍成一圈,自由向船長交流,之後由引水人丟一些破冰問題,印象中有:自我介紹、哪一種動物像自己、期待之後的月會可以聽到什麼。這個環節結束後再分成三組,跟三位引水人隨意交流。
我們的船長 Andy 分享了 Google 的求職與創業經驗。
自我介紹滿有趣的一點是在場的有好像有 3 位都提到潛水,導致後來大家自介都要提一下我會潛水/我不會潛水 XD
順帶一提,自介部分感受到了一些不作為的焦慮能量,don't do that,感覺好討厭 XD 多來點努力與積極上進能量分享吧!
整體而言,對後續的活動滿期待的。可以感受到參與的許多位學員都對於自己的職涯相當積極與負責。例如持續參與社群、或是分享自己如何進修,都讓人相當欣賞,希望之後可以多跟他們交流 >"<
--
都已經錄取了就講實話...開幕式還要海選這個流程我覺得滿沒意義的。
我不覺得海選可以看出熱於分享與求知的潛力。開開心心來交流,但時不時想到正在被觀察感覺很差。
ps 公告說每組最多 10 位水手,3 位航海士。當天稍微看了一下椅子,其實水手區椅子也只有排十張,但我沒有注意到是不是每一組都是這樣。
另外,聽說技術開發組報名的人很少。
報名表問題
本文會提到
名詞:
物件實字 object literal
{ }
建構式
function() {}
// Object initialiser or literal
{ [ nameValuePair1[, nameValuePair2[, ...nameValuePairN] ] ] }
// Called as a constructor
new Object([value])
Object.create()
Object.create()
指定其原型物件與屬性,創建一個新物件。
語法 Object.create(proto[, propertiesObject])
var o;
// 建立以null為原型的物件
o = Object.create(null);
o = {};
// 等同於:
o = Object.create(Object.prototype);
function heroCreator (name, act) {
const hero = {} //物件實字宣告方法
hero.name = name
hero.act = act
hero.attack = function () { console..log( `${this.name} 使用 ${this.act} 攻擊` ) }
return h
}
const pika = heroCreator('皮卡丘', '十萬伏特')
pika.attack()
現在想要改成共用方法 attack,不要直接寫進 creator
function heroCreator (name, act) {
const hero = {} //物件實字宣告方法
hero.name = name
hero.act = act
// hero.attack = function () { console..log( `${this.name} 使用 ${this.act} 攻擊` ) }
// 抽出來
return h
}
function attack (act) {
console..log( `${this.name} 使用 ${this.act} 攻擊`
}
const pika = heroCreator('皮卡丘', '十萬伏特')
pika.attack = attack
pika.attack()
const actions = {
atk: function () { console..log(${this.name} 使用攻擊`) }
def: function () { console..log(${this.name} 防禦`) }
}
function heroCreator(name) {
//const h = {}
const h = Object.create(actions)
h.name = name
h.act = act // act not defined
retrun h
}
用繼承的方式而不是直接寫進 creator,避免我忘記傳進 act
proto 所有的物件都有這個屬性
當在這個物件裡找不到某個屬性時,會去找物件的 proto 去尋找原型,一直到 null
const h1 = heroCreator('pika')
console.log(h1.__proto__) // 原型是 actions
JS 的標準內建物件
1.__proto__
Uncaught SyntaxError: Invalid or unexpected token
let a = 1
a.__proto__
Number {0, constructor: ƒ, toExponential: ƒ, toFixed: ƒ, toPrecision: ƒ, …}
//自動 boxing 成 Number
heroObj.create(actions)
等於
heroObj.__proto__ = actions
// 不要這樣做
誰呼叫,誰實 this
fun a () {
fun b() {}
b() //caller is global, this is window, 跟執行堆疊無關
}
fun heroFactory(name,act) {
this.name = name //this = global
}
fun heroFactory(name,act) {
var a = b = 2 // b=2 會被提升到 global 宣告一個 var b;
log(a) //2
lob(b) //2
}
log(a) //not defined
lob(b) //2 b 已經被拉到全域宣告
改變 this 的指向
const h3 = new heroFactory('h3','run') // new 會幫忙做兩件事 1. this 指向 action 2. retrun this
const h4 = heroFactory('h4','fly') // retrun undefined
new hF() 裡
retrun 原始型別會被無視, return 複雜型別才可以
new
創出一個新的 object,我們叫它 O
把 O 的 proto 指向 "原型" 的 prototype,才能繼承原型鍊
拿 O 當作 context,呼叫 Person 這個建構函式
回傳 O
function 是物件
func a() {
log(this.age) //this == global this.name == undefined
}
a.age = 18
proto 是指向原型的 prototype 的一個屬性
fn.prototype 預設是空物件
物件原型
可以用不同方式 建構式 物件實字 定義
instance 的 proto 會指向他的原型,自定義的物件的 proto 會指向 function
Person.prototype:
instance 的屬性,所有的物件實例都會有這個屬性
proto 指向 prototype
============================
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Object/create
[教學] 深入淺出 JavaScript ES6 Class (類別)
Javascripter 必須知道的繼承 prototype, [[prototype]], proto
JS基本觀念: 原型鏈(prototype chain)
該來理解 JavaScript 的原型鍊了
你懂 JavaScript 嗎?#19 原型(Prototype)
js中proto和prototype的区别和关系?
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript
[[Prototype]] javascript proto
javascript interview question "this"
jQuery source code
IFEE
contentful
not definded & undefined
hello()
Uncaught ReferenceError: hello is not defined
ReferenceError 沒有宣告過
let b = {} // 創造一個物件 b (用物件實字 or 建構式)
b.hello()
Uncaught TypeError: Cannot read property 'hello' is not a function
注意: 不是印出 undefuned ,而是 TypeError is not a function
如果改成 b.hello 就是 undefuned
undefined 怎麼出來的 => 原型鍊上找不到
b.protop 順著鍊上找到最後是 null,所以回傳 undefined
new
hero = new Hero()
prototype vs proto
RECAP
fn.prototype 建構
fn.proto 指向原型
本文會提到
名詞:
物件實字 object literal
{ }
建構式
function() {}
// Object initialiser or literal
{ [ nameValuePair1[, nameValuePair2[, ...nameValuePairN] ] ] }
// Called as a constructor
new Object([value])
Object.create()
Object.create()
指定其原型物件與屬性,創建一個新物件。
語法 Object.create(proto[, propertiesObject])
var o;
// 建立以null為原型的物件
o = Object.create(null);
o = {};
// 等同於:
o = Object.create(Object.prototype);
function heroCreator (name, act) {
const hero = {} //物件實字宣告方法
hero.name = name
hero.act = act
hero.attack = function () { console..log( `${this.name} 使用 ${this.act} 攻擊` ) }
return h
}
const pika = heroCreator('皮卡丘', '十萬伏特')
pika.attack()
現在想要改成共用方法 attack,不要直接寫進 creator
function heroCreator (name, act) {
const hero = {} //物件實字宣告方法
hero.name = name
hero.act = act
// hero.attack = function () { console..log( `${this.name} 使用 ${this.act} 攻擊` ) }
// 抽出來
return h
}
function attack (act) {
console..log( `${this.name} 使用 ${this.act} 攻擊`
}
const pika = heroCreator('皮卡丘', '十萬伏特')
pika.attack = attack
pika.attack()
const actions = {
atk: function () { console..log(${this.name} 使用攻擊`) }
def: function () { console..log(${this.name} 防禦`) }
}
function heroCreator(name) {
//const h = {}
const h = Object.create(actions)
h.name = name
h.act = act // act not defined
retrun h
}
用繼承的方式而不是直接寫進 creator,避免我忘記傳進 act
proto 所有的物件都有這個屬性
當在這個物件裡找不到某個屬性時,會去找物件的 proto 去尋找原型,一直到 null
const h1 = heroCreator('pika')
console.log(h1.__proto__) // 原型是 actions
JS 的標準內建物件
1.__proto__
Uncaught SyntaxError: Invalid or unexpected token
let a = 1
a.__proto__
Number {0, constructor: ƒ, toExponential: ƒ, toFixed: ƒ, toPrecision: ƒ, …}
//自動 boxing 成 Number
heroObj.create(actions)
等於
heroObj.__proto__ = actions
// 不要這樣做
誰呼叫,誰實 this
fun a () {
fun b() {}
b() //caller is global, this is window, 跟執行堆疊無關
}
fun heroFactory(name,act) {
this.name = name //this = global
}
fun heroFactory(name,act) {
var a = b = 2 // b=2 會被提升到 global 宣告一個 var b;
log(a) //2
lob(b) //2
}
log(a) //not defined
lob(b) //2 b 已經被拉到全域宣告
改變 this 的指向
const h3 = new heroFactory('h3','run') // new 會幫忙做兩件事 1. this 指向 action 2. retrun this
const h4 = heroFactory('h4','fly') // retrun undefined
new hF() 裡
retrun 原始型別會被無視, return 複雜型別才可以
new
創出一個新的 object,我們叫它 O
把 O 的 proto 指向 "原型" 的 prototype,才能繼承原型鍊
拿 O 當作 context,呼叫 Person 這個建構函式
回傳 O
function 是物件
func a() {
log(this.age) //this == global this.name == undefined
}
a.age = 18
proto 是指向原型的 prototype 的一個屬性
fn.prototype 預設是空物件
物件原型
可以用不同方式 建構式 物件實字 定義
instance 的 proto 會指向他的原型,自定義的物件的 proto 會指向 function
Person.prototype:
instance 的屬性,所有的物件實例都會有這個屬性
proto 指向 prototype
============================
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Object/create
[教學] 深入淺出 JavaScript ES6 Class (類別)
Javascripter 必須知道的繼承 prototype, [[prototype]], proto
JS基本觀念: 原型鏈(prototype chain)
該來理解 JavaScript 的原型鍊了
你懂 JavaScript 嗎?#19 原型(Prototype)
js中proto和prototype的区别和关系?
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript
[[Prototype]] javascript proto
javascript interview question "this"
jQuery source code
IFEE
contentful
not definded & undefined
hello()
Uncaught ReferenceError: hello is not defined
ReferenceError 沒有宣告過
let b = {} // 創造一個物件 b (用物件實字 or 建構式)
b.hello()
Uncaught TypeError: Cannot read property 'hello' is not a function
注意: 不是印出 undefuned ,而是 TypeError is not a function
如果改成 b.hello 就是 undefuned
undefined 怎麼出來的 => 原型鍊上找不到
b.protop 順著鍊上找到最後是 null,所以回傳 undefined
new
hero = new Hero()
prototype vs proto
RECAP
fn.prototype 建構
fn.proto 指向原型
有鑑於,被朋友問到講得哩哩落落,寫個小 memo 給自己
本文著重在比較 Java class-based 與 JavaScript protoytpe-based
OOP(物件導向程式)是什麼?
OOP = Object-oriented programming = 物件導向程式設計,是一種以物件設計程式設計的設計方法。
希望可以透過三大特性:繼承、封裝、多型,讓程式碼減少重複代碼並彈性地擴充,以及能零活調用組裝 。
遵守OOP開發原則(SOLID) 也能寫出更好維護的軟體。
本文以繼承特性為討論物件導向的範圍。
Java 是靜態(編譯)、強型別語言
學習 Java 的基礎:
在 Java 中的物件必須先定義出 Class 才能夠創造出物件,而程式的運作需要透過 Object (Class Instance)。
從 Hello World 的範例裡看到,一行 print 指令需要被寫在一個 HelloWorld Class 檔案裡,編譯後執行。
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello! World!");
}
}
Java 透過 new 與 extends 關鍵字來做到類別實例與繼承,Object Class 是所有的 Class 共同繼承的源頭。
// Class
public class Hero extends GameObject{
public String name;
public Hero(String name) {
this.name = name;
}
}
// Object
Hero heroAria = new Hero(Aria);
Hero heroBrant = new Hero(Brant);
我們已經為所有的 Hero 類別都定義了 name 屬性,如果之後想要修改所有物件的 name 屬性,例如加上 HERO 在名字前,就不需要一一修改。
這裡繼承的對象 class,沒有談到實體化的物件。
JavaScript 是動態(直譯/腳本)、弱型別語言
JavaScript 支援 OOP,也支援 FP(Functional Programming)
JavaScript 中則是使用 Prototype(原型)為基礎設計。
OOP 是一種設計典範,通常用於開發系統軟體。
因此,JavaScript、Python 這樣的腳本語言,OOP 的概念不是入門學習時首要的學習目標,許多教材會將 OOP 放在進階觀念裡。
回到繼承,JavaScript 是腳本語言,所以它並不用 Class 的方式實現繼承,而是透過原型鍊查找物件屬性。
講到繼承,JavaScript 就只有一個建構子:物件。每個物件都有一個連著其他原型(prototype)的私有屬性(private property)物件。原型物件也有著自己的原型,於是原型物件就這樣鏈結,直到撞見 null 為止:null 在定義裡沒有原型、也是原型鏈(prototype chain)的最後一個鏈結。
我從 Java 進入 JavaScript 在學習 prototype 的時候曾產生混亂,不明白為什麼用建構式定義物件時使用 function 關鍵字、為什麼 new 一個函式會跑出物件。(因為我們定義的這個函式是個建構子)
傳統的 OOP 都是先定義了類別,接著在建立物件實例之後,在類型上定義的所有屬性與函式均複製到此實例。但 JavaScript 不會複製這些屬性與函式,卻是在物件實例與其建構子之間設定連結 (原型鍊中的連結),只要順著原型鍊就能在建構子之中找到屬性與函式。
MDN 物件原型
function f() {
return 2;
}
// 從 Function.prototype 繼承的函式,含有諸如 call、bind……之類的方法
// f ---> Function.prototype ---> Object.prototype ---> null
function Graph() {
this.vertices = [];
this.edges = [];
}
Graph.prototype = {
addVertex: function(v) {
this.vertices.push(v);
}
};
var g = new Graph();
// g 是個有著「vertices」與「edges」屬性的物件。
// 在執行 new Graph() 時 g.[[Prototype]] 是 Graph.prototype 的值。
累了,寫到這裡好了。
有誤歡迎糾正。
有鑑於,被朋友問到講得哩哩落落,寫個小 memo 給自己
本文著重在比較 Java class-based 與 JavaScript protoytpe-based
OOP(物件導向程式)是什麼?
OOP = Object-oriented programming = 物件導向程式設計,是一種以物件設計程式設計的設計方法。
希望可以透過三大特性:繼承、封裝、多型,讓程式碼減少重複代碼並彈性地擴充,以及能零活調用組裝 。
遵守OOP開發原則(SOLID) 也能寫出更好維護的軟體。
本文以繼承特性為討論物件導向的範圍。
Java 是靜態(編譯)、強型別語言
學習 Java 的基礎:
在 Java 中的物件必須先定義出 Class 才能夠創造出物件,而程式的運作需要透過 Object (Class Instance)。
從 Hello World 的範例裡看到,一行 print 指令需要被寫在一個 HelloWorld Class 檔案裡,編譯後執行。
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello! World!");
}
}
Java 透過 new 與 extends 關鍵字來做到類別實例與繼承,Object Class 是所有的 Class 共同繼承的源頭。
// Class
public class Hero extends GameObject{
public String name;
public Hero(String name) {
this.name = name;
}
}
// Object
Hero heroAria = new Hero(Aria);
Hero heroBrant = new Hero(Brant);
我們已經為所有的 Hero 類別都定義了 name 屬性,如果之後想要修改所有物件的 name 屬性,例如加上 HERO 在名字前,就不需要一一修改。
這裡繼承的對象 class,沒有談到實體化的物件。
JavaScript 是動態(直譯/腳本)、弱型別語言
JavaScript 支援 OOP,也支援 FP(Functional Programming)
JavaScript 中則是使用 Prototype(原型)為基礎設計。
OOP 是一種設計典範,通常用於開發系統軟體。
因此,JavaScript、Python 這樣的腳本語言,OOP 的概念不是入門學習時首要的學習目標,許多教材會將 OOP 放在進階觀念裡。
回到繼承,JavaScript 是腳本語言,所以它並不用 Class 的方式實現繼承,而是透過原型鍊查找物件屬性。
講到繼承,JavaScript 就只有一個建構子:物件。每個物件都有一個連著其他原型(prototype)的私有屬性(private property)物件。原型物件也有著自己的原型,於是原型物件就這樣鏈結,直到撞見 null 為止:null 在定義裡沒有原型、也是原型鏈(prototype chain)的最後一個鏈結。
我從 Java 進入 JavaScript 在學習 prototype 的時候曾產生混亂,不明白為什麼用建構式定義物件時使用 function 關鍵字、為什麼 new 一個函式會跑出物件。(因為我們定義的這個函式是個建構子)
傳統的 OOP 都是先定義了類別,接著在建立物件實例之後,在類型上定義的所有屬性與函式均複製到此實例。但 JavaScript 不會複製這些屬性與函式,卻是在物件實例與其建構子之間設定連結 (原型鍊中的連結),只要順著原型鍊就能在建構子之中找到屬性與函式。
MDN 物件原型
function f() {
return 2;
}
// 從 Function.prototype 繼承的函式,含有諸如 call、bind……之類的方法
// f ---> Function.prototype ---> Object.prototype ---> null
function Graph() {
this.vertices = [];
this.edges = [];
}
Graph.prototype = {
addVertex: function(v) {
this.vertices.push(v);
}
};
var g = new Graph();
// g 是個有著「vertices」與「edges」屬性的物件。
// 在執行 new Graph() 時 g.[[Prototype]] 是 Graph.prototype 的值。
累了,寫到這裡好了。
有誤歡迎糾正。
subtitle: Ken 與 FP 的旅程 ~ 2021-03-31
一直以來都是對 procedure programming 和 OOP 比較熟悉,粗略地知道 functional programming 的概念,也有使用這樣的程式設計法,但沒有再進一步了解,機緣下聽到了 Ken 的這場分享,以下是我聽完分享後的一些思考。
(pipe)
賣場上有三種折價券:98 折、95 折、92 折,沒有限制,可以同時使用。
如果用程式表達這三種折價券可以用三個函式:
const useCoupon98 = x => x*0.98;
const useCoupon95 = x => x*0.95;
const useCoupon92 = x => x*0.92;
如果用 procedure programming 描述我用三張折價券買了一本書:
let book = 400;
let result = useCoupon98(book)
result = useCoupon95(book)
result = useCoupon92(book)
好像也沒有不對,但在這個情境裡,也許用 functional 的方法思考會更符合情境。因為折扣卷並沒有一定要先使用哪一張,但這樣的寫法默默地寫下了執行順序。
如果使用 functional prgramming,似乎會好一點:
let book = 400;
let useCoupons = (a,b,c) => x => a(b(c(x))); //為方便使用固定三個參數,可以改成不定參數
let useCoupons(useCoupon98,useCoupon95,useCoupon92)(book)
雖然這個 useCoupons 並不完美,它裡面的實作依舊是按照順序呼叫,但這個函式已經成功將使用折價券的過程封裝起來,對使用者來說只知道它可以接收折價券當參數。
還記得剛開始學習函式時,學到使用函式可以減少重複的程式碼,讓程式碼更好維護。
另外,也能透過函式命名讓程式更好懂(封裝流程?)。
再來換個情境看看,現在要做一顆切換顏色的按鈕。
範例示範用原生 js 與一步一步將一顆按鈕掛進 container,與用 React hook 方法的差別
const container = document.getElementById('container')
const btn = document.createElement('button')
btn.className ="gray"
btn.onClick = function(e){
if(this.classList.conatins('gray')){
this.classList.remove('gray')
this.classList.add('red')
}else{
this.classList.remove('red')
this.classList.add('gray')
}
}
container.appendChild(btn)
如果用流程的方式思考:
如果有很多顆按鈕就不好維護這段判斷顏色的程式了,於是想把這段程式抽給函式也很合理:
const changeColor = (prevColor, activeColor) => {
if(this.classList.conatins(prevColor)){
this.classList.remove(prevColor)
this.classList.add(activeColor)
}else{
this.classList.remove(prevColor)
this.classList.add(activeColor)
}
}
順便再加個變數。
很基本,所有學到函式與變數的人都能輕鬆做到。
const container = document.getElementById('container')
const btn = document.createElement('button')
btn.className ="gray"
btn.onClick = function(e){
changeColor('gray','red')
}
container.appendChild(btn)
現在,可以來看看 React 在做的事,其實也就是把整個過程要用到的命令式寫法,都抽成函式。
const Container = (props) => {
const [color, setColor] = useState('gray')
const changeColor = () => {
setColor( prevColor => prevColor === 'gray' ? 'red' : 'gray')
}
return (
<button className="${color}" onClick={changeColor} >click</button>
)
}
抽出函式這件事從很久以前就學過了,但以往是有大量重複的地方或流程很長才會想到用函式。
但 functional programming 的思考,似乎是沒有必要的命令(沒有順序分枝?)都應該抽成函式。
procedure 的方式,在控制流程分枝時相當好用。
但 if ... else ... 遇到狀態時,就相當棘手了。
在不需要流程控制時,應該以 functional programming 思考。functional progamming 會在前端流行起來,也許是做前端需要大量維護狀態。
大概吧。
有空再研究ㄌ
subtitle: Ken 與 FP 的旅程 ~ 2021-03-31
一直以來都是對 procedure programming 和 OOP 比較熟悉,粗略地知道 functional programming 的概念,也有使用這樣的程式設計法,但沒有再進一步了解,機緣下聽到了 Ken 的這場分享,以下是我聽完分享後的一些思考。
(pipe)
賣場上有三種折價券:98 折、95 折、92 折,沒有限制,可以同時使用。
如果用程式表達這三種折價券可以用三個函式:
const useCoupon98 = x => x*0.98;
const useCoupon95 = x => x*0.95;
const useCoupon92 = x => x*0.92;
如果用 procedure programming 描述我用三張折價券買了一本書:
let book = 400;
let result = useCoupon98(book)
result = useCoupon95(book)
result = useCoupon92(book)
好像也沒有不對,但在這個情境裡,也許用 functional 的方法思考會更符合情境。因為折扣卷並沒有一定要先使用哪一張,但這樣的寫法默默地寫下了執行順序。
如果使用 functional prgramming,似乎會好一點:
let book = 400;
let useCoupons = (a,b,c) => x => a(b(c(x))); //為方便使用固定三個參數,可以改成不定參數
let useCoupons(useCoupon98,useCoupon95,useCoupon92)(book)
雖然這個 useCoupons 並不完美,它裡面的實作依舊是按照順序呼叫,但這個函式已經成功將使用折價券的過程封裝起來,對使用者來說只知道它可以接收折價券當參數。
還記得剛開始學習函式時,學到使用函式可以減少重複的程式碼,讓程式碼更好維護。
另外,也能透過函式命名讓程式更好懂(封裝流程?)。
再來換個情境看看,現在要做一顆切換顏色的按鈕。
範例示範用原生 js 與一步一步將一顆按鈕掛進 container,與用 React hook 方法的差別
const container = document.getElementById('container')
const btn = document.createElement('button')
btn.className ="gray"
btn.onClick = function(e){
if(this.classList.conatins('gray')){
this.classList.remove('gray')
this.classList.add('red')
}else{
this.classList.remove('red')
this.classList.add('gray')
}
}
container.appendChild(btn)
如果用流程的方式思考:
如果有很多顆按鈕就不好維護這段判斷顏色的程式了,於是想把這段程式抽給函式也很合理:
const changeColor = (prevColor, activeColor) => {
if(this.classList.conatins(prevColor)){
this.classList.remove(prevColor)
this.classList.add(activeColor)
}else{
this.classList.remove(prevColor)
this.classList.add(activeColor)
}
}
順便再加個變數。
很基本,所有學到函式與變數的人都能輕鬆做到。
const container = document.getElementById('container')
const btn = document.createElement('button')
btn.className ="gray"
btn.onClick = function(e){
changeColor('gray','red')
}
container.appendChild(btn)
現在,可以來看看 React 在做的事,其實也就是把整個過程要用到的命令式寫法,都抽成函式。
const Container = (props) => {
const [color, setColor] = useState('gray')
const changeColor = () => {
setColor( prevColor => prevColor === 'gray' ? 'red' : 'gray')
}
return (
<button className="${color}" onClick={changeColor} >click</button>
)
}
抽出函式這件事從很久以前就學過了,但以往是有大量重複的地方或流程很長才會想到用函式。
但 functional programming 的思考,似乎是沒有必要的命令(沒有順序分枝?)都應該抽成函式。
procedure 的方式,在控制流程分枝時相當好用。
但 if ... else ... 遇到狀態時,就相當棘手了。
在不需要流程控制時,應該以 functional programming 思考。functional progamming 會在前端流行起來,也許是做前端需要大量維護狀態。
大概吧。
有空再研究ㄌ
Laravel 新手場的紀錄
windows 10 家用版 可能裝不起來 Docker
想挑戰可以參考 搭建 Laravel Sail 开发环境 - Windows
docker ps
curl -s https://laravel.build/example-app | bash
./vendor/bin/sail up
index.php
,在經過一連串的啟動後 request 會分派到路由檔案 eg. routes/web.php
public/index.php
<?php
define('LARAVEL_START', microtime(true));
/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader for
| our application. We just need to utilize it! We'll simply require it
| into the script here so that we don't have to worry about manual
| loading any of our classes later on. It feels great to relax.
|
*/
require __DIR__.'/../vendor/autoload.php';
/*
|--------------------------------------------------------------------------
| Turn On The Lights
|--------------------------------------------------------------------------
|
| We need to illuminate PHP development, so let us turn on the lights.
| This bootstraps the framework and gets it ready for use, then it
| will load up this application so that we can run it and send
| the responses back to the browser and delight our users.
|
*/
$app = require_once __DIR__.'/../bootstrap/app.php';
/*
|--------------------------------------------------------------------------
| Run The Application
|--------------------------------------------------------------------------
|
| Once we have the application, we can handle the incoming request
| through the kernel, and send the associated response back to
| the client's browser allowing them to enjoy the creative
| and wonderful application we have prepared for them.
|
*/
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$response = $kernel->handle(
$request = Illuminate\Http\Request::capture()
);
$response->send();
$kernel->terminate($request, $response);
開啟 routes/web.php 開始撰寫第一個路由
<?php
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('welcom');
});
語法是一個配對的字串與一個 callback function。
預設範例是讓 /
回傳一個叫做 welcom 的 view(有關畫面,即 laravel blade 會在下一次介紹 )。
既然是動態網站,通常會有一些邏輯要處理,通常不會將邏輯直接寫在路由檔案裡,而是抽到控制器。(參考:MVC 架構)
可以透過 artisan 指令建立 controller
php artisan make:controller HelloController
這樣就會在 app/Http/Controllers/ 底下建立一個 HelloController.php
開啟 HelloController.php
<?php
namespace App\Http\Controllers\;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class HelloController extends Controller
{
public function home(): string
{
return 'Hello Controller';
}
}
在這個 controller 裡面寫下一個 home function
回到路由檔案寫下,我們希望將 /home 匹配到我們建立的 HomeController 裡面的 home function
Route::get('/home', 'HomeController@home');
在 Laravel 8 之前使用字串匹配,但目前建議使用陣列
Route::get('/home', HomeController@home);
Laravel 新手場的紀錄
windows 10 家用版 可能裝不起來 Docker
想挑戰可以參考 搭建 Laravel Sail 开发环境 - Windows
docker ps
curl -s https://laravel.build/example-app | bash
./vendor/bin/sail up
index.php
,在經過一連串的啟動後 request 會分派到路由檔案 eg. routes/web.php
public/index.php
<?php
define('LARAVEL_START', microtime(true));
/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader for
| our application. We just need to utilize it! We'll simply require it
| into the script here so that we don't have to worry about manual
| loading any of our classes later on. It feels great to relax.
|
*/
require __DIR__.'/../vendor/autoload.php';
/*
|--------------------------------------------------------------------------
| Turn On The Lights
|--------------------------------------------------------------------------
|
| We need to illuminate PHP development, so let us turn on the lights.
| This bootstraps the framework and gets it ready for use, then it
| will load up this application so that we can run it and send
| the responses back to the browser and delight our users.
|
*/
$app = require_once __DIR__.'/../bootstrap/app.php';
/*
|--------------------------------------------------------------------------
| Run The Application
|--------------------------------------------------------------------------
|
| Once we have the application, we can handle the incoming request
| through the kernel, and send the associated response back to
| the client's browser allowing them to enjoy the creative
| and wonderful application we have prepared for them.
|
*/
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$response = $kernel->handle(
$request = Illuminate\Http\Request::capture()
);
$response->send();
$kernel->terminate($request, $response);
開啟 routes/web.php 開始撰寫第一個路由
<?php
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('welcom');
});
語法是一個配對的字串與一個 callback function。
預設範例是讓 /
回傳一個叫做 welcom 的 view(有關畫面,即 laravel blade 會在下一次介紹 )。
既然是動態網站,通常會有一些邏輯要處理,通常不會將邏輯直接寫在路由檔案裡,而是抽到控制器。(參考:MVC 架構)
可以透過 artisan 指令建立 controller
php artisan make:controller HelloController
這樣就會在 app/Http/Controllers/ 底下建立一個 HelloController.php
開啟 HelloController.php
<?php
namespace App\Http\Controllers\;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class HelloController extends Controller
{
public function home(): string
{
return 'Hello Controller';
}
}
在這個 controller 裡面寫下一個 home function
回到路由檔案寫下,我們希望將 /home 匹配到我們建立的 HomeController 裡面的 home function
Route::get('/home', 'HomeController@home');
在 Laravel 8 之前使用字串匹配,但目前建議使用陣列
Route::get('/home', HomeController@home);
這兩篇文章的 route 都是
https://jntng.coderbridge.io/2021/03/23/about-this-series-spy-engineer/
顯示的是第一篇文章 => "前言"
所以沒有人知道我測到什麼 bug QQ
這兩篇文章的 route 都是
https://jntng.coderbridge.io/2021/03/23/about-this-series-spy-engineer/
顯示的是第一篇文章 => "前言"
所以沒有人知道我測到什麼 bug QQ
UX 對我來說是一個完全陌生也沒有想了解的專業領域。
但想說都花時間參與訪談了,就記錄一下學了什麼。
以一個體驗的心態寫下學到的新名詞。
一些專案的資源與專案開發過程可以參考下面兩個連結:
我寫的會議記錄 => https://jt-li.gitbook.io/uiux/
另一位組員寫的會議紀錄 => https://medium.com/ux-supportgroup/wtm-project/home
預計會寫這些東西
另外也希望可以寫一些觀察跟共事心得
UX 對我來說是一個完全陌生也沒有想了解的專業領域。
但想說都花時間參與訪談了,就記錄一下學了什麼。
以一個體驗的心態寫下學到的新名詞。
一些專案的資源與專案開發過程可以參考下面兩個連結:
我寫的會議記錄 => https://jt-li.gitbook.io/uiux/
另一位組員寫的會議紀錄 => https://medium.com/ux-supportgroup/wtm-project/home
預計會寫這些東西
另外也希望可以寫一些觀察跟共事心得
入門一個完全沒概念的東西的時候我覺得書還是滿不錯的,好的作者會用連貫的觀點串連文章,編列章節順序、設立知識點,就像設計一門課一樣,而且還有校稿、編輯、美術。比起單篇網路文章,一本書以更系統的方式組織知識架構。對英文不到 Native 程度的我來說,繁體書的學習效果還不錯。
缺點是框架書很容易過時,而且書很不好攜帶,不像網路文章隨時可以看(所以通常我看完就會趕快賣掉...)。
我一開始買了 Laravel 5.7 實務專題範例教學:主流PHP開發框架入門。這本真的入門,適合對 web、後端、API 沒什麼概念的超新手。看這本書的時候也有看 Victor 寫的鐵人賽系列文:使用 Laravel 打造 RESTful API,現在已經出書並且改寫到 Laravel 8(這本可能是目前最適合推薦的 Laravel 入門書)。
另外這兩本也是滿多人推薦的:
Laravel 繁體中文的官方文件有 Laravel Dojo 目前只到 5.5,另外還有 laravel.tw 只到 5.3。早期的文件比較短,讀起來不太費力。但後面就比較複雜,我還是超新手的時候其實看官方文章會覺得有點吃力,因為 Laravel 官方文件沒有 Quick Start,對超新手而言其實不知道哪些是必要的。
對於不能讀英文的人,中文我比較推簡體中文的 Laravel 学院,裡面有最新的官方文件翻譯(還有補充教學),也有不斷翻新教程(買過電商教程覺得還可以)、論壇也有活躍討論。
比較喜歡看影片的推薦 Laravel 權威: Laravel X Form Scratch,跟著打一打基本上算會 Laravel 了。
如果說書本或線上課是線性學習方式,那網路文章和影片就是點狀的學習模式。
(影片指的是像講座或特定主題分享的影片)
我有在追的是
剛學會框架後可以開始看 PHP 也有 Day 和 Laracon Taiwan 的分享,早期內容偏向新手,不過最近的 Laracon 議程就偏中高階。
Laracasts 上則是有許多相關生態系的主題影片,例如 Tailwind, Cypress, Livewire 等。如果有跟上 Laracasts 的腳步,基本上可以不用擔心去面試說自己有在學習新技術會被攻擊 XD
追蹤 Laracon,Laracasts 講師(或肉搜他們)可以找到更多資源,但最後也會發現其實在發表的還是那幾個大大 XD
某天突然發現別人跟自己的 KOL 不太一樣...
以下推薦幾個不錯的:
總是在螢幕前看大大?你可以靠近一點。
自己一個人學習很孤單?你可以試試看抱大腿學習法。
最近正好有進行中的 Dojo 活動:(2021/3)
抱起來ㄚ
寫累了,草草收尾。
忘記補一個重要的中文社群網站 Facebook
台灣的 PHP/Laravel 職缺、新聞、發問、活動都可以在這裡找。
入門一個完全沒概念的東西的時候我覺得書還是滿不錯的,好的作者會用連貫的觀點串連文章,編列章節順序、設立知識點,就像設計一門課一樣,而且還有校稿、編輯、美術。比起單篇網路文章,一本書以更系統的方式組織知識架構。對英文不到 Native 程度的我來說,繁體書的學習效果還不錯。
缺點是框架書很容易過時,而且書很不好攜帶,不像網路文章隨時可以看(所以通常我看完就會趕快賣掉...)。
我一開始買了 Laravel 5.7 實務專題範例教學:主流PHP開發框架入門。這本真的入門,適合對 web、後端、API 沒什麼概念的超新手。看這本書的時候也有看 Victor 寫的鐵人賽系列文:使用 Laravel 打造 RESTful API,現在已經出書並且改寫到 Laravel 8(這本可能是目前最適合推薦的 Laravel 入門書)。
另外這兩本也是滿多人推薦的:
Laravel 繁體中文的官方文件有 Laravel Dojo 目前只到 5.5,另外還有 laravel.tw 只到 5.3。早期的文件比較短,讀起來不太費力。但後面就比較複雜,我還是超新手的時候其實看官方文章會覺得有點吃力,因為 Laravel 官方文件沒有 Quick Start,對超新手而言其實不知道哪些是必要的。
對於不能讀英文的人,中文我比較推簡體中文的 Laravel 学院,裡面有最新的官方文件翻譯(還有補充教學),也有不斷翻新教程(買過電商教程覺得還可以)、論壇也有活躍討論。
比較喜歡看影片的推薦 Laravel 權威: Laravel X Form Scratch,跟著打一打基本上算會 Laravel 了。
如果說書本或線上課是線性學習方式,那網路文章和影片就是點狀的學習模式。
(影片指的是像講座或特定主題分享的影片)
我有在追的是
剛學會框架後可以開始看 PHP 也有 Day 和 Laracon Taiwan 的分享,早期內容偏向新手,不過最近的 Laracon 議程就偏中高階。
Laracasts 上則是有許多相關生態系的主題影片,例如 Tailwind, Cypress, Livewire 等。如果有跟上 Laracasts 的腳步,基本上可以不用擔心去面試說自己有在學習新技術會被攻擊 XD
追蹤 Laracon,Laracasts 講師(或肉搜他們)可以找到更多資源,但最後也會發現其實在發表的還是那幾個大大 XD
某天突然發現別人跟自己的 KOL 不太一樣...
以下推薦幾個不錯的:
總是在螢幕前看大大?你可以靠近一點。
自己一個人學習很孤單?你可以試試看抱大腿學習法。
最近正好有進行中的 Dojo 活動:(2021/3)
抱起來ㄚ
寫累了,草草收尾。
忘記補一個重要的中文社群網站 Facebook
台灣的 PHP/Laravel 職缺、新聞、發問、活動都可以在這裡找。
前陣子剛結束第一期的 TMMA 格鬥課程,紀錄並分享一下這段時間的上課心得。
從小因為愛看漫畫的關係,自然地就對格鬥有憧憬。
大學的時候短暫學了一年的空手道,辜負了學長用心教學,現在想想真的很慚愧QQ
選擇 TMMA 其實沒什麼理由,剛好網路蒐到 TMMA 雙和館,離家很近、有免費體驗課,費用也在預算內。
2020 年底某天在 IG 上看到隔年要漲價的訊息,就決定要趕快去上課 XD
我是上陳柏榕的拳擊體驗課,當天只有兩個人,幸運地享受一對二授課。
結束之後我們兩個人都報名了,如果在體驗課結束當天決定入會買課程就可以得到免費一堂課,再加上當時有個上 google 評論的活動,我們得到很多贈課(現在沒有了,而且漲價囉^^)。
最開始是想說學好一種運動,所以只挑踢拳擊。
後來發現其實對初學者來說也沒什麼差,所以後來散打、踢拳擊、泰拳都會上,主要是挑時間和老師。
另外也會挑同學...以下說明...
因為是上一般時段團體課,雖然是初階課程但是學員的強度落差滿大的,有練了好幾期的學員,也第一學期的超新手。
教練沒辦法顧到每一個人,所以發現只有自己是超新手的就會很痛苦。
配不到差不多程度的學員跟老學員一組時,會因為一直記不住動作、拿不好靶,覺得自己害別人沒辦法練習感到挫折。
也因為挫折感會讓去上課變得很不快樂,所以我中間有一度不太想去上課 :P
還好因為我不是固定時間上課,後來發現某些課程入門者不知原因比較多,我就改去那個時段。
建議還是找朋友一起報名比較好,不然就想辦法認識新朋友,約一起上課。
90 分鐘的課程,通常是前 20 分鐘暖身,後 10 分鐘體能加收操。
但每個教練的教學也不太相同,例如熱身有的喜歡讓學員跳繩、有的會帶跑繩梯;
有的教練把體能在穿插教學中,有的是會結束後一起帶;
有的課程和體能塞很滿,有的就比較隨意看全體的狀況;
有的會給新手比較簡單的動作,有的不會特別減少動作。
沒有說哪個比較好,可以多試試看不同教學風格。
以個人角度評價:
我喜歡的部分是這邊的【教學方式和氛圍】,教練讓我覺得是認真在教你運動、教選手,幫你看動作,而不是讓你做做樣子。
(補充一下:看動作不是期待教練當私人教練,盯著你。還是要自己多練習,有空檔抓著教練問)
不喜歡的部分就是【沒有新手入門課】,也不見得每次都能如自己預期的分到實力差不多的練習對手,陪你一起升等。
對初學者而言的唯一一次入門課就是在格鬥體驗課,之後要運氣好剛好那堂課比較多新手才有辦法練到入門動作。
但整體而言對這邊的教學與上課方式都是好評的,也推薦給對技擊格鬥有憧憬的人來試試。
我比較喜歡的教練是蔡昇諭、宋昆陽、陳柏榕教練。
補充一下這邊的性別比,男女比沒有差到很多,通常男女比是 2:1 ~ 1:1。
如果比較喜歡跟同性別的對練,也有女子專班。
預約課程滿自由的,透過 APP 預約課程,在一個小時前取消都不會扣堂數,這點真的很讚,畢竟有時候就是會想耍個懶或臨時加班。
可以上官網查詢,在標註格鬥體驗課的時段去可以免費上課一次(還是要租器材),體驗內容看教的教練是誰。
拳擊手套和手綁帶是所有課必備的,大部分的人都有自備。
我的護脛是租用的,有用到腿的課程基本上都要租,教練有說要戴上再去櫃台租即可。
(雙和館)櫃台有賣運動飲料,因為是商業大樓也有飲水機和廁所。但就沒有浴室了。
]]>前陣子剛結束第一期的 TMMA 格鬥課程,紀錄並分享一下這段時間的上課心得。
從小因為愛看漫畫的關係,自然地就對格鬥有憧憬。
大學的時候短暫學了一年的空手道,辜負了學長用心教學,現在想想真的很慚愧QQ
選擇 TMMA 其實沒什麼理由,剛好網路蒐到 TMMA 雙和館,離家很近、有免費體驗課,費用也在預算內。
2020 年底某天在 IG 上看到隔年要漲價的訊息,就決定要趕快去上課 XD
我是上陳柏榕的拳擊體驗課,當天只有兩個人,幸運地享受一對二授課。
結束之後我們兩個人都報名了,如果在體驗課結束當天決定入會買課程就可以得到免費一堂課,再加上當時有個上 google 評論的活動,我們得到很多贈課(現在沒有了,而且漲價囉^^)。
最開始是想說學好一種運動,所以只挑踢拳擊。
後來發現其實對初學者來說也沒什麼差,所以後來散打、踢拳擊、泰拳都會上,主要是挑時間和老師。
另外也會挑同學...以下說明...
因為是上一般時段團體課,雖然是初階課程但是學員的強度落差滿大的,有練了好幾期的學員,也第一學期的超新手。
教練沒辦法顧到每一個人,所以發現只有自己是超新手的就會很痛苦。
配不到差不多程度的學員跟老學員一組時,會因為一直記不住動作、拿不好靶,覺得自己害別人沒辦法練習感到挫折。
也因為挫折感會讓去上課變得很不快樂,所以我中間有一度不太想去上課 :P
還好因為我不是固定時間上課,後來發現某些課程入門者不知原因比較多,我就改去那個時段。
建議還是找朋友一起報名比較好,不然就想辦法認識新朋友,約一起上課。
90 分鐘的課程,通常是前 20 分鐘暖身,後 10 分鐘體能加收操。
但每個教練的教學也不太相同,例如熱身有的喜歡讓學員跳繩、有的會帶跑繩梯;
有的教練把體能在穿插教學中,有的是會結束後一起帶;
有的課程和體能塞很滿,有的就比較隨意看全體的狀況;
有的會給新手比較簡單的動作,有的不會特別減少動作。
沒有說哪個比較好,可以多試試看不同教學風格。
以個人角度評價:
我喜歡的部分是這邊的【教學方式和氛圍】,教練讓我覺得是認真在教你運動、教選手,幫你看動作,而不是讓你做做樣子。
(補充一下:看動作不是期待教練當私人教練,盯著你。還是要自己多練習,有空檔抓著教練問)
不喜歡的部分就是【沒有新手入門課】,也不見得每次都能如自己預期的分到實力差不多的練習對手,陪你一起升等。
對初學者而言的唯一一次入門課就是在格鬥體驗課,之後要運氣好剛好那堂課比較多新手才有辦法練到入門動作。
但整體而言對這邊的教學與上課方式都是好評的,也推薦給對技擊格鬥有憧憬的人來試試。
我比較喜歡的教練是蔡昇諭、宋昆陽、陳柏榕教練。
補充一下這邊的性別比,男女比沒有差到很多,通常男女比是 2:1 ~ 1:1。
如果比較喜歡跟同性別的對練,也有女子專班。
預約課程滿自由的,透過 APP 預約課程,在一個小時前取消都不會扣堂數,這點真的很讚,畢竟有時候就是會想耍個懶或臨時加班。
可以上官網查詢,在標註格鬥體驗課的時段去可以免費上課一次(還是要租器材),體驗內容看教的教練是誰。
拳擊手套和手綁帶是所有課必備的,大部分的人都有自備。
我的護脛是租用的,有用到腿的課程基本上都要租,教練有說要戴上再去櫃台租即可。
(雙和館)櫃台有賣運動飲料,因為是商業大樓也有飲水機和廁所。但就沒有浴室了。
]]>地方小報
1400 萬讀者 2000-2500 萬讀者
未來以數據利用發展
創作者平台
2.2 萬創作者(不只是文章)
vocus premium, IP 媒合(頭部創作者變現)
作者變多了,接下來...
五年的願景:成為媒體/出版集團
接下來的挑戰:如果只跟頭部創作者合作發展受限
女性向媒體
中小型媒體的挑戰
品牌發展重點
五年的願景:媒體整併
]]>地方小報
1400 萬讀者 2000-2500 萬讀者
未來以數據利用發展
創作者平台
2.2 萬創作者(不只是文章)
vocus premium, IP 媒合(頭部創作者變現)
作者變多了,接下來...
五年的願景:成為媒體/出版集團
接下來的挑戰:如果只跟頭部創作者合作發展受限
女性向媒體
中小型媒體的挑戰
品牌發展重點
五年的願景:媒體整併
]]>先記下幾個覺得有收穫的分享
10/14 前端也能當全端?!用 GraphQL 直接串到 PostgreSQL
徐愷, KOLABLE CTO & Co-founder
kk 講師分享 HASURA 這個資料庫服務,讓前端工程師可以用 Heroku 快速建立自己的 GraphQL DB。
另外 Hasura 也能透過其他服務幫你解決一些原本應該只有後端才能做的事,例如驗證、event trigger、action。
最後是 JAM stack 的概念。
10/16 你的 JS 該減肥了!5個提升網頁載入速度的技巧
趙勗博, 歐姆雷特資深前端工程師
勗博講師分享過去執行最佳化的經驗,從 JS blocks, sode splitting 到五個使用過的最佳化的方法:
有些有興趣的議題沒有聽到,像是 AMP 和 PWA,之後如果有機會還會回來補這一篇!
]]>先記下幾個覺得有收穫的分享
10/14 前端也能當全端?!用 GraphQL 直接串到 PostgreSQL
徐愷, KOLABLE CTO & Co-founder
kk 講師分享 HASURA 這個資料庫服務,讓前端工程師可以用 Heroku 快速建立自己的 GraphQL DB。
另外 Hasura 也能透過其他服務幫你解決一些原本應該只有後端才能做的事,例如驗證、event trigger、action。
最後是 JAM stack 的概念。
10/16 你的 JS 該減肥了!5個提升網頁載入速度的技巧
趙勗博, 歐姆雷特資深前端工程師
勗博講師分享過去執行最佳化的經驗,從 JS blocks, sode splitting 到五個使用過的最佳化的方法:
有些有興趣的議題沒有聽到,像是 AMP 和 PWA,之後如果有機會還會回來補這一篇!
]]>精準行銷大商機!ChatBot x AI打造各領域的智能聊天機器人
之前在 COSCUP 聽說 chatbot 的公司在台灣有上千家,荔枝智慧一開始從客服 AI 做起,之後加上額外功能,例如好友推薦、自然推薦、排成發送折券等等數據分析。
掌握潮流趨勢!主動出擊「商品推薦系統」打造最懂你/妳的電商平台
透過 feature generation,強調針對不同產品建立模型,給予不同的特徵。
拖拉式中控系統讓消費者逃不出的「再行銷」閉環
沒聽到
發揮O2O串流效益!極致的會員關係經營,拉近與消費者的距離
沒聽到
人人都能發揮影響力!媒合「微網紅」的社群行銷平台
分享對網紅的觀察與效益分析。分享者提到這個年代透過小網紅的口碑分享成本效益遠大於大網紅或明星代言。主要技術是透過 IG 爬蟲建立自己的網紅資料庫。
平台提供的痛點解決:
1.小網紅邊際效益遞減
2.解決執行問題(雙方的安全性保證:保證付錢,保證製作內容)
3.多網紅媒合(一次想找多位中大型網紅的溝通成本高)
打造數位生態圈中的MarTech應用
覺得很無聊就先走了
]]>精準行銷大商機!ChatBot x AI打造各領域的智能聊天機器人
之前在 COSCUP 聽說 chatbot 的公司在台灣有上千家,荔枝智慧一開始從客服 AI 做起,之後加上額外功能,例如好友推薦、自然推薦、排成發送折券等等數據分析。
掌握潮流趨勢!主動出擊「商品推薦系統」打造最懂你/妳的電商平台
透過 feature generation,強調針對不同產品建立模型,給予不同的特徵。
拖拉式中控系統讓消費者逃不出的「再行銷」閉環
沒聽到
發揮O2O串流效益!極致的會員關係經營,拉近與消費者的距離
沒聽到
人人都能發揮影響力!媒合「微網紅」的社群行銷平台
分享對網紅的觀察與效益分析。分享者提到這個年代透過小網紅的口碑分享成本效益遠大於大網紅或明星代言。主要技術是透過 IG 爬蟲建立自己的網紅資料庫。
平台提供的痛點解決:
1.小網紅邊際效益遞減
2.解決執行問題(雙方的安全性保證:保證付錢,保證製作內容)
3.多網紅媒合(一次想找多位中大型網紅的溝通成本高)
打造數位生態圈中的MarTech應用
覺得很無聊就先走了
]]>@component('components.card')
@endcomponent
We can write some html and CSS codes, and reuse it.
If we want to generate some cards whitch have same syle but different data, we can use for-loop and pass collection, like this:
@for ($i = 0; $i < 3; $i++)
@component('components.card', ['post' => $data[$i] ] )
@endcomponent
@endfor
However, Laravel 7 canceled component directives(@component). So, you should use Blade component tag(x-[componentName]) to display your comoponet
<x-cards/>
Like Vue.Js, in blade component you can pass data by attributes.
You may pass data to Blade components using HTML attributes. Hard-coded, primitive values may be passed to the component using simple HTML attributes. PHP expressions and variables should be passed to the component via attributes that use the : character as a prefix:
<x-cards type="error" :message="$message"/>
//in card component
<div class="alert alert-{{ $type }}">
{{ $message }}
</div>
寫死的資料可以直接用 type="error"
傳遞,如果需要傳遞陣列資料則需要 :
前置號。
例如:
<h2>熱門文章</h2>
<div class="flex flex-col">
@for ($i = 0; $i < 5; $i++)
<x-cards :post="$data[$i]"/>
@endfor
</div>
//in card component
<div >
<h4 class="pb-2 border-b-2">{{ $post['title'] }}</h4>
</div>
]]>@component('components.card')
@endcomponent
We can write some html and CSS codes, and reuse it.
If we want to generate some cards whitch have same syle but different data, we can use for-loop and pass collection, like this:
@for ($i = 0; $i < 3; $i++)
@component('components.card', ['post' => $data[$i] ] )
@endcomponent
@endfor
However, Laravel 7 canceled component directives(@component). So, you should use Blade component tag(x-[componentName]) to display your comoponet
<x-cards/>
Like Vue.Js, in blade component you can pass data by attributes.
You may pass data to Blade components using HTML attributes. Hard-coded, primitive values may be passed to the component using simple HTML attributes. PHP expressions and variables should be passed to the component via attributes that use the : character as a prefix:
<x-cards type="error" :message="$message"/>
//in card component
<div class="alert alert-{{ $type }}">
{{ $message }}
</div>
寫死的資料可以直接用 type="error"
傳遞,如果需要傳遞陣列資料則需要 :
前置號。
例如:
<h2>熱門文章</h2>
<div class="flex flex-col">
@for ($i = 0; $i < 5; $i++)
<x-cards :post="$data[$i]"/>
@endfor
</div>
//in card component
<div >
<h4 class="pb-2 border-b-2">{{ $post['title'] }}</h4>
</div>
]]>
step 1. make:middleware Cors
step 2. 設定 return header
step 3. 註冊 middleware
step 4. 設定 routes
make:middleware Cors
php artisan make:middleware Cors
產生在 app/Http/Middleware 裡
允許所有來源
<?php
namespace App\Http\Middleware;
use Closure;
class Cors
{
public function handle($request, Closure $next)
{
return $next($request)
->header('Access-Control-Allow-Origin', '*')
->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
->header('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, X-Token-Auth, Authorization');
}
}
打開 app/Http/Kernel.php
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'cors' => \App\Http\Middleware\Cors::class //加入 Cors::class
];
Route::group([
'middleware' => ['cors'],
], function ($router) {
// middleware cors 保護的 route:
Route::get('/hi', function () {
return '{"hi":"hi"}';
});
});
]]>step 1. make:middleware Cors
step 2. 設定 return header
step 3. 註冊 middleware
step 4. 設定 routes
make:middleware Cors
php artisan make:middleware Cors
產生在 app/Http/Middleware 裡
允許所有來源
<?php
namespace App\Http\Middleware;
use Closure;
class Cors
{
public function handle($request, Closure $next)
{
return $next($request)
->header('Access-Control-Allow-Origin', '*')
->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
->header('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, X-Token-Auth, Authorization');
}
}
打開 app/Http/Kernel.php
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'cors' => \App\Http\Middleware\Cors::class //加入 Cors::class
];
Route::group([
'middleware' => ['cors'],
], function ($router) {
// middleware cors 保護的 route:
Route::get('/hi', function () {
return '{"hi":"hi"}';
});
});
]]>
了解 Laravel component 的進化。
@comonent 是 laravel 5.4 的新功能。參考 5.4 的教學影片筆記。
component 可以讓 blade 引用 component blade 的 html 實作。
@component('ad') 會對應到 components/ad.blade,@slot('title') 會對應到該 component 的 {{ $title }} 變數。
welcome blade 是一個完整的 HTML 檔案。如果它想引入一個廣告元件可以這麼做:
welcome
//...
@component('ad')
@slot('title')
laravel 線上課
@endslot
@endcomponent
//...
ad
<div class="ad">
<h1>{{ $title }}</h1>
<p>最後倒數優惠</p>
</div>
這樣好像看不出什麼好處,我直接把 component 寫進去就好啦。
多個廣告的 welcome,或者其他頁面也要使用廣告元件的話:
//...
@component('ad')
@slot('title')
laravel 線上課
@endslot
@endcomponent
@component('ad')
@slot('title')
Vue 線上課
@endslot
@endcomponent
//...
如果我的網站廣告想要插入多個廣告,這樣就有點用了。component 讓我不用寫出同樣的 css class 和 "最後倒數優惠"。
如果我的廣告要呈現不同內文或連到不同網址,可以用多個 slot。
welcome
//...
@component('ad')
@slot('title')
超好喝紅茶
@endslot
@slot('content')
紅茶很好喝
@endslot
@endcomponent
@component('ad')
@slot('title')
超好喝奶茶
@endslot
@slot('content')
奶茶很好喝
@endslot
@endcomponent
//...
dashboard
<div class="dashboard">
<h1>{{ $title }}</h1>
<p>{{ $content }}</p>
</div>
welcome
//...
@component('ad')
@slot('title')
laravel 線上課
@endslot
<div class="button">
<a href="https://donate.me.com/">Buy Me a Coffee</a>
</div>
@endcomponent
//...
ad
<div class="ad">
<h1>{{ $title }}</h1>
<p>最後倒數優惠</p>
{{ $slot }}
</div>
{{ $slot }} 綁定所有沒有指定的內容,除非 component 只有一個內容,不然不太好用。
component 裡 {{}} 如果沒有收到應該要有的變數會發生 Error Exception Undefined variable。
這時可以用 @if isset 做判斷:
welcome
//...
@component('ad')
@slot('title')
laravel 線上課
@endslot
@slot('button')
<a href="https://donate.me.com/">Buy Me a Coffee</a>
@endslot
@endcomponent
//...
ad
<div class="ad">
<h1>{{ title }}</h1>
<p>最後倒數優惠</p>
@if (isset($button))
<div class="button">
{{ $button }}
</div>
@endif
</div>
component blade(ad) 先判斷調用它的 blade(welcome) 有沒有這個變數,有的話才呈現。
使用 {{}} 的預設是比較方便的方法: {{ $title or 'Default' }}
注意:
{{ $title or 'Default' }}
是 5.4 的寫法, 5.7 之後是用{{ $title ?? 'Default' }}
了解 Laravel component 的進化。
@comonent 是 laravel 5.4 的新功能。參考 5.4 的教學影片筆記。
component 可以讓 blade 引用 component blade 的 html 實作。
@component('ad') 會對應到 components/ad.blade,@slot('title') 會對應到該 component 的 {{ $title }} 變數。
welcome blade 是一個完整的 HTML 檔案。如果它想引入一個廣告元件可以這麼做:
welcome
//...
@component('ad')
@slot('title')
laravel 線上課
@endslot
@endcomponent
//...
ad
<div class="ad">
<h1>{{ $title }}</h1>
<p>最後倒數優惠</p>
</div>
這樣好像看不出什麼好處,我直接把 component 寫進去就好啦。
多個廣告的 welcome,或者其他頁面也要使用廣告元件的話:
//...
@component('ad')
@slot('title')
laravel 線上課
@endslot
@endcomponent
@component('ad')
@slot('title')
Vue 線上課
@endslot
@endcomponent
//...
如果我的網站廣告想要插入多個廣告,這樣就有點用了。component 讓我不用寫出同樣的 css class 和 "最後倒數優惠"。
如果我的廣告要呈現不同內文或連到不同網址,可以用多個 slot。
welcome
//...
@component('ad')
@slot('title')
超好喝紅茶
@endslot
@slot('content')
紅茶很好喝
@endslot
@endcomponent
@component('ad')
@slot('title')
超好喝奶茶
@endslot
@slot('content')
奶茶很好喝
@endslot
@endcomponent
//...
dashboard
<div class="dashboard">
<h1>{{ $title }}</h1>
<p>{{ $content }}</p>
</div>
welcome
//...
@component('ad')
@slot('title')
laravel 線上課
@endslot
<div class="button">
<a href="https://donate.me.com/">Buy Me a Coffee</a>
</div>
@endcomponent
//...
ad
<div class="ad">
<h1>{{ $title }}</h1>
<p>最後倒數優惠</p>
{{ $slot }}
</div>
{{ $slot }} 綁定所有沒有指定的內容,除非 component 只有一個內容,不然不太好用。
component 裡 {{}} 如果沒有收到應該要有的變數會發生 Error Exception Undefined variable。
這時可以用 @if isset 做判斷:
welcome
//...
@component('ad')
@slot('title')
laravel 線上課
@endslot
@slot('button')
<a href="https://donate.me.com/">Buy Me a Coffee</a>
@endslot
@endcomponent
//...
ad
<div class="ad">
<h1>{{ title }}</h1>
<p>最後倒數優惠</p>
@if (isset($button))
<div class="button">
{{ $button }}
</div>
@endif
</div>
component blade(ad) 先判斷調用它的 blade(welcome) 有沒有這個變數,有的話才呈現。
使用 {{}} 的預設是比較方便的方法: {{ $title or 'Default' }}
注意:
{{ $title or 'Default' }}
是 5.4 的寫法, 5.7 之後是用{{ $title ?? 'Default' }}
基本上是看 laracasts - cypress and laravel integration 的筆記。
npm install cypress --save-dev
安裝好後會產生 cypress.json 檔和 cypress 資料夾
啟動你的 app,並在 cypress.json 設定入口網站
{
"baseUrl": "http://laravel7_starter.test"
}
在 integration\examples 裡寫一個不通過的測試
it('works', () => {
expect(2+2).to.equal(5);
});
開啟 GUI,點剛剛寫的 example_spec.js
npx cypress open
https://github.com/laracasts/cypress
安裝
php artisan cypress-boilerplate
設定測試環境(安裝這個 package 會自動備份當前環境,並使用 env.cypress 作為測試環境)
DB_CONNECTION=mysql
DB_DATABASE=cypress
https://github.com/guiyomh/cypress-boilerplate
語法
describe('a feature', () => {
describe('a portion', () => {
it('perform', () => {
});
});
});
describe('a portion', () => {
});
context('a portion', () => {
});
.env DB 改成 sqlite
DB_CONNECTION=sqlite
DB_DATABASE=/Users/本地某個資料夾/database.sqlite
database/database.sqlite
新增一個 database.sqlite,執行 php artisan migrate
,指定 --env=cypress
php artisan migrate --env=cypress
describe('Blog', () => {
it('show all posts', () => {
cy.create('App\\Post', {
title: 'My First Post'
});
cy.visit('/blog').contains('My First Post');
});
it('create a post', () => {
});
});
foreach
describe('Blog', () => {
beforeach( () => {
cy.log('hello world');
});
});
cy.refreshdatabase()
刷新 db 指令
describe('Blog', () => {
beforeach( () => {
cy.refreshdatabase();
});
});
failOnSatusCode: false
顯示錯誤
cy.visit('/blog',{
failOnSatusCode: false
}).contains('My First Post');
cy.php()
php 語法
cy.php(`App\\Post::count()`).then( count => { cy.log('post count: + count')});
基本上是看 laracasts - cypress and laravel integration 的筆記。
npm install cypress --save-dev
安裝好後會產生 cypress.json 檔和 cypress 資料夾
啟動你的 app,並在 cypress.json 設定入口網站
{
"baseUrl": "http://laravel7_starter.test"
}
在 integration\examples 裡寫一個不通過的測試
it('works', () => {
expect(2+2).to.equal(5);
});
開啟 GUI,點剛剛寫的 example_spec.js
npx cypress open
https://github.com/laracasts/cypress
安裝
php artisan cypress-boilerplate
設定測試環境(安裝這個 package 會自動備份當前環境,並使用 env.cypress 作為測試環境)
DB_CONNECTION=mysql
DB_DATABASE=cypress
https://github.com/guiyomh/cypress-boilerplate
語法
describe('a feature', () => {
describe('a portion', () => {
it('perform', () => {
});
});
});
describe('a portion', () => {
});
context('a portion', () => {
});
.env DB 改成 sqlite
DB_CONNECTION=sqlite
DB_DATABASE=/Users/本地某個資料夾/database.sqlite
database/database.sqlite
新增一個 database.sqlite,執行 php artisan migrate
,指定 --env=cypress
php artisan migrate --env=cypress
describe('Blog', () => {
it('show all posts', () => {
cy.create('App\\Post', {
title: 'My First Post'
});
cy.visit('/blog').contains('My First Post');
});
it('create a post', () => {
});
});
foreach
describe('Blog', () => {
beforeach( () => {
cy.log('hello world');
});
});
cy.refreshdatabase()
刷新 db 指令
describe('Blog', () => {
beforeach( () => {
cy.refreshdatabase();
});
});
failOnSatusCode: false
顯示錯誤
cy.visit('/blog',{
failOnSatusCode: false
}).contains('My First Post');
cy.php()
php 語法
cy.php(`App\\Post::count()`).then( count => { cy.log('post count: + count')});
沒有使用過 blade 開發專案,筆記一下摸索過程
文後附上學習資源
一般在做 muti-page 網站時,常常會遇到重複區塊的問題。舉例來說一個科技新聞網的 header、navbar、footer 是重複的內容,要改變的只有 page-content 區塊。
Laravel 透過 blade 解決這個問題。利用像是物件導向的方法,讓視圖可以「引用」重複的內容,並讓子視圖可以「擴充」父視圖。
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="csrf-token" value="{{ csrf_token() }}" />
<link href="{{ mix('css/app.css') }}" type="text/css" rel="stylesheet" />
<style>
<!-- 一堆 link -->
</style>
</head>
<body>
<nav class="navbar">
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link" href="{{ url('category/techonology') }}">科技</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url('category/marketing') }}">行銷</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url('category/management') }}">管理</a>
</li>
</ul>
</nav>
<div class="page-content flex-center position-ref full-height">
<!-- -->
</div>
<footer class="py-5 bg-dark">
<div class="container">
<p class="m-0 text-center text-white">Copyright © 科技新聞網 2020</p>
</div>
</footer>
</body>
</html>
現在我們可以把剛剛的 HTML 重複的 navbar、footer 元件化,並在 master 組合(header 就直接寫在 master 裡)。
視圖透過 @include 引用其他視圖已經實作的 HTML。
檔案結構
resources
|-layouts
|---master
|---partials
|-----navboar
navbar
<nav class="navbar">
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link" href="{{ url('category/techonology') }}">科技</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url('category/marketing') }}">行銷</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url('category/management') }}">管理</a>
</li>
</ul>
</nav>
master
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="csrf-token" value="{{ csrf_token() }}" />
<link href="{{ mix('css/app.css') }}" type="text/css" rel="stylesheet" />
@yield('page-style')
</head>
<body>
@include('layouts.partials.navbar')
@yield('page-content')
<!-- 下一段解釋 -->
@include('layouts.partials.footer')
<script src="{{ mix('js/app.js') }}" type="text/javascript"></script>
</body>
</html>
(父)視圖可以使用 @yield 指令「預留」一個區塊給其他視圖擴充。
(子)視圖透過 @extends 指定要擴充的視圖、@section 包夾的區塊則必須實作 @yield 指令所預留的區塊。
master
@yield('page-content')
<!-- 預留一塊必須實作的區塊 -->
post
@extends('layouts.master')
<!-- 指定擴充 master -->
@section('page-content')
<!-- 實作內容 -->
@endsection
layouts 放重複的共用程式、categories 裡有文章總覽(allpost)與單篇文章(post),因為文章總覽頁與單篇文章頁排版不同,所以是兩個樣板文件。
resources
|-layouts
|---master
|---partials
|-----navboar
|-----footer
|-categories
|---allpost
|---post
參考程式碼
master
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="csrf-token" value="{{ csrf_token() }}" />
<link href="{{ mix('css/app.css') }}" type="text/css" rel="stylesheet" />
@yield('page-style')
</head>
<body>
@include('layouts.partials.navbar')
@yield('page-content')
@include('layouts.partials.footer')
<script src="{{ mix('js/app.js') }}" type="text/javascript"></script>
</body>
</html>
allpost
@extends('layouts.master')
@section('page-style')
<link href="{{ asset('css/posts.css') }}" rel="stylesheet">
@endsection
@section('page-content')
<!-- Page Content -->
<div class="container">
<!-- Page Features -->
<div class="row text-center">
@foreach(range(1, 4) as $id)
<div class="col-lg-3 col-md-6 mb-4">
<div class="card h-100">
<img class="card-img-top" src="http://placehold.it/500x325" alt="">
<div class="card-body">
<h4 class="card-title">文章標題 {{ $id }}</h4>
<p class="card-text">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sapiente esse necessitatibus neque.
</p>
</div>
<div class="card-footer">
<a href="{{ url('posts/'.$id) }}" class="btn btn-primary">閱讀全文</a>
</div>
</div>
</div>
@endforeach
</div>
<!-- /.row -->
</div>
<!-- /.container -->
@endsection
post
@extends('layouts.master')
@section('page-style')
<link href="{{ asset('css/posts.css') }}" rel="stylesheet">
@endsection
@section('page-content')
<!-- Page Content -->
<div class="container">
<div class="row">
</div>
<!-- /.row -->
</div>
<!-- /.container -->
@endsection
沒有使用過 blade 開發專案,筆記一下摸索過程
文後附上學習資源
一般在做 muti-page 網站時,常常會遇到重複區塊的問題。舉例來說一個科技新聞網的 header、navbar、footer 是重複的內容,要改變的只有 page-content 區塊。
Laravel 透過 blade 解決這個問題。利用像是物件導向的方法,讓視圖可以「引用」重複的內容,並讓子視圖可以「擴充」父視圖。
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="csrf-token" value="{{ csrf_token() }}" />
<link href="{{ mix('css/app.css') }}" type="text/css" rel="stylesheet" />
<style>
<!-- 一堆 link -->
</style>
</head>
<body>
<nav class="navbar">
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link" href="{{ url('category/techonology') }}">科技</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url('category/marketing') }}">行銷</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url('category/management') }}">管理</a>
</li>
</ul>
</nav>
<div class="page-content flex-center position-ref full-height">
<!-- -->
</div>
<footer class="py-5 bg-dark">
<div class="container">
<p class="m-0 text-center text-white">Copyright © 科技新聞網 2020</p>
</div>
</footer>
</body>
</html>
現在我們可以把剛剛的 HTML 重複的 navbar、footer 元件化,並在 master 組合(header 就直接寫在 master 裡)。
視圖透過 @include 引用其他視圖已經實作的 HTML。
檔案結構
resources
|-layouts
|---master
|---partials
|-----navboar
navbar
<nav class="navbar">
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link" href="{{ url('category/techonology') }}">科技</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url('category/marketing') }}">行銷</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url('category/management') }}">管理</a>
</li>
</ul>
</nav>
master
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="csrf-token" value="{{ csrf_token() }}" />
<link href="{{ mix('css/app.css') }}" type="text/css" rel="stylesheet" />
@yield('page-style')
</head>
<body>
@include('layouts.partials.navbar')
@yield('page-content')
<!-- 下一段解釋 -->
@include('layouts.partials.footer')
<script src="{{ mix('js/app.js') }}" type="text/javascript"></script>
</body>
</html>
(父)視圖可以使用 @yield 指令「預留」一個區塊給其他視圖擴充。
(子)視圖透過 @extends 指定要擴充的視圖、@section 包夾的區塊則必須實作 @yield 指令所預留的區塊。
master
@yield('page-content')
<!-- 預留一塊必須實作的區塊 -->
post
@extends('layouts.master')
<!-- 指定擴充 master -->
@section('page-content')
<!-- 實作內容 -->
@endsection
layouts 放重複的共用程式、categories 裡有文章總覽(allpost)與單篇文章(post),因為文章總覽頁與單篇文章頁排版不同,所以是兩個樣板文件。
resources
|-layouts
|---master
|---partials
|-----navboar
|-----footer
|-categories
|---allpost
|---post
參考程式碼
master
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="csrf-token" value="{{ csrf_token() }}" />
<link href="{{ mix('css/app.css') }}" type="text/css" rel="stylesheet" />
@yield('page-style')
</head>
<body>
@include('layouts.partials.navbar')
@yield('page-content')
@include('layouts.partials.footer')
<script src="{{ mix('js/app.js') }}" type="text/javascript"></script>
</body>
</html>
allpost
@extends('layouts.master')
@section('page-style')
<link href="{{ asset('css/posts.css') }}" rel="stylesheet">
@endsection
@section('page-content')
<!-- Page Content -->
<div class="container">
<!-- Page Features -->
<div class="row text-center">
@foreach(range(1, 4) as $id)
<div class="col-lg-3 col-md-6 mb-4">
<div class="card h-100">
<img class="card-img-top" src="http://placehold.it/500x325" alt="">
<div class="card-body">
<h4 class="card-title">文章標題 {{ $id }}</h4>
<p class="card-text">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sapiente esse necessitatibus neque.
</p>
</div>
<div class="card-footer">
<a href="{{ url('posts/'.$id) }}" class="btn btn-primary">閱讀全文</a>
</div>
</div>
</div>
@endforeach
</div>
<!-- /.row -->
</div>
<!-- /.container -->
@endsection
post
@extends('layouts.master')
@section('page-style')
<link href="{{ asset('css/posts.css') }}" rel="stylesheet">
@endsection
@section('page-content')
<!-- Page Content -->
<div class="container">
<div class="row">
</div>
<!-- /.row -->
</div>
<!-- /.container -->
@endsection
寫了好幾天,每天都在更正錯誤= =
blade 裡面太多類似的方法了,直接看 Laracasts 7 真的一頭霧水,去惡補完前幾代的 blade 才能理解。最好先了解一下 Laracel 5 的 component。
@extends + @section
功能上跟 @component + @slot
一樣
之後 @component + @slot
被 <x-component> + <x-slot>
取代
至於 <x-component />
看起來就是 @include
@extends
透過 @extends('layout')
擴充 Layout,插入 footer 元件
layout 裡面留一塊區塊給其他 blade 實作。當我們進入 page blade 時,因為 page 擴充 layout,所以看起來就像 layout,但是 @yield('content') 將呈現 @section('content') 包夾的內容。
page.blade
@extends('layout')
@section('content')
implements something
@endsection
layout.blade
@yield('content')
也可以使用 @component 寫法
要引用 component 的那個 blade 實作內容
<!-- /resources/my/oops-alert.blade.php -->
@component('alert')
<strong>Whoops!</strong> Something went wrong!
@endcomponent
component 寫好樣式用 slot 預留位置給其他 blade 插入內容
<!-- /resources/views/alert.blade.php -->
<div class="alert alert-danger">
{{ $slot }}
</div>
x-component
取代 @component更正
其實不用 make:component 也可以,這樣就會變成匿名元件(anonymous compontn = 沒有綁 view model 的 component,有 view nodel 可以做更多資料操控)
我不知道為什麼之前做匿名元件都弄不出來,我真的不知道...
blade 只要遇到 x-component
就會去掃描 components 資料夾。(要有 view model render)
其實這樣 layout 叫父視圖也怪怪的。之前是用 @extends 擴充,所以叫父視圖沒什麼問題。但 layout 變成 component 感覺就像一個普通的個元件,被注入到 view page。心理上過不去,怪怪的。
x-component
+ {{ $slot }}views 的 blade 實作注入 component
<!-- /resources/views/oops-alert.blade.php -->
<x-alert>
<strong>Whoops!</strong> Something went wrong!
</x-alert>
layout component 一樣用 slot 預留可以被注入的部分
<!-- /resources/components/alert.blade.php -->
<div class="alert alert-danger">
{{ $slot }}
</div>
<x-component>
+ <x-slot>
<x-componentName>
基本上就是之前的@component('componentName')
<x-slot name="var">
基本上就是之前的@slot('var')
content.blade
實作 HTML,並透過 <x-layout>
指定注入樣板 layout.blade
content.blade
裡,title="Laravel"
的 title 資料綁定 component 的 {{ $title }}
變數呈現。content.blade
裡,<x-slot name="ad">
ad 綁定 component 的 {{ $ad }}
content.blade
裡,沒有綁定變數的預設綁定給 {{ $slot }}
的資料是由 content.blade
提供,注意
這邊如果 blade 想直接傳 title 變數給 component blade,component blade 必須是匿名的
否則必須在 view model 裡面設定 public variabel
resources/views/content.blade.php
<x-layout title="Laravel">
<x-slot name="ad">
Buy Me a Coffee
</x-slot>
Laravel 7 Blade Component Note
</x-layout>
resources/views/components/layout.blade.php
<div>
Hello {{ $title }}
</div>
<div>
@if( isset($ad) )
<div class="ad">
{{ $ad }}
</div>
@endif
<div class="dashboard">
{{ $slot ?? '' }}
</div>
<div>
現在有一個 flash blade 是擴充 layout
檔案結構:
resources/views/
|-components //可注入的元件 blade
|---layout.blade.php
|-welcome.blade.php //視圖 blade
layout = HTML 結構檔案
{{ $slot }}
welcome = 注入 layout ,並實作 layout slot
<x-layout>
<section>
<p>一些提示訊息</p>
</section>
</x-layout>
但 welcome 裡面的東西是可以再做元件,因此我們再做一個 flash 元件:
檔案結構:
resources/views/
|-components //注入子視圖的元件
|---layout.blade.php
|---flash.blade.php
|-welcome.blade.php //子視圖
flash
<section>
<p>一些提示訊息</p>
</section>
welcome
<x-layout>
<x-flash></x-flash>
</x-layout>
這樣 welcome 就會透過 x- 去注入 layout,並實作 layout 的 slot。
welcom 實作又是用一個 x- ,所以它會注入 flash。flash 沒有需要實作的內容,最終呈現的畫面就是 flash 所寫的 <p>一些提示訊息</p>
。
之前我們傳入的變數都是直接使用雙括號顯示。例如 title="Laravel"
-> {{ $title }}
。
使用 props 可以傳入變數
flash
@props([
'type' => 'light'
])
<section class=" {{$type === 'dark' ? 'bg-black' : 'bg-gray-300'}} ">
<p>
{{ $slot }}
</p>
</section>
在 welcome 沒有傳入 type 時,props 設定 type 為 light 版面。
現在從 welcome 傳入 dark。結果就是 dark 版面。
welcome
<x-layout>
<x-flash type="dark">
flash~~
</x-flash>
</x-layout>
props 可以有更多的應用
flash
@props([
'type' => 'light',
'colors' => [
'light' => 'bg-gray-300',
'dark' => 'bg-black'
]
])
<section class="{{ $colors[$type] }}" >
<p>
{{ $slot }}
</p>
</section>
<x-component />
前面插來插去的,搞到最後都不知道是誰繼承,感覺在哪個地方實作都可以。這個寫法就比較清楚,component 裡面實作你的元件,view page 用 <x-component />
注入。
譬如這個寫死的 footer 元件要注入到 pages/home,就跟 @include 一樣好懂。
resources/views/components/footer.blade.php
<div>
default footer
<div>
resources/views/pages/home.blade.php
<x-footer />
一樣是可以做匿名元件
resources/views/components/footer.blade.php
<div>
{{ $title }} //laravel
<div>
resources/views/pages/home.blade.php
<x-footer title="laravel"/>
透過 make:component DemoLayout
產生 app/View/Components/DemoLayout
、resources/views/components/demo-Layout.balde.php
demo-Layout
<?php
namespace App\View\Components;
use Illuminate\View\Component;
class DemoLayout extends Component
{
/**
* Create a new component instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Get the view / contents that represent the component.
*
* @return \Illuminate\View\View|string
*/
public function render()
{
return view('components.demo-layout');
}
}
header.php (extends Component)
<?php
namespace App\View\Components;
use Illuminate\View\Component;
class Header extends Component
{
public $header; //
public function __construct($header)
{
$this->header = $header //
}
public function render()
{
return view('components.header');
}
}
header.blade.php
<div>
{{ $header }}
</div>
layout.blade.php
<x-header header="My website" />
make:component text --inline
在 Component Class 直接 return blade view 就不用去 resources/views/components 找對應的檔案
Component Class 可以置換 attributes,也可以 merge
render()
{
return <<<'blade'
<div {{ $attrubutes->merge(['class' => 'bg-red-400 text-white']) }}>
{{ $description here }}
</div>
blade;
}
layout.blade 可以覆蓋 Component Class 寫的 style
<x-notify description="" class="bg-green-400" />
Component Class 也可以傳進其他東西例如 type
render()
{
return <<<'blade'
<div class="{{ $type === 'success' ? 'bg-green-400' : 'bg-red-400'}}"">
{{ $description here }}
</div>
blade;
}
寫了好幾天,每天都在更正錯誤= =
blade 裡面太多類似的方法了,直接看 Laracasts 7 真的一頭霧水,去惡補完前幾代的 blade 才能理解。最好先了解一下 Laracel 5 的 component。
@extends + @section
功能上跟 @component + @slot
一樣
之後 @component + @slot
被 <x-component> + <x-slot>
取代
至於 <x-component />
看起來就是 @include
@extends
透過 @extends('layout')
擴充 Layout,插入 footer 元件
layout 裡面留一塊區塊給其他 blade 實作。當我們進入 page blade 時,因為 page 擴充 layout,所以看起來就像 layout,但是 @yield('content') 將呈現 @section('content') 包夾的內容。
page.blade
@extends('layout')
@section('content')
implements something
@endsection
layout.blade
@yield('content')
也可以使用 @component 寫法
要引用 component 的那個 blade 實作內容
<!-- /resources/my/oops-alert.blade.php -->
@component('alert')
<strong>Whoops!</strong> Something went wrong!
@endcomponent
component 寫好樣式用 slot 預留位置給其他 blade 插入內容
<!-- /resources/views/alert.blade.php -->
<div class="alert alert-danger">
{{ $slot }}
</div>
x-component
取代 @component更正
其實不用 make:component 也可以,這樣就會變成匿名元件(anonymous compontn = 沒有綁 view model 的 component,有 view nodel 可以做更多資料操控)
我不知道為什麼之前做匿名元件都弄不出來,我真的不知道...
blade 只要遇到 x-component
就會去掃描 components 資料夾。(要有 view model render)
其實這樣 layout 叫父視圖也怪怪的。之前是用 @extends 擴充,所以叫父視圖沒什麼問題。但 layout 變成 component 感覺就像一個普通的個元件,被注入到 view page。心理上過不去,怪怪的。
x-component
+ {{ $slot }}views 的 blade 實作注入 component
<!-- /resources/views/oops-alert.blade.php -->
<x-alert>
<strong>Whoops!</strong> Something went wrong!
</x-alert>
layout component 一樣用 slot 預留可以被注入的部分
<!-- /resources/components/alert.blade.php -->
<div class="alert alert-danger">
{{ $slot }}
</div>
<x-component>
+ <x-slot>
<x-componentName>
基本上就是之前的@component('componentName')
<x-slot name="var">
基本上就是之前的@slot('var')
content.blade
實作 HTML,並透過 <x-layout>
指定注入樣板 layout.blade
content.blade
裡,title="Laravel"
的 title 資料綁定 component 的 {{ $title }}
變數呈現。content.blade
裡,<x-slot name="ad">
ad 綁定 component 的 {{ $ad }}
content.blade
裡,沒有綁定變數的預設綁定給 {{ $slot }}
的資料是由 content.blade
提供,注意
這邊如果 blade 想直接傳 title 變數給 component blade,component blade 必須是匿名的
否則必須在 view model 裡面設定 public variabel
resources/views/content.blade.php
<x-layout title="Laravel">
<x-slot name="ad">
Buy Me a Coffee
</x-slot>
Laravel 7 Blade Component Note
</x-layout>
resources/views/components/layout.blade.php
<div>
Hello {{ $title }}
</div>
<div>
@if( isset($ad) )
<div class="ad">
{{ $ad }}
</div>
@endif
<div class="dashboard">
{{ $slot ?? '' }}
</div>
<div>
現在有一個 flash blade 是擴充 layout
檔案結構:
resources/views/
|-components //可注入的元件 blade
|---layout.blade.php
|-welcome.blade.php //視圖 blade
layout = HTML 結構檔案
{{ $slot }}
welcome = 注入 layout ,並實作 layout slot
<x-layout>
<section>
<p>一些提示訊息</p>
</section>
</x-layout>
但 welcome 裡面的東西是可以再做元件,因此我們再做一個 flash 元件:
檔案結構:
resources/views/
|-components //注入子視圖的元件
|---layout.blade.php
|---flash.blade.php
|-welcome.blade.php //子視圖
flash
<section>
<p>一些提示訊息</p>
</section>
welcome
<x-layout>
<x-flash></x-flash>
</x-layout>
這樣 welcome 就會透過 x- 去注入 layout,並實作 layout 的 slot。
welcom 實作又是用一個 x- ,所以它會注入 flash。flash 沒有需要實作的內容,最終呈現的畫面就是 flash 所寫的 <p>一些提示訊息</p>
。
之前我們傳入的變數都是直接使用雙括號顯示。例如 title="Laravel"
-> {{ $title }}
。
使用 props 可以傳入變數
flash
@props([
'type' => 'light'
])
<section class=" {{$type === 'dark' ? 'bg-black' : 'bg-gray-300'}} ">
<p>
{{ $slot }}
</p>
</section>
在 welcome 沒有傳入 type 時,props 設定 type 為 light 版面。
現在從 welcome 傳入 dark。結果就是 dark 版面。
welcome
<x-layout>
<x-flash type="dark">
flash~~
</x-flash>
</x-layout>
props 可以有更多的應用
flash
@props([
'type' => 'light',
'colors' => [
'light' => 'bg-gray-300',
'dark' => 'bg-black'
]
])
<section class="{{ $colors[$type] }}" >
<p>
{{ $slot }}
</p>
</section>
<x-component />
前面插來插去的,搞到最後都不知道是誰繼承,感覺在哪個地方實作都可以。這個寫法就比較清楚,component 裡面實作你的元件,view page 用 <x-component />
注入。
譬如這個寫死的 footer 元件要注入到 pages/home,就跟 @include 一樣好懂。
resources/views/components/footer.blade.php
<div>
default footer
<div>
resources/views/pages/home.blade.php
<x-footer />
一樣是可以做匿名元件
resources/views/components/footer.blade.php
<div>
{{ $title }} //laravel
<div>
resources/views/pages/home.blade.php
<x-footer title="laravel"/>
透過 make:component DemoLayout
產生 app/View/Components/DemoLayout
、resources/views/components/demo-Layout.balde.php
demo-Layout
<?php
namespace App\View\Components;
use Illuminate\View\Component;
class DemoLayout extends Component
{
/**
* Create a new component instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Get the view / contents that represent the component.
*
* @return \Illuminate\View\View|string
*/
public function render()
{
return view('components.demo-layout');
}
}
header.php (extends Component)
<?php
namespace App\View\Components;
use Illuminate\View\Component;
class Header extends Component
{
public $header; //
public function __construct($header)
{
$this->header = $header //
}
public function render()
{
return view('components.header');
}
}
header.blade.php
<div>
{{ $header }}
</div>
layout.blade.php
<x-header header="My website" />
make:component text --inline
在 Component Class 直接 return blade view 就不用去 resources/views/components 找對應的檔案
Component Class 可以置換 attributes,也可以 merge
render()
{
return <<<'blade'
<div {{ $attrubutes->merge(['class' => 'bg-red-400 text-white']) }}>
{{ $description here }}
</div>
blade;
}
layout.blade 可以覆蓋 Component Class 寫的 style
<x-notify description="" class="bg-green-400" />
Component Class 也可以傳進其他東西例如 type
render()
{
return <<<'blade'
<div class="{{ $type === 'success' ? 'bg-green-400' : 'bg-red-400'}}"">
{{ $description here }}
</div>
blade;
}
一直沒用過,用用看,基本照這篇做
https://ithelp.ithome.com.tw/articles/10210529
step 1. windows 環境下安裝
step 2. Homestead Vagrant Box
step 3. Git clone Homestead
step 4. 設定 Homestead
step 5. 啟動
step 6. 在虛擬機建立專案
step 7. 啟動瀏覽器
step 8. 資料庫連接
vagrant box add laravel/homestead
provider 選 3
git clone https://github.com/laravel/homestead.git Homestead
在 GitHub 發布頁面上找到最新的穩定版本,透過 git 的 checkout 指令切換:
cd Homestead
git checkout 想要的版本
init 產生 Homstead.yaml 這個設定檔。
設定 Homstead.yaml
1.必須產生 app key,不設定密碼
ssh-keygen -t rsa -C "your_email@example.com"
2.map code folder 改成 C:\Code
3.改 sites 和 host file
folders:
- map: C:\Lara
to: /home/vagrant/code
之後要進 code 建立的專案叫 redis-test,順便去修改 host file -> C:\Windows\System32\drivers\etc\hosts
sites:
- map: homestead.test
to: /home/vagrant/code/public
- map: redis.test
to: /home/vagrant/code/redis-test/public
vagrant up
vagrant ssh
cd code
laravel new [name]
根據 step 4 Homstead.yaml 所設定的 mapping 位置,code 底下的資料夾會對應到 C:\Lara
sites 之前一起設定好了
http://redis.test/
在 homestead 建立 database
vagrant ssh
mysql
指令進入 mysql
> create database `laravel-shopping`; //建立資料庫
> show databases; //檢查
修改 .env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel-shopping //改這裡
DB_USERNAME=homestead //改這裡
DB_PASSWORD=secret //改這裡
homestead 如果要連 homestead 的資料庫用 3306
如果想從連本地機器連接 homestead mysql,要用 127.0.0.1:33060 會導向 192.168.10.10:3306
一直沒用過,用用看,基本照這篇做
https://ithelp.ithome.com.tw/articles/10210529
step 1. windows 環境下安裝
step 2. Homestead Vagrant Box
step 3. Git clone Homestead
step 4. 設定 Homestead
step 5. 啟動
step 6. 在虛擬機建立專案
step 7. 啟動瀏覽器
step 8. 資料庫連接
vagrant box add laravel/homestead
provider 選 3
git clone https://github.com/laravel/homestead.git Homestead
在 GitHub 發布頁面上找到最新的穩定版本,透過 git 的 checkout 指令切換:
cd Homestead
git checkout 想要的版本
init 產生 Homstead.yaml 這個設定檔。
設定 Homstead.yaml
1.必須產生 app key,不設定密碼
ssh-keygen -t rsa -C "your_email@example.com"
2.map code folder 改成 C:\Code
3.改 sites 和 host file
folders:
- map: C:\Lara
to: /home/vagrant/code
之後要進 code 建立的專案叫 redis-test,順便去修改 host file -> C:\Windows\System32\drivers\etc\hosts
sites:
- map: homestead.test
to: /home/vagrant/code/public
- map: redis.test
to: /home/vagrant/code/redis-test/public
vagrant up
vagrant ssh
cd code
laravel new [name]
根據 step 4 Homstead.yaml 所設定的 mapping 位置,code 底下的資料夾會對應到 C:\Lara
sites 之前一起設定好了
http://redis.test/
在 homestead 建立 database
vagrant ssh
mysql
指令進入 mysql
> create database `laravel-shopping`; //建立資料庫
> show databases; //檢查
修改 .env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel-shopping //改這裡
DB_USERNAME=homestead //改這裡
DB_PASSWORD=secret //改這裡
homestead 如果要連 homestead 的資料庫用 3306
如果想從連本地機器連接 homestead mysql,要用 127.0.0.1:33060 會導向 192.168.10.10:3306
給自己一個期許,今年來聽議程,明年要上台分享!
今年是自由入場,跟著人群會場報到,拿出事先填好的健康調查,可以得到名牌和手提袋、酒精。
服務台可以領 WIFI 密碼。
今天主要待在 GDG 的議程軌,聽了 firebase、BERT、口罩地圖、GCP。
中間跑去聽 mozilla 社群分享。
第二天本來是打算聽 PostgreSQL 的議程軌,但因為今天是跟朋友約,他對這個主題沒什麼興趣,後來就決定聽早上去聽 StartUp 的議程軌(這個軌幾乎等於區塊鍊新創),結果朋友睡過頭 一直到中午他都沒有出現,然後我也因為懶得移動一整個早上都待在 TR409 當共筆小精靈。
一個滿有趣的觀察是,早上四場其實都是區塊鍊與開源,但十點兩場標題放區塊練,十一點兩場標題是新創公司,後者教室爆滿,前者感覺教室冷清,不知道是大家還沒起床,還是...?
區塊鏈產業與開源文化的交集:信任以及共識 - Charles
蛤?區塊鏈公司是強迫開源 - ping
新創開源要幹嘛? - Tammy Yang
新創公司的開源之路 - Hung-Ying Tai (hydai)
下午朋友出現了,一起去點心桌晃晃,換點數。還好第一天有來,攤位宣傳品已經被拿得差不多了。因為朋友公司做 AI Chatbot,所以主要待在 Chatbot,但我對 Chatbot 背景知識幾乎零,而且個人以使用者角度覺得 Line 內嵌網頁超難用 XD
一個下午聽下來沒有特別學到技術,但默默覺得 Chatbot 社群滿不錯的,可以從共筆看出來 XD
Chatbot 共筆
另外中間有溜去聽一下維基百科的場次。
三十分鐘的議程其實沒辦法太深入,畢竟不是課程。而且如果是想學新技術,與其參加一年一度大拜拜,不如多多參與社群常態讀書會。因為這次參與讓我認識了不少開源社群,以及他們正在推廣的活動,許多社群平常都有在做技術推廣,如果沒辦法當講師、捐錢,去參加、去貢獻筆記也是對開源組織的支持。
這兩天透過闖關認識不少開源組織,這邊列出一些我以前不知道/不太熟的:
發現他們有錄影,附上連結:
COSCUP X PostgreSQL 2020
https://www.facebook.com/groups/pgsql.tw/
除了寫這篇廢文之外,自己之後最大的改變就是真的要去參與離家近的社群了!
]]>給自己一個期許,今年來聽議程,明年要上台分享!
今年是自由入場,跟著人群會場報到,拿出事先填好的健康調查,可以得到名牌和手提袋、酒精。
服務台可以領 WIFI 密碼。
今天主要待在 GDG 的議程軌,聽了 firebase、BERT、口罩地圖、GCP。
中間跑去聽 mozilla 社群分享。
第二天本來是打算聽 PostgreSQL 的議程軌,但因為今天是跟朋友約,他對這個主題沒什麼興趣,後來就決定聽早上去聽 StartUp 的議程軌(這個軌幾乎等於區塊鍊新創),結果朋友睡過頭 一直到中午他都沒有出現,然後我也因為懶得移動一整個早上都待在 TR409 當共筆小精靈。
一個滿有趣的觀察是,早上四場其實都是區塊鍊與開源,但十點兩場標題放區塊練,十一點兩場標題是新創公司,後者教室爆滿,前者感覺教室冷清,不知道是大家還沒起床,還是...?
區塊鏈產業與開源文化的交集:信任以及共識 - Charles
蛤?區塊鏈公司是強迫開源 - ping
新創開源要幹嘛? - Tammy Yang
新創公司的開源之路 - Hung-Ying Tai (hydai)
下午朋友出現了,一起去點心桌晃晃,換點數。還好第一天有來,攤位宣傳品已經被拿得差不多了。因為朋友公司做 AI Chatbot,所以主要待在 Chatbot,但我對 Chatbot 背景知識幾乎零,而且個人以使用者角度覺得 Line 內嵌網頁超難用 XD
一個下午聽下來沒有特別學到技術,但默默覺得 Chatbot 社群滿不錯的,可以從共筆看出來 XD
Chatbot 共筆
另外中間有溜去聽一下維基百科的場次。
三十分鐘的議程其實沒辦法太深入,畢竟不是課程。而且如果是想學新技術,與其參加一年一度大拜拜,不如多多參與社群常態讀書會。因為這次參與讓我認識了不少開源社群,以及他們正在推廣的活動,許多社群平常都有在做技術推廣,如果沒辦法當講師、捐錢,去參加、去貢獻筆記也是對開源組織的支持。
這兩天透過闖關認識不少開源組織,這邊列出一些我以前不知道/不太熟的:
發現他們有錄影,附上連結:
COSCUP X PostgreSQL 2020
https://www.facebook.com/groups/pgsql.tw/
除了寫這篇廢文之外,自己之後最大的改變就是真的要去參與離家近的社群了!
]]>Step 1 – 建立專案
Step 2 – 設定 nginx/.env
Step 3 – 設定 nginx/sites/[projectName].conf
Step 4 – 改 /ect/hosts
Step 5 – 運行 laradock 和瀏覽器
step 6 - 連結資料庫
注意檔案結構!
上一篇已經建立好 laradock 的專案資料夾,裡面有 laradock。現在要再建立兩個給前後端的資料夾。
專案資料夾
|-be <- 要用來放 Laravel
|-js <- 要用來放 Angular
|-laradock
進去專案資料夾去 clone 或 create 你的專案。
專案資料夾
|-be
|---public
|-----index.php
|-js
|---public
|-----index.html
|-laradock
|---nginx
|-----.env
|-----sites
|-------be.conf
|-------js.conf
保持不動,在laradock同級目錄
D:\docker\laradock\nginx\sites
新增內容,可以從 .example 改。nginx.conf 會 include
要改兩個地方
1.root
root /var/www/[專案名稱]/[放index的資料夾通常是public];
2.server_name
/ect/hosts 要對應的名稱
js.conf
server {
listen 80;
listen [::]:80;
server_name js;
root /var/www/js/public;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
try_files $uri /index.php =404;
fastcgi_pass php-upstream;
fastcgi_index index.php;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
location /.well-known/acme-challenge/ {
root /var/www/letsencrypt/;
log_not_found off;
}
}
be.conf
server {
listen 80;
listen [::]:80;
server_name be;
root /var/www/be/public;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
try_files $uri /index.php =404;
fastcgi_pass php-upstream;
fastcgi_index index.php;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
location /.well-known/acme-challenge/ {
root /var/www/letsencrypt/;
log_not_found off;
}
}
127.0.0.1 js
127.0.0.1 be
docker-compose exec workspace bash
開瀏覽器檢查
http://js:5566/
http://be:5566/
如果是 mysql
BD_HOST 改成 localhost
Step 1 – 建立專案
Step 2 – 設定 nginx/.env
Step 3 – 設定 nginx/sites/[projectName].conf
Step 4 – 改 /ect/hosts
Step 5 – 運行 laradock 和瀏覽器
step 6 - 連結資料庫
注意檔案結構!
上一篇已經建立好 laradock 的專案資料夾,裡面有 laradock。現在要再建立兩個給前後端的資料夾。
專案資料夾
|-be <- 要用來放 Laravel
|-js <- 要用來放 Angular
|-laradock
進去專案資料夾去 clone 或 create 你的專案。
專案資料夾
|-be
|---public
|-----index.php
|-js
|---public
|-----index.html
|-laradock
|---nginx
|-----.env
|-----sites
|-------be.conf
|-------js.conf
保持不動,在laradock同級目錄
D:\docker\laradock\nginx\sites
新增內容,可以從 .example 改。nginx.conf 會 include
要改兩個地方
1.root
root /var/www/[專案名稱]/[放index的資料夾通常是public];
2.server_name
/ect/hosts 要對應的名稱
js.conf
server {
listen 80;
listen [::]:80;
server_name js;
root /var/www/js/public;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
try_files $uri /index.php =404;
fastcgi_pass php-upstream;
fastcgi_index index.php;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
location /.well-known/acme-challenge/ {
root /var/www/letsencrypt/;
log_not_found off;
}
}
be.conf
server {
listen 80;
listen [::]:80;
server_name be;
root /var/www/be/public;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
try_files $uri /index.php =404;
fastcgi_pass php-upstream;
fastcgi_index index.php;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
location /.well-known/acme-challenge/ {
root /var/www/letsencrypt/;
log_not_found off;
}
}
127.0.0.1 js
127.0.0.1 be
docker-compose exec workspace bash
開瀏覽器檢查
http://js:5566/
http://be:5566/
如果是 mysql
BD_HOST 改成 localhost
前往 https://docs.docker.com/docker-for-windows/install/
建立一個專案資料夾,進去資料夾 clone laradock
git clone https://github.com/Laradock/laradock.git
cd laradock
cp env-example .env
修改php版本
docker-compose up -d nginx mysql phpmyadmin redis workspac
結構
專案資料夾
|---.git
|---laradock
docker-compose up
會比較久-> .env 把 port 80 改掉就好
ERROR: for nginx Cannot start service nginx
-> 重開治百病
laradock ports are not available: bind: an attempt was made to access a socket in a way forbidden by its access permissions
C:\Users\ty>netsh int ipv4 show excludedportrange protocol=tcp
通訊協定 tcp 連接埠排除範圍
開始連接埠 結束連接埠
---------- ----------
80 80
1554 1653
1654 1753
1754 1853
5357 5357
50000 50059 *
* - 管理的連接埠排除。
能那麼快解決要感謝保哥
https://blog.miniasp.com/post/2019/03/31/Ports-blocked-by-Windows-10-for-unknown-reason
前往 https://docs.docker.com/docker-for-windows/install/
建立一個專案資料夾,進去資料夾 clone laradock
git clone https://github.com/Laradock/laradock.git
cd laradock
cp env-example .env
修改php版本
docker-compose up -d nginx mysql phpmyadmin redis workspac
結構
專案資料夾
|---.git
|---laradock
docker-compose up
會比較久-> .env 把 port 80 改掉就好
ERROR: for nginx Cannot start service nginx
-> 重開治百病
laradock ports are not available: bind: an attempt was made to access a socket in a way forbidden by its access permissions
C:\Users\ty>netsh int ipv4 show excludedportrange protocol=tcp
通訊協定 tcp 連接埠排除範圍
開始連接埠 結束連接埠
---------- ----------
80 80
1554 1653
1654 1753
1754 1853
5357 5357
50000 50059 *
* - 管理的連接埠排除。
能那麼快解決要感謝保哥
https://blog.miniasp.com/post/2019/03/31/Ports-blocked-by-Windows-10-for-unknown-reason
從 github 上下載了一個活生生的專案,興奮地 php artisan serve
,怎麼噴出一堆錯誤代碼?
要怎麼要讓它跑起來呢?
不論你是用 clone 還是下載 zip,下載到自己的電腦的一定不是完整的專案,就像濃縮的果汁一樣。
這時候你需要跑一些指令安裝套件和做一些本地設定,才能夠正常地運行專案。
當 php artisan serve
出現 404 not found ,最有可能就是少了套件了。
npm install
Warning: require(C:\xampp\htdocs\birdboard\public/../vendor/autoload.php): failed to open stream: No such file or directory in C:\xampp\htdocs\birdboard\public\index.php on line 24
Fatal error: require(): Failed opening required 'C:\xampp\htdocs\birdboard\public/../vendor/autoload.php' (include_path='C:\xampp\php\PEAR') in C:\xampp\htdocs\birdboard\public\index.php on line 24
composer install
cmd 告訴你沒有 vender\autoload.php 。
composer install
跟 npm 套件一樣,composer 套件檔案很大、也很常修改,所以通常 vender 檔案預設是不上傳的,只會上傳 composer.json
紀錄。
沒有 .env 。
.env 裡面有許多私密的資料,預設不上傳。通常會有一個 .env.example
,可以用這個修改。
把 .env.example
改成 .env
,先沿用預設設定。
RuntimeException
No application encryption key has been specified.
cmd 告訴你沒有 key,所以就要給它 key 。
php artisan key:generate
到這邊為止,已經可以看到首頁起來了~
接下來,還要把資料庫連起來!
回到第三步驟提到的 .env ,現在要來設定資料庫。
如果你使用 homestead 要沿用預設的 mysql 和 homestead ,就不需要修改。
如果使用 XAMPP 和想要使用預設的 phpmyadmin ,也只需要改資料庫的名稱和 username。
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=test
DB_USERNAME=root
DB_PASSWORD=
既然是抓下來的專案,通常已經寫好 migration 和 seed ,現在要把它們還原!
php artisan migrate:install
php artisan migrate:refresh
php artisan db:seed
config\app.php
文件是個拿到基本上就會先改的東西~
'name' => env('APP_NAME', 'Laravel'), //改成自己的專案名稱
'timezone' => 'Asia/Taipei', //不改資料庫時間不對
'locale' => 'zh-tw', //如果有用中文套件或多國語需求才會改
改完記得 php artisan config:cache
設定檔才會更新
以上,過一陣子就忘記的東西,自己筆記一份。
]]>從 github 上下載了一個活生生的專案,興奮地 php artisan serve
,怎麼噴出一堆錯誤代碼?
要怎麼要讓它跑起來呢?
不論你是用 clone 還是下載 zip,下載到自己的電腦的一定不是完整的專案,就像濃縮的果汁一樣。
這時候你需要跑一些指令安裝套件和做一些本地設定,才能夠正常地運行專案。
當 php artisan serve
出現 404 not found ,最有可能就是少了套件了。
npm install
Warning: require(C:\xampp\htdocs\birdboard\public/../vendor/autoload.php): failed to open stream: No such file or directory in C:\xampp\htdocs\birdboard\public\index.php on line 24
Fatal error: require(): Failed opening required 'C:\xampp\htdocs\birdboard\public/../vendor/autoload.php' (include_path='C:\xampp\php\PEAR') in C:\xampp\htdocs\birdboard\public\index.php on line 24
composer install
cmd 告訴你沒有 vender\autoload.php 。
composer install
跟 npm 套件一樣,composer 套件檔案很大、也很常修改,所以通常 vender 檔案預設是不上傳的,只會上傳 composer.json
紀錄。
沒有 .env 。
.env 裡面有許多私密的資料,預設不上傳。通常會有一個 .env.example
,可以用這個修改。
把 .env.example
改成 .env
,先沿用預設設定。
RuntimeException
No application encryption key has been specified.
cmd 告訴你沒有 key,所以就要給它 key 。
php artisan key:generate
到這邊為止,已經可以看到首頁起來了~
接下來,還要把資料庫連起來!
回到第三步驟提到的 .env ,現在要來設定資料庫。
如果你使用 homestead 要沿用預設的 mysql 和 homestead ,就不需要修改。
如果使用 XAMPP 和想要使用預設的 phpmyadmin ,也只需要改資料庫的名稱和 username。
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=test
DB_USERNAME=root
DB_PASSWORD=
既然是抓下來的專案,通常已經寫好 migration 和 seed ,現在要把它們還原!
php artisan migrate:install
php artisan migrate:refresh
php artisan db:seed
config\app.php
文件是個拿到基本上就會先改的東西~
'name' => env('APP_NAME', 'Laravel'), //改成自己的專案名稱
'timezone' => 'Asia/Taipei', //不改資料庫時間不對
'locale' => 'zh-tw', //如果有用中文套件或多國語需求才會改
改完記得 php artisan config:cache
設定檔才會更新
以上,過一陣子就忘記的東西,自己筆記一份。
]]>6/22 發生這個錯誤,當時在裝 nexmo 以為是預設空間不夠,後來換中國的映像解決問題,確定是 mirror 地址掛掉。之後台灣社群也有人建了台灣的映像檔。
"composer update" not working #9003
Content-Length mismatch, received 547139 bytes out of the expected 2345297
http://repo.packagist.org could not be fully loaded, package information was loaded from the local cache and may be out of date
檢查自己的鏡像檔
composer config -l
composer config -g repos.packagist composer https://packagist.tw
composer config repo.packagist composer https://mirrors.aliyun.com/composer/
composer config repo.packagist composer https://packagist.jp
兩週後同樣的方法也成功幫我解決了類似問題
反正 composer install 有問題先換 mirror
6/22 發生這個錯誤,當時在裝 nexmo 以為是預設空間不夠,後來換中國的映像解決問題,確定是 mirror 地址掛掉。之後台灣社群也有人建了台灣的映像檔。
"composer update" not working #9003
Content-Length mismatch, received 547139 bytes out of the expected 2345297
http://repo.packagist.org could not be fully loaded, package information was loaded from the local cache and may be out of date
檢查自己的鏡像檔
composer config -l
composer config -g repos.packagist composer https://packagist.tw
composer config repo.packagist composer https://mirrors.aliyun.com/composer/
composer config repo.packagist composer https://packagist.jp
兩週後同樣的方法也成功幫我解決了類似問題
反正 composer install 有問題先換 mirror