Full Stack
Full Stack
Express:
1. Cách Import?
Để cài đặt
npm install express
Để Import
Common Module
const <Express> = require("express")
ECMA Module
import <Express> from "express"
2. Tạo 1 App?
const <App> = <Express>()
Mỗi khi chạy lệnh trên, thì 1 App mới được tạo, các App không liên quan tới nhau, mỗi
App sẽ chiếm giữ nhiều Port, và không thể có Port bị 2 App chiếm giữ
3. Lắng Nghe Tại 1 Port?
Để 1 App chiếm giữ 1 Port, hay bắt đầu lắng nghe tại Port này
<App>.listen(<Port>, <Call Back>)
Đây là hàm bất đồng bộ, nên các lệnh tiếp theo chạy luôn không chờ, sau khi đã chiếm
giữ thành công thì <Call Back> sẽ được gọi, không chỉ định <Call Back> cũng được
Nếu gọi lệnh trên lần 2 với cùng <Port> sẽ lỗi
Ví dụ
foo.listen(3000)
4. Middleware?
Với mỗi Path khác nhau trên URL, ta có thể gửi yêu cầu tới nó bằng các phương thức
khác nhau như Get, Post, …, và mỗi Path như vậy, sẽ có 1 Middleware Stack cho riêng
nó, Middleware Stack sẽ bao gồm Middleware 1, Middleware 2, Middleware 3, …, khi
gửi yêu cầu với phương thức bất kì, thì ngay lập tức Middleware 1 sẽ được gọi đầu tiên,
và được truyền các tham số lần lượt là <Request>, <Response>, và <Next>, khi
Middleware 1 chạy, nếu gặp lệnh <Next>() lần đầu tiên, thì lập tức nhảy sang chạy
Middleware 2, tương tự Middleware 2 chạy thì nếu gặp lệnh <Next>() thì sẽ nhảy sang
chạy Middleware 3, …, dễ thấy cơ chế giống như đệ quy, cho tới khi chạy xong
Middleware cuối cùng, thì nó sẽ quay lại Middleware kế cuối để chạy nốt phần sau
<Next>(), lưu ý <Next>() chạy lần thứ 2 trở đi sẽ vô dụng và nếu không còn Middleware
nào để chạy thì <Next>() cũng vô dụng, rồi lại quay lui Middleware kế kế cuối, …, trong
khi chuỗi Middleware chạy, bạn sẽ thấy biểu tượng vòng tròn xoay xoay nghĩa là đang tải
ở trên tiêu đề Tab, cho tới khi có lệnh <Response>.send hoặc <Response>.render trong
Middleware thì nó mới hết, đồng thời gửi Response về trình duyệt, trường hợp 1
Middleware không có lệnh <Next>() bên trong sẽ quay vòng vòng mãi mãi, lưu ý 2 lệnh
send và render chạy thì mấy lệnh sau nó vẫn chạy tiếp và bạn không thể gửi Response 2
lần
Để thêm 1 Middleware, cái nào thêm sau thì đánh số lớn hơn, ví dụ Middleware 1, 2, 3,
…
<App>.use(<Path Đầu>, <Middleware>)
<Middleware> sẽ là 1 Call Back nhận 3 tham số như đã nói
<Path Đầu> tức là lệnh trên sẽ thêm <Middleware> vào tất cả các Path có khởi đầu là
<Path Đầu>, ví dụ <Path Đầu> = "/foo/bar", thì các Path như "/foo/bar/alice",
"/foo/bar/alice/john", "/foo/bar/boo", … đều được thêm <Middleware>
Lệnh trên áp dụng với mọi Port mà <App> đang chiếm giữ
Nếu <Path Đầu> không chỉ định thì áp dụng cho mọi Path
<Path Đầu> có thể sử dụng cơ chế động, bằng cách thêm dấu 2 chấm ở đầu các khúc, ví
dụ Path tĩnh thông thường sẽ là /foo/bar, /alice, …, còn Path động sẽ là
/foo/:slug, /:bar, /:gg/concac/:concu, …, xét ví dụ /:gg/concac/:concu, thì tất cả các Path
từ 3 khúc trở lên, sao cho khúc thứ 2 là concac, sẽ bị dính, ví dụ /x/concac/y/z,
/lon/concac/longchim, …, nghĩa là tương đương với hàng tỉ câu lệnh use, ứng với tất cả
Path này, chuỗi sau dấu : của các khúc được gọi là Slug, trong <Middleware>, bạn có thể
dùng <Request> để truy xuất giá trị của các Slug, thông qua Object trả về bởi lệnh
<Request>.params, Object này có cặp Key Value, với Key là tên Slug, và Value là giá trị
hiện tại của nó bạn nhập trên URL, tiếp tục ví dụ trên, giả sử bạn nhập Path của URL là
/concho/concac/buom/thui, thì sẽ dính /:gg/concac/:concu, khi này <Request>.params
là
{
"gg": "concho",
"concu": "buom"
}
Tương tự như trên, nhưng Middleware được thêm sẽ có thêm điều kiện là nếu Path trên
URL không giống y chang <Path> hoặc yêu cầu với phương thức không phải Get, thì sẽ
Next ngay lập tức mà không chạy Call Back, <Path> vẫn có thể động, <Path> phải được
chỉ định
<App>.get(<Path>, <Middleware>)
Về lệnh send
<Response>.send(<Response Body>)
Nếu <Response Body> là String, thì thuộc tính "Content-Type" của Response Header sẽ
là "text/html;charset=urf-8"
Nếu <Response Body> là 1 Object viết theo Dictionary, thì "Content-Type" là
"application/json;charset=utf-8"
Về lệnh render, cũng như trên, nhưng trước khi gửi Response thì nó sẽ thông qua Engine
chính, 1 App sẽ có nhiều Engine, và giá trị của thuộc tính View Engine của App chính là
tên đại diện của Engine chính, các Engine còn lại là phụ
<Response>.render(<Đường Dẫn Tới File Render>)
Khi lệnh trên được chạy, trước tiên, nó sẽ tìm đến thư mục A được chỉ định bởi thuộc
tính Views của App, tức thuộc tính Views của App phải là String đường dẫn tuyệt đối tới
thư mục A hoặc tương đối tới A, kể từ bên trong thư mục làm việc hiện tại, <Đường Dẫn
Tới File Render> sẽ là đường dẫn tương đối, kể từ bên trong A, dẫn tới File cần Render,
không ghi phần mở rộng, File cần Render này phải có phần mở rộng = tên đại diện của
Engine chính, tùy vào loại Engine mà nó sẽ xử lí File này khác nhau để trả về 1 String cuối
cùng, String này sẽ làm phần Response Body
Ví dụ
app.use("/foo", (req, res, next) => {
console.log(1)
next()
console.log(2)
})
app.use("/foo", (req, res, next) => {
console.log(3)
next()
console.log(4)
})
app.get("/foo/bar", (req, res, next) => {
console.log(5)
next()
console.log(6)
})
app.get("/foo/bar", (req, res, next) => {
console.log(7)
res.send("ggnore")
console.log(8)
})
Ở đây, khi bạn nhập URL với Path là /foo/bar, thì màn hình Console lập tức hiện ra là
1
3
5
7
8
6
4
2
Về <Request>
Để trả về Object ứng với chuỗi Query trên URL, tức là gồm các Key Value của các tham số
Query
<Request>.query
5. Cài Đặt Server?
Mỗi 1 App sẽ có các thuộc tính riêng, trong đó có 1 số thuộc tính liên quan đến cài đặt,
còn lại là thuộc tính thường, để gán lại giá trị cho 1 thuộc tính hoặc tạo mới 1 thuộc tính
<App>.set(<Tên Thuộc Tính>, <Giá Trị>)
Ví dụ
foo.set("hahanore", 123)
Để trả về giá trị của 1 thuộc tính
<App>.get(<Tên Thuộc Tính>)
Các thuộc tính cài đặt
Thuộc tính View Engine, "view engine"
Thuộc tính Views, "views", mặc định là String đường dẫn tuyệt đối tới thư mục làm việc
hiện tại, thêm thư mục "views" đằng sau, ví dụ "C:\Users\pc\Desktop\Web Test\views"
Để thêm 1 Engine vào App
<App>.engine(<Tên Đại Diện Engine>, <Engine>)
Nếu lặp lại lệnh trên với cùng <Tên Đại Diện Engine>, thì bỏ thằng trước lấy thằng sau
Ví dụ
foo.engine("hahanore", ultimate_engine())
6. Các File Tĩnh?
Lệnh sau sẽ trả về 1 Middleware
<Express>.static(<Đường Dẫn Tới Nguồn Tĩnh>)
<Đường Dẫn Tới Nguồn Tĩnh> có thể là tuyệt đối hoặc tương đối từ trong thư mục làm
việc hiện, nó sẽ dẫn đến thư mục A
Bạn có thể Pass Middleware này vào phương thức use của 1 App, nó có tác dụng phân
tích URL, nếu thấy URL là đường dẫn tới 1 File, tức là có phần mở rộng, nó sẽ xem xét
thư mục A có File đó không, nếu có thì trả về trình duyệt, ví dụ Path của URL là
/foo/bar/alice.png, thì trong A nếu có thư mục "foo" và trong "foo" có "bar" và trong
"bar" có "alice.png" thì sẽ trả về File "alice.png", nếu không tồn tại thì trả về lỗi 404, ví
dụ
app.use(express.static("thu/mucA"))
7. Xử Lí Request Body?
Như đã biết, Request Body chính là các cặp Key Value trong Form bạn Submit bằng
phương thức Post, tuy nhiên Request Body không có ngay được để sử dụng trong các
Middleware, mà bạn cần phải xử lí các thông tin Submit trước mới ra được Request
Body, để làm điều này thì dùng lệnh sau, lệnh này trả về 1 Middleware có tác dụng xử lí
thông tin Submit để tạo Request Body
<Express>.urlencoded({extended: true})
Ví dụ
app.use(express.urlencoded({extended: true}))
Sau khi Middleware trên được chạy, thì các Middleware tiếp theo có thể sử dụng lệnh
sau để trả về Object, gồm các cặp Key Value trong Request Body
<Request>.body
8. Mô Hình MVC (Model View Controller)?
Nodemon:
1. Cách Tải?
npm install nodemon --save-dev
Khi này, trong thư mục con ".bin" của "node_modules", sẽ có File "nodemon.cmd"
2. Cách Khởi Động Lại Server Mỗi Khi Thay Đổi File?
Dùng File "nodemon.cmd"
node_modules/.bin/nodemon.cmd <Đường Dẫn Tới File JS Không Cần Phần Mở Rộng>
Lệnh trên y chang như dùng Node để chạy 1 File JS, tuy nhiên, thay vì chỉ có 1 Process
node.exe thì có 2 Process node.exe cùng xuất hiện, 1 cái dùng để hóng các thay đổi
trong các File để làm mới cái còn lại, và cái này tồn tại vĩnh viễn cho tới khi bạn cố tính
tắt nó đi, nghĩa là, khác với Node, Nodemon sẽ không dừng cho dù File JS đã chạy xong,
và bất cứ khi nào các File liên quan đến File JS đó bị thay đổi, thì Nodemon sẽ chạy lại từ
đầu, mặc định thì các File liên quan phải có phần mở rộng là ".js", ".mjs" hoặc ".json" thì
mới tính, các File còn lại thay đổi hay không cũng chẳng làm mới, để thay đổi sự mặc
định này, thì tạo File "nodemon.json" trong thư mục làm việc hiện tại, và đặt thuộc tính
"ext" trong nó thành chuỗi các phần mở rộng sẽ lắng nghe sự thay đổi, ví dụ
{
"ext": "js json scss css"
}
JSON Server:
1. Cách Tải?
npm install json-server
2. Tạo JSON Server?
npx json-server <Đường Dẫn Tới File JSON Có Phần Mở Rộng>
Lệnh trên sẽ tạo 1 Server tại http://localhost:3000, để tạo Server tại Port khác thì thêm
cờ -p, theo sau là số Port, Server chỉ đóng khi Terminal chạy lệnh trên hủy chạy
Nội dung File JSON sẽ bao gồm các Key cấp 1, Value của mỗi Key này là thứ sẽ được trả
về khi bạn gửi yêu cầu vào Link tới Server / <Tên Key> bằng phương thức Get, ví dụ
http://localhost:3500/ggnore
Thứ được trả về khi gửi yêu cầu Get bằng hàm fetch, là 1 Object, gọi là Response, để trả
về 1 Promise, Promise này bất đồng bộ có tác dụng giải mã nội dung từ JSON thành biến,
nghĩa là nó trả về đúng kiểu dữ liệu, khi Fulfilled thì Promise Result = giá trị biến
<Response>.json()
Ví dụ
fetch("http://localhost:3500/ggnore").then(x => x.json()).then(x => console.log(x))
Cookie Parser?
1. Cách Import?
Để tải
npm install cookie-parser
Để Import
Common Module
const <Cookie Parser> = require("cookie-parser")
ECMA Module
import <Cookie Parser> from "cookie-parser"
2. Middleware Giải Mã Cookie?
<Request> trong Middleware của App của Express chưa thể sử dụng Cookie ngay được,
nhắc lại Cookie này tự động được gửi kèm theo yêu cầu từ phía trình duyệt người dùng,
để trả về Middleware có chức năng giải mã Cookie
<Cookie Parser>()
Ví dụ
app.use(cookie_parser())
Bây giờ ở các Middleware tiếp theo, có thể dùng lệnh sau để trả về Cookie, là Object viết
theo Dictionary, chứa các cặp Key Value đều là String
<Request>.cookies
Express Handlebars:
1. Cách Import?
Để tải
npm install express-handlebars
Để Import
Common Module
const <Express Handlebars> = require("express-handlebars")
ECMA Module
import <Express Handlebars> from "express-handlebars"
2. Thêm Engine Vào App Của Express?
<App>.engine(<Tên Đại Diện Engine>, <Express Handlebars>.engine(<Config>))
<Config> là 1 Object viết theo Dictionary
Engine này hoạt động như sau, trong thư mục được chỉ định bởi thuộc tính Views của
<App>, phải có 1 thư mục tên là "layouts", trong đây lại phải có 1 File tên là "main" với
phần mở rộng = giá trị của thuộc tính "extname" của <Config>, ví dụ extname =
".ggnore", nếu không chỉ định thì mặc định extname = ".handlebars", File "main" này y
chang 1 File HTML hoàn chỉnh, tuy nhiên trong nó có thể dùng 1 số cú pháp đặc biệt
Khi bạn viết như sau, thì vị trí bạn viết, sẽ được đặt thẳng vào toàn bộ nội dung của File
cần Render
{{{body}}}
Khi bạn viết như sau, thì vị trí bạn viết, sẽ được đặt thẳng vào toàn bộ nội dung của 1
File A, File A này được xác định như sau, xét thư mục được chỉ định bởi thuộc tính Views
của <App>, phải có 1 thư mục tên là "partials" bên trong nó, và <Đường Dẫn Đến File
Partial> sẽ bắt đầu từ bên trong thư mục "partials" này, dẫn tới File A, không ghi phần
mở rộng, File A phải có phần mở rộng = phần mở rộng của File "main" ở trên
{{> <Đường Dẫn Đến File Partial>}
- Ví dụ
{{> foo/bar}
Nội dung của File "main" sau khi được thế, sẽ là thứ được trả về làm Response Body
Path:
1. Cách Import?
Thư viện này tự động dùng được chỉ cần File JS chạy bằng Node, không cần tải
Để Import
Common Module
const <Path> = require("path")
ECMA Module
Import <Path> from "path"
2. Nối Đường Dẫn?
<Path>.join(<Các Đường Dẫn>)
Lệnh trên sẽ trả về String có được nhờ việc nối tất cả String trong <Các Đường Dẫn> lại
với nhau bằng dấu \ giữa các String, sau đó bất kì dấu / nào tồn tại đều bị biến thành \,
đồng thời mọi chùm dấu \ liền nhau sẽ bị hợp thành 1 dấu \ duy nhất, ví dụ
path.join("C::Emmet: Increment by 1/:a/concu", "concac", "conbuom//")
Lệnh trên trả về "C::Emmet: Increment by 1\:a\concu\concac\conbuom\"
HTTP:
1. Cách Import?
Thư viện này tự động dùng được chỉ cần File JS chạy bằng Node, không cần tải
Để Import
Common Module
const <HTTP> = require("http")
ECMA Module
Import <HTTP> from "http"
2.
Mongoose:
1. Cách Import?
Để tải
npm install mongoose
Để Import
Common Module
const <Mongoose> = require("mongoose ")
ECMA Module
import <Mongoose> from "mongoose"
2. Kết Nối Với Cluster?
Một lúc bạn có thể kết nối với nhiều cơ sở dữ liệu của nhiều Cluster khác nhau, nhưng
trong đó, chỉ có 1 kết nối tiêu chuẩn, bạn chỉ được phép tạo nhiều nhất 1 kết nối tiêu
chuẩn, các kết nối còn lại là kết nối thường
Lệnh dưới đây sẽ tạo 1 Promise bất đồng bộ, nó có nhiệm vụ kết nối với 1 cơ sở dữ liệu
của 1 Cluster, có thể là ở trên đám mây hoặc cục bộ, sau khi kết nối xong thì thu được
Promise Result là 1 Object, tạm gọi là <Connection>, đây là kết nối tiêu chuẩn
<Mongoose>.connect(<URI>)
<URI> là URI tới Cluster thêm phần tên cơ sở dữ liệu muốn kết nối ở đằng sau, lưu ý nếu
kết nối cục bộ, thì localhost phải đổi thành 127.0.0.1, ví dụ các URI sau là hợp lệ
mongodb+srv://thanglon:[email protected]/coso1
mongodb://127.0.0.1:27017/coso2
Tương tự, nhưng lệnh dưới đây tạo ra kết nối thường, Promise Result cũng là
<Connection>
<Mongoose>.createConnection(<URI>)
Nếu để đó thì các kết nối vẫn giữ nguyên, để ngắt kết nối, đúng hơn là trả về 1 Promise
bất đồng bộ, có nhiệm vụ ngắt kết nối
<Connection>.disconnect()
Nếu <Connection> là kết nối tiêu chuẩn thì có thể thay bằng <Mongoose>
Lệnh sau trả về 1 Schema, tạm gọi là <Schema>, khi <Schema> này được gắn với 1
Collection của 1 cơ sở dữ liệu nào đó, thì những lần tạo Document tiếp theo trên
Collection đó phải tuân theo <Schema> này mới được lưu vào Collection
new <Mongoose>.Schema(<Scheme>, {
collection: <Tên Collection>,
versionKey: <Tên Version Key>
})
<Scheme> là Object viết theo kiểu Dictionary, Value ở đây sẽ là kiểu dữ liệu
<Tên Collection> tạm gọi là thuộc tính Collection Name của <Schema>, không chỉ định
cũng được
<Tên Version Key> tạm gọi là thuộc tính Version Key của <Schema>, không chỉ định thì
mặc định nó = "__v"
Lệnh sau trả về 1 Object, tạm gọi là <Model> ứng với 1 Collection của cơ sở dữ liệu
<Connection>.model(<Tên Model>, <Schema>)
<Tên Model> là String, bạn đặt cái mẹ gì cũng được
Nếu <Schema> có chỉ định thuộc tính Collection Name, thì giá trị của thuộc tính này sẽ
chính là tên của Collection mà ta sẽ liên kết tới, nếu không tồn tại Collection nào có tên
này trong cơ sở dữ liệu thì sẽ tạo mới, nếu không chỉ định Collection Name, thì
Collection liên kết tới sẽ có tên suy ra bởi <Tên Model>, bằng cách viết thường hết các
chữ cái, rồi các dấu cách thay bằng dấu _, rồi sẽ đổi sang dạng số nhiều, ví dụ thêm s
hoặc es cuối từ tiếng Anh
Nếu <Connection> là kết nối tiêu chuẩn, thì có thể thế <Connection> ở lệnh trên thành
<Mongoose>
Lệnh sau sẽ trả về 1 Promise bất đồng bộ, có nhiệm vụ Query 1 số Document trong
Collection ứng với <Model>, Promise Result sẽ là 1 Array chứa các Object, tạm gọi là
<Document>, chính là các Document được Query ra
<Model>.find(<Query>)
<Query> viết y chang như chuỗi Query trong Mongo DB Compass, tức là 1 Object viết
theo Dictionary
Để trả về 1 bản nháp Document, tạm gọi là <Temp Document>, nó chưa lưu vào
Collection vội
new <Model>(<Nội Dung Document>)
<Nội Dung Document> là Object viết theo Dictionary, viết kiểu gì cũng được
Các kiểu dữ liệu tương ứng giữa JS và Mongo DB
JS Mongo DB
String String
Nếu là số nguyên vừa tầm thì khi lưu
Number sẽ thành Int32, ngược lại nếu số thập
phân, hoặc vượt tầm thì Double
Boolean Boolean
Array Array
Date Date
<Mongoose>.Schema.Types.Decimal128 Decimal128
<Mongoose>.Schema.Types.BigInt Int64
Object Object
<Mongoose>.Schema.Types.ObjectId ObjectID
Chỉnh sửa 1 <Document> y chang như khi bạn chỉnh sửa 1 Object viết theo Dictionary,
để trả về 1 Promise bất đồng bộ, có nhiệm vụ lưu <Document> hoặc <Temp Document>
vào Collection
<Document>.save()
Lệnh trên sẽ lỗi nếu <Document> không tuân theo <Schema>, tức là có 1 cặp Key Value
trong <Document>, mà kiểu dữ liệu của Value không thể ép về kiểu được chỉ định trong
<Schema>
Nếu trong <Document> chứa các Key không có trong <Schema>, thì các Key này bị bỏ
không lưu
Nếu trong <Document> thiếu Key được chỉ định trong <Schema>, thì không sao, các Key
này cũng sẽ không lưu trừ khi có giá trị mặc định
Sẽ có 2 Key nữa được lưu vào là Key "_id" và Version Key
- Với Key "_id", thì đây là Key được tạo bởi hệ thống, không thể chỉnh sửa hay xóa, kiểu là
ObjectID, tất cả Document trong Collection sẽ được đảm bảo Value của Key "_id" là độc
nhất
- Với Version Key, nếu bạn chỉ định nó trong <Schema> là false, thì sẽ không lưu Version
Key nào hết, nhưng nếu nó là 1 String nào đó, thì bạn sẽ thấy có 1 Key với tên là String
đó, được lưu với kiểu dữ liệu là Int32 với giá trị ban đầu = 0
Để trả về 1 ObjectID
new <Mongoose>.Types.ObjectId(<String 24 Kí Tự Thập Lục Phân>)
Để xóa tất cả Document thỏa mãn Query nào đó, nói đúng hơn là trả về 1 Promise bất
đồng bộ, có nhiệm vụ xóa các Document, cách viết Query đã biết
<Model>.deleteMany(<Query>)
Developer Tools:
<Response Body>
Dễ thấy giữa phần <Response Header> và <Response Body> sẽ có 1 dòng trống
<Phiên Bản Giao Thức Và Trạng Thái> thông thường sẽ có dạng sau, ví dụ giao thức là
HTTP phiên bản 1.1, mã trạng thái phản hồi là 200
HTTP/1.1 200 OK
<Response Header> sẽ bao gồm các dòng, mỗi dòng là 1 thuộc tính
- "Date", thời điểm phản hồi xảy ra, theo múi giờ chuẩn, có cú pháp
<Thứ>, <Ngày> <Tháng> <Năm> <Giờ>:<Phút>:<Giây> GMT
a) <Thứ>, <Tháng> là từ tiếng anh, lấy 3 chữ cái đầu, kí tự đầu viết hoa
- "Content-Encoding", cơ chế mã hóa của <Response Body>
Kí tự tương ứng
%2B +
%20 Dấu cách
%26 &
%3D =
%23 #
Ví dụ, đầu tiên bạn nhập Query như sau vào URL
?f+++o o= abc&a%2B=1
- Thì trước tiên, nó sẽ quy đổi về Query hợp pháp sau
?f+++o%20%20o=%20%20abc&a%2B=1&concac&concu=
- Sau đó, dùng các quy tắc như đã nói, ta được 2 cặp Key Value
{
"f o o": " abc",
"a+": "1",
"concac": "",
"concu": ""
}
7. Tab Network?
Có 4 phần, thanh trên cùng, gọi tắt là thanh công cụ mạng, phần ngay bên dưới, gọi là
cửa sổ đồ thị mạng, phần rộng hơn bên dưới, là cửa sổ File tải lên, và thanh dưới cùng,
gọi là thanh thống kê mạng
Tab "Network" ban đầu khi bạn mở cửa sổ phát triển sẽ trống, và kể từ lúc này nó bắt
đầu hóng dữ liệu mà máy chủ gửi về trang Web ở máy bạn, cũng như những dữ liệu bạn
gửi cho máy chủ, …, để tạm ngưng việc hóng, Click biểu tượng màu đỏ bên trái cùng ở
thanh công cụ mạng = nhấn "Ctrl" + "E", khi này nó sẽ thành biểu tượng vòng tròn xám,
nhấn lại nó nữa để bắt đầu hóng lại, nhưng đồng thời cũng xóa tất cả những gì đã hóng
Tất cả những gì trong Tab "Network" cũng sẽ bị xóa khi Tab liên kết với cửa sổ phát triển
chuyển hướng sang trang Web khác, để ngăn chặn việc xóa nội dung trong Tab
"Network" khi chuyển hướng trang hoặc khi hóng lại, Tick vào ô "Preserve log" tại thanh
công cụ mạng, và Untick để trở lại mặc định
Để chủ động xóa tất cả nội dung trong Tab "Network", Click biểu tượng "Clear network
log" bên trái thanh công cụ mạng = nhấn "Ctrl" + "L"
Để ý ngay dưới thanh công cụ mạng, sẽ có 1 thanh khác, gọi là thanh lọc, thanh này mặc
định sẽ hiện ra, để ẩn hiện nó, Click biểu tượng "Filter" ở bên trái thanh công cụ mạng
Về cửa sổ File tải lên
Cột "Name", tên phần cuối cùng trong URL bạn gửi yêu cầu tới, ví dụ URL là
https://www.youtube.com/watch?v=UnDDZrz1BoQ thì phần cuối sẽ là watch?
v=UnDDZrz1BoQ, Click vào tên ở cột này sẽ mở cửa sổ chi tiết yêu cầu ở bên phải
Cột "Status", mã trạng thái phản hồi
HTML:
<Loại>
"checkbox" Ô vuông bo góc dùng để Tick hoặc Untick
Vòng tròn dùng để Tick, một khi đã Tick
không thể Untick, trong 1 File HTML, nếu
có nhiều Tag input với type = radio, và
"radio"
cùng giá trị name, thì chỉ có tối đa 1 vòng
tròn được Tick, Tick vòng khác, thì vòng
trước Untick
Khung chữ nhật bo góc, Click chuột vào để
"text" nhập văn bản, Click chuột ra để không
nhập nữa, văn bản nhập không bị xóa
Nút bấm, Click chuột vào để bấm, chữ trên
"submit" nút bấm = <Nội Dung Hiển Thị>, mặc định
là "Submit"
21. Tag Select?
Tag này chỉ chứa Tag Option làm Tag con
<select name = <Tên>>
<option value = <Giá Trị 1>><Tên Option 1></option>
<option value = <Giá Trị 2>><Tên Option 2></option>
…
</select>
Tag trên hoạt động như Node Inline Block, tuy nhiên các thuộc tính CSS mặc định khá
phức tạp nên ta cũng không nên tạo kiểu lại cho nó làm gì
Nó giống như 1 Menu chọn tùy chọn, bạn sẽ chỉ chọn 1 trong các tùy chọn được liệt kê,
mỗi tùy chọn là 1 Tag Option, cái hiện ra là <Tên Option>, còn <Giá Trị> là thứ sẽ được
Submit khi bạn đặt Tag Select vào 1 Tag Form và Submit
22. Tag Button?
<button>
<Nội Dung>
</button>
Tag trên hoạt động như Node Inline Block, <Nội Dung> sẽ được bao trong 1 nút bấm,
Click chuột lên nó để bấm
23. Tag Label?
<label for = <Bound ID>>
<Nội Dung>
</label>
Chả khác mẹ gì Tag span, ngoại trừ việc có thêm thuộc tính CSS cursor = default
Nếu chỉ định <Bound ID> là giá trị của thuộc tính id của 1 Tag nào đó, thì Tag Label này sẽ
bị gắn với Tag đó, và khi này nó sẽ có 1 số hiệu ứng đặc biệt
Nếu Click vào Tag Label bị gắn với Tag Input loại ô Input văn bản, thì như việc bạn Click
vào ô Input đó để nhập, tương tự với các loại Input khác và Tag Select
24. Tag Form?
<form method = <Phương Thức> action = <Path Submit>>
<Nội Dung>
</form>
Các thuộc tính CSS mặc định
<Ngôn Ngữ>
"vi" Tiếng Việt
"en" Tiếng Anh
Ví dụ
<h1 lang = "vi">
foo
</h1>
26. Favicon?
Là biểu tượng nhỏ nằm bên trái tiêu đề Tab, để thêm Favicon
<link rel = "shortcut icon" href = "<Đường Dẫn Tới Favicon>">
Ví dụ
<link rel = "shortcut icon" href = "foo.png">
27. Kí Tự Thoát?
Ví dụ bạn muốn hiển thị chuỗi "<h1>gg</h1>" lên màn hình, nhưng đang tiếc là chỉ hiện
thị được "gg" do cái kia bị tưởng là Tag, để làm được điều này, ta sẽ dùng kí tự thoát
biểu diễn < và >, tương ứng là < và >
Ví dụ, "<h1>gg</h1>
CSS:
<Gạch Ở Đâu>
none Mặc định, không gạch gì hết
overline Hiện Top Line lệch 1 tí của kí tự
Hiện Base Line xuống dưới 1 tí của kí tự,
underline nếu kí tự ví dụ như g, nó có cuống ở phía
dưới thì có thể che con mẹ nó underline
line-through Hiện Middle Line lệch 1 tí của kí tự
Có thể hiện cùng lúc nhiều gạch, ví dụ
text-decoration-line: overline line-through;
Để chỉ định kiểu gạch
text-decoration-style: <Kiểu Gạch>;
Ta có
<Kiểu Gạch>
solid Mặc định, gạch thẳng
dashed Gạch đứt quãng
Để chỉ định màu gạch
text-decoration-color: <Màu>;
Để chỉ định độ dày gạch
text-decoration-thickness: <Độ Dày>;
Có thể viết gộp 4 thuộc tính trên lại
text-decoration: <Các Thuộc Tính>;
Ví dụ
text-decoration: overline underline dashed 10px red;
9. Viết In Đậm?
Thêm thuộc tính CSS "font-weight: bold;"
10. Viết Số Kiểu Cách?
font-variant-numeric: <Kiểu Cách>;
Thuộc tính CSS này có tính kế thừa
Áp dụng cho toàn bộ kí tự số trong Node
Ta có
<Kiểu Cách>
normal Mặc định, như bạn hay thấy
oldstyle-nums Viết các số với độ cao chênh lệch nhau
tabular-nums Chiều rộng mỗi số = nhau
11. Chuyển Sang In Hoa Hoặc In Thường?
text-transform: <Kiểu In>;
Thuộc tính CSS này có tính kế thừa
Ta có
<Kiểu In>
none Mặc định, không làm gì hết
uppercase Tất cả kí tự đều in hoa
lowercase Tất cả kí tự đều in thường
capitalize Biến kí tự đầu tiên mỗi từ viết hoa
12. Viết Chữ Từ Trên Xuống?
Thêm thuộc tính CSS "writing-mode: vertical-lr"
Xét Node có thuộc tính CSS này, quay Box của nó ngược chiều kim đồng hồ góc 90 độ,
được điểm nhìn A, gọi điểm nhìn cũ là B, viết chữ từ trái sang phải, hết dòng thì lên dòng
bên trên, bây giờ giới hạn không còn là chiều rộng mà là chiều cao màn hình, đồng thời
kí tự và ảnh trong mỗi dòng sẽ được căn giữa dòng, lưu ý ảnh không bị quay ở điểm nhìn
B
Base Line so với viết theo kiểu ngang là kí tự bên phải cùng ở điểm nhìn A
Tương tự "writing-mode: vertical-rl", quay Box 90 độ ngược chiều kim đồng hồ, viết từ
trái sang, hết dòng thì xuống dưới
Ta có chỉ định thuộc tính CSS direction để xác định chiều viết, điểm nhìn trái phải sẽ bị
đảo ngược
direction: <Chiều>;
Thuộc tính CSS này có tính kế thừa
Ta có
<Chiều>
ltr Mặc định, đéo có gì để nói
Chưa đặt dòng vào Content Box vội, xét
mỗi dòng, lặp qua từng Node con, nếu bắt
rtl gặp Node Inline Block thì đẩy nó sang bên
phải Content Box, nếu gặp Node Inline, thì
đẩy 1 lúc hết phần còn lại
Theo điểm nhìn A, margin-block-start = margin-top, margin-block-end =
margin-bottom, margin-inline-start = margin-left, margin-inline-end = margin-right,
tương tự cho cả padding
13. Hàm Trả Về Giá Trị Thuộc Tính Tag?
attr(<Tên Thuộc Tính>)
Lệnh trên sẽ trả về String, do đó nó chỉ có thể áp dụng cho thuộc tính CSS content của
lớp giả before và after
Ví dụ
h1::after {
content: attr(daucac);
}
Khi này content = giá trị của thuộc tính daucac của Tag h1 được chọn
14. Đặt Biến?
Biến được khai báo ở Node cha, sẽ có thể dùng lại ở Node con cháu
Nếu 1 biến được khai báo 2 lần, thì lần nào Selector có độ ưu tiên cao hơn thì chọn, nếu
cùng độ ưu tiên thì lấy thằng viết sau
Cú pháp
--<Tên Biến> : <Giá Trị>;
Để trả về giá trị của 1 biến
var(--<Tên Biến>)
Để nếu biến không tồn tại thì lấy giá trị mặc định nào đó
var(--<Tên Biến>, <Giá Trị Mặc Định>)
Ví dụ
.foo {
--daucac: red;
--daulon: 10px;
}
.bar {
color: var(--daucac);
width: var(--daulon, 8px);
}
15. Padding?
Để chỉ định Padding cho 1 phía
padding-<Phía>: <Kích Thước>;
<Phía> phải là top, left, bottom hoặc right
Ví dụ
padding-top: 10px;
Để chỉ định Padding cho nhiều phía cùng lúc
padding: <Các Kích Thước>;
Ta có
deg Độ
Dải màu coi như 1 ảnh nền, kích thước ảnh này mặc định = kích thước Box ứng với thuộc
tính CSS background-clip
Ví dụ
background-image: linear-gradient(123deg, red, yellow);
Bạn có thể chỉ định nhiều ảnh 1 lúc, ảnh viết trước thì hiện ở phía trên, một số thuộc
tính sẽ áp dụng chung cho các ảnh, ví dụ
background-image:
url("foo.png"),
url("bar.png"),
linear-gradient(123deg, red, yellow)
;
Khi này, ta có thể chỉ định nhiều giá trị cho thuộc tính CSS background-clip, mỗi giá trị sẽ
ứng với 1 ảnh riêng, nghĩa là mỗi ảnh sẽ có vùng chứa khác nhau, thuộc tính CSS
background-color sẽ lấy Box đầu
Ví dụ
background-clip: content-box, border-box;
Gốc tọa độ để đặt ảnh sẽ tùy thuộc vào thuộc tính background-origin, mặc định là
Padding Box, do đó khi đặt ảnh, góc trái trên ảnh sẽ khít với góc trái trên Padding Box
background-origin: <Box Khác>;
Phần ảnh vượt quá Box sẽ bị ẩn, tất cả mọi thứ sẽ đè lên ảnh nền trừ màu nền, mặc định
ảnh sẽ lặp lại theo cả chiều ngang và dọc, lặp theo cả chiều âm, để chỉ định nó chỉ lặp lại
theo 1 phương hoặc không lặp lại theo chiều nào
background-repeat: <Chiều Lặp>;
Ta có
<Trigger> Cơ chế
Tạo 1 Node giả trước Node con đầu tiên,
:before
mặc định như 1 Node văn bản rỗng
Tạo 1 Node giả ngay sau Node con cuối
:after
cùng, mặc định như 1 Node văn bản rỗng
Nếu kí tự bị bôi đen thì áp kiểu không thì
:selection
thôi
Ví dụ
h1::selection {
color: blue;
}
Độ ưu tiên của lớp giả = độ ưu tiên của Class, ví dụ h1::selection = độ ưu tiên của h1 + độ
ưu tiên của selection = 0-0-0-1 + 0-0-1-0 = 0-0-1-1
23. Vị trí?
Mặc định mỗi Node có thuộc tính CSS "position: static;", khi này, thuộc tính CSS top, left,
bottom, right sẽ vô tác dụng, nghĩa Node sẽ luôn đứng im tại chỗ
position: <Kiểu Vị Trí>;
ta có
<Kiểu Vị Trí>
static Mặc định, không thể Offset
Gốc tọa độ là vị trí mặc định, tức là vị trí
khi position = static, có thể dịch sang phải
bằng left, dịch sang trái bằng right, dịch
xuống dưới = top và dịch lên trên bằng
relative bottom, nếu chỉ định left thì right vô dụng,
nếu chỉ định top, thì bottom vô dụng, khi
Offset, bản thể thật sự của nó vẫn đứng
yên, tức là phần nó chiếm chỗ vẫn như cũ,
chỉ có phần kết xuất ra là bị Offset
absolute Gốc tọa độ là góc trái trên Padding Box của
Node tổ tiên gần nhất có thuộc tính CSS
position khác static, nếu không tìm thấy thì
lấy Node HTML, tọa độ (0, 0) thì góc trái
trên của Border Box của Node này sẽ = gốc
tọa độ = góc trái trên của Padding Box của
Node tổ tiên đã nói, tuy nhiên điều này chỉ
áp dụng khi bạn chỉ sử dụng left và top,
nếu bạn sử dụng right và bottom, thì gốc
tọa độ sẽ là góc phải dưới của Padding Box
của Node tổ tiên đã nói, góc phải dưới
Border Box của Node này sẽ = gốc tọa độ
này khi tọa độ = (0, 0), cơ chế dịch tương
đồng với left và right, chỉ đảo chiều lại, nếu
cùng chỉ định left, right và width, thì right
bị lơ, nếu cùng chỉ định left và right nhưng
không chỉ định width, thì width sẽ tự điều
chỉnh, tương tự cho top và bottom và
height, còn một điều lưu ý nữa là Node
này sẽ bị bứt ra khỏi trang Web, nghĩa là
phần không gian nó chiếm khi position =
static sẽ được trả tự do, và Node này sẽ
trong trạng thái lơ lửng
Gốc tọa độ là góc trái trên màn hình, bứt
Node này ra khỏi trang Web cho nó nổi tự
do, phần không gian nó chiếm cũng bị trả
fixed
lại, coi màn hình là Node tổ tiên của nó, cơ
chế top, left, bottom, right y chang như
absolute
24. Xử Lí Tràn Biên?
Giả sử nội dung bị tràn ra khỏi Padding Box của Node nào đó, bạn muốn ẩn nó đi và tạo
thanh cuộn, xử lí cả tràn ngang và tràn dọc
overflow: <Cách Xử Lí>;
Ta có
<Cách Xử Lí>
Mặc định, không xử lí, hiện cả nội dung
visible
tràn
ẩn nội dung tràn khỏi Padding Box, kể cả
hidden
phần ảnh bị tràn
= hidden, nhưng có thêm 2 thanh cuộn, 1
cái nằm bên trái cạnh phải của Padding
scroll Box, 1 cái nằm bên trên cạnh dưới của
Padding Box, luôn hiện dù tràn hay không
tràn
auto = scroll, nhưng chỉ hiện thanh cuộn khi tràn
Để chỉ xử lí tràn ngang hoặc tràn dọc
overflow-<Phương>: <Cách Xử Lí>;
<Phương> = x là tràn ngang, = y là tràn dọc, nếu chỉ chỉ định 1 phương thì phương còn lại
mặc định = auto
Nếu chỉ định theo cách này thì bạn không được phép chỉ định 1 phương visible và
phương còn lại không visible, để có thể làm được điều này, dùng clip, nó giống hidden
nhưng khi chỉ định lên 1 phương, thì phương còn lại được phép visible
Ví dụ
overflow-x: hidden;
overflow-y: visible;
Phương x hidden, phương y auto
overflow-x: clip;
overflow-y: visible;
Phương x hidden, phương y visible
Để hiện thêm 1 phần ngoài rìa Padding Box
overflow-clip-margin: <Kích Thước>;
Lệnh này chỉ có tác dụng khi cả 2 phương đều dùng clip
<Kích Thước> có thể là content-box, border-box, mặc định là 0px kể từ Padding Box
Ví dụ
overflow: clip;
overflow-clip-margin: 20px;
Nghĩa là sẽ hiện trong vùng Padding Box đã mở rộng thêm 20px ra 4 phía
25. Xử Lí Con Trỏ Chuột Khi Di Lên Content Box Của Node?
cursor: <Kiểu Con Trỏ>;
Ta có
<Kiểu Căn>
left Mặc định, đéo làm gì
Căn phải tất cả các Node con Inline và
right Inline Block, nghĩa là gạt chúng sang bên
phải
Căn giữa tất cả các Node con Inline và
center
Inline Block
Khi có từ 2 dòng chỉ chứa Node con Inline
hoặc Inline Block trở lên, các Node này sẽ
có khoảng trống cách nhau ra để Node đầu
justify
mỗi dòng chạm cạnh trái Content Box
Node cha, và Node cuối mỗi dòng chạm
cạnh phải Content Box Node cha
= left khi thuộc tính CSS direction = ltr và =
start
right khi thuộc tính CSS direction = rtl
= left khi thuộc tính CSS direction = rtl và =
end
right khi thuộc tính CSS direction = ltr
Lưu ý tất cả kiểu căn chữ ở đây đều phụ thuộc vào điểm nhìn được xác định bởi thuộc
tính CSS writing-mode
Để chỉnh sửa căn dòng cuối cùng
text-align-last: <Kiểu Căn>;
Để thụt đầu dòng dòng đầu tiên, có thể thụt lùi, mặc định không thụt
text-indent: <Độ Thụt>;
27. Danh Sách?
display: list-item;
Khi 1 Node có thuộc tính CSS trên, nó sẽ được xem là Node Block, đồng thời được tạo
thêm 1 lớp giả marker, đứng trước cả lớp giả before, lớp giả này có các thuộc tính CSS
mặc định sau
<Kí Tự>
disc Mặc định, chấm đen,
circle Đường tròn
Đánh số từ 1. trở đi, bắt đầu từ Node có
thuộc tính CSS này, lan truyền xuống phía
dưới bằng DFS, gặp Node có thuộc tính CSS
decimal display = list-item thì đánh số, gặp Node
con cũng có thuộc tính decimal thì tạo 1
Process con, DFS bên trong Node này, bắt
đầu từ 1.
28. Định Dạng Bảng?
Các thuộc tính sau chỉ sử dụng được với Tag table
border-collapse: <Hợp Nhất Không>;
Thuộc tính này có tính kế thừa
Ta có
<Hợp Nhất Không>
seperate Các ô trong bảng sẽ có Border cho riêng nó
2 ô liền nhau trong bảng sẽ dùng chung
collapse
Border ở chỗ tiếp xúc
Để Border của các ô cách nhau 1 khoảng, mặc định sát nhau, chỉ áp dụng khi border-
collapse = separate
border-spacing: <Khoảng Cách>;
29. Flex Box?
display: flex;
Node Flex = Node Block, và khác khá nhiều thứ, nó có 2 trục là trục chính và trục phụ,
mặc định trục chính hướng từ trái sang phải, trục phụ từ trên xuống dưới
Để thay đổi chiều trục chính và trục phụ
flex-direction: <Chiều>;
Ta có
<Cách Chia>
Lấy hết phần không gian còn lại trong
space-between Node Flex, chia đều và đặt vào khe giữa
mỗi 2 Node con kề nhau
Giống space-between, nhưng trước Node
con đầu tiên và đằng sau Node con cuối
space-around
cùng sẽ có khoảng không = nửa khoảng
không giữa khe của 2 Node con liền kề
space-evenly Giống space-around, nhưng khoảng không
trước Node con đầu tiên và sau Node con
cuối cùng = khoảng không giữa khe của 2
Node con liền kề
Ta có thể thay đổi thứ tự các Node con, ví dụ biến Node con đầu tiên thành Node con
thứ 2, …
order: <Index>;
Ví dụ để biến Node con thứ 3 thành Node con thứ 5
order: 5;
1. Bố Cục?
1 File YAML thường có phần mở rộng ".yml", nó cũng giống như JSON, dùng để lưu trữ
dữ liệu, cú pháp của nó = JSON nhưng bỏ tất cả ngoặc {} và dấu phẩy ngăn cách các phần
tử, các kiểu dữ liệu cho phép là String, số, Boolean, mảng, Object, String không cần bọc
trong dấu nháy, các thuộc tính của 1 Object thì phải thụt đầu dòng so với Object và
thằng hàng nhau, khoảng cách thụt bao nhiêu cũng được, nếu là mảng thì không dùng
dấu [], mà liệt kê ra mỗi phần tử trên 1 dòng, có thụt đầu dòng, đồng thời trước phần tử
phải có 1 dấu - và từ 1 dấu cách trở lên, các dấu - này phải thằng hàng nhau, nếu muốn
chỉ định 1 Object là 1 phần tử của mảng, thì chỉ cần dùng dấu - với Key đầu tiên, ví dụ
name: John Doe
age: 35
address:
street:
ggnore: 1
ga: 5
city: Anytown
state: CA
zip: 12345
hobbies:
- reading
- hiking
- cooking:
- shit
- cock
- longlon: 1
ggnore: 1
- longcu: 5
longchim:
gaga: 8
Ở đây address là Key có nhiều thuộc tính, hobbies là mảng [reading, hiking, {cooking :
[shit, cock]}, {longlon : 1, ggnore : 1}, {longcu : 5, longchim : {gaga : 8}}]
Giá trị Boolean thì có thể viết hoa hết, thường hết hoặc viết hoa chữ cái đầu, ví dụ true,
TRUE, True
SASS:
1. Cách Tải?
npm install node-sass --save-dev
Khi này, trong thư mục con ".bin" của "node_modules", sẽ có File "node-sass.cmd"
2. Biên Dịch SCSS Ra CSS?
File SCSS có phần mở rộng là ".scss"
Để biên dịch 1 File SCSS thành 1 File CSS, dùng File "node-sass.cmd"
node_modules/.bin/node-sass.cmd <Đường Dẫn Tới File SCSS Có Phần Mở Rộng>
<Đường Dẫn Tới File CSS Có Phần Mở Rộng>
Ví dụ
node_modules/.bin/node-sass.cmd foo/bar.scss boo/bob.css
Để biên dịch tất cả các File SCSS con cấp 1 của thư mục A thành các File CSS cùng tên vào
thư mục B
node_modules/.bin/node-sass.cmd <Đường Dẫn Tới A> -o <Đường Dẫn Tới B>
Ví dụ
node_modules/.bin/node-sass.cmd foo/bar -o alice/john/bob
Để vào chế độ lắng nghe, tức nếu có thay đổi nào ở File SCSS thì nó sẽ tự động biên dịch
lại thành File CSS tương ứng, thêm cờ -w, tức là khi này sẽ có 1 Process tên "node.exe"
xuất hiện có nhiệm vụ lắng nghe các thay đổi trong các File SCSS chỉ định, ví dụ
node_modules/.bin/node-sass.cmd foo/bar.scss boo/bob.css -w
node_modules/.bin/node-sass.cmd foo/bar -o alice/john/bob -w
3. Cú Pháp SCSS?
Y chang CSS, chỉ khác là có thêm 1 số lệnh mới
Lệnh Import, trình biên dịch sẽ xử lí cái này trước
@import <Các Đường Dẫn>;
- <Các Đường Dẫn> bao gồm các đường dẫn tới các File SCSS không có phần mở rộng, mỗi
đường dẫn cách nhau dấu phẩy, bọc trong dấu nháy, khi biên dịch thì lần lượt toàn bộ
nội dung của từng File SCSS được liệt kê sẽ được đặt thẳng vào vị trí của lệnh Import kia,
thằng nào liệt kê sau thì đặt ở dưới, lệnh Import này đặt ở đâu cũng được, ví dụ
h1 {
background-color: red;
h2 {
color: red;
@import "conlon/concu1", "conlon/concu1";
}
}
- Lưu ý nếu tên File thật có dấu _ đằng trước, thì khi Import, bạn có thể bỏ 1 dấu _ này đi
Lệnh Extend
@extend <Selector>;
- Khi trình biên dịch gặp lệnh này, thì nó sẽ rà soát lại toàn bộ các khối <Selector>, và
nhóm chúng lại với khối chứa lệnh trên, ví dụ
h2 {
color: black;
}
h1 {
background-color: red;
h3 {
color: blue;
@extend h2;
}
}
h2 {
font-size: 100px;
}
- Tương đương
h2, h1 h3 {
color: black;
}
h1 {
background-color: red;
}
h1 h3 {
color: blue;
}
h2, h1 h3 {
font-size: 100px;
}
Lệnh Mixin, dùng để tạo hàm
@mixin <Tên Hàm>(<Các Tham Số>){
<Danh Sách Các Thuộc Tính CSS Có Sử Dụng Tham Số Truyền Vào>
}
- Tên hàm chỉ gồm chữ cái hoặc số hoặc dấu - hoặc _, không được bắt đầu bằng số, tên
tham số cũng vậy nhưng bắt đầu phải là kí tự $, ví dụ $foo-bar123
- Để truyền đối số cho hàm, rồi đặt phần bên trong hàm vào chính vị trí lệnh sau
@include <Tên Hàm>(<Các Đối Số>);
- Ví dụ
@mixin foo($bar, $alice){
background-color: $bar;
color: $alice;
}
h1 {
font-size: 100px;
@include foo(red, #fff);
width: 100px;
}
- Tương đương
h1 {
font-size: 100px;
background-color: red;
color: #fff;
width: 100px;
}
Lồng nhau, bạn có thể lồng phần hiện thực các Selector vào bên trong nhau để thể hiện
tính cha con, ví dụ
nav {
color: red;
ul {
list-style: none;
margin: 0;
padding: 0;
}
li {
display: inline-block;
}
}
- Tương đương
nav {
color: red;
}
nav ul {
list-style: none;
margin: 0;
padding: 0;
}
nav li {
display: inline-block;
}
Toán tử cộng 2 giá trị cùng kiểu như 1px + 2px, 1rem + 2rem, red + blue, …, toán tử trừ 2
giá trị cùng kiểu như 1px - 2px, …
Khai báo biến
<Tên Biến>: <Giá Trị>;
- <Tên Biến> phải tuân theo quy tắc như tham số hàm, nó cũng tuân theo Scope, đặt
trong Scope nào thì chỉ dùng được ở Scope đó, và phải khai báo trước khi sử dụng, ví dụ
$foo-bar123: 100px;
h1 {
width: $foo-bar123;
}
4. Normalize CSS?
Để cài thư viện Normalize CSS
npm install normalize.css
Khi này, trong File SCSS, bạn có thể dùng lệnh sau để nhúng CSS của thư viện này vào,
thư viện này bản chất là có sẵn các CSS tiêu chuẩn đẹp
@import "normalize.css";
5. Font?
Bạn có thể dùng Import với đường dẫn là URL trên mạng, thì nó sẽ tải CSS trên đường
dẫn này về
@import url(<URL Bọc Trong Nháy>);
Bạn có thể kiếm Font thông qua Link https://fonts.google.com/
Về Tab "Fonts"
- Nút "Filters" góc trái trên để ẩn hiện Panel lọc, Panel lọc gồm
a) Mục "Preview", bạn gõ thứ gì đó vào trong, thì phần bên phải sẽ hiện thị dòng chữ đó
với các Font được liệt kê
b) Thanh trượt Pixel ở dưới là Font Size
c) Mục "Language" để lọc ra các Font dành cho ngôn ngữ nào đó
- Phần bên dưới liệt kê tất cả các họ Font, bạn có thể lọc ra = cách nhập tên họ Font vào
thanh tìm kiếm trên cùng
- Click vào 1 họ Font sẽ vào phần chi tiết họ Font đó
a) Nút "Get font" để thêm họ Font này vào giỏ hàng
- Nút giỏ hàng góc phải trên, Click vào để xem giỏ hàng
a) Nút "Get embed code", Click vào, rồi Copy URL Import mong muốn, nó sẽ Import hết các
họ Font trong giỏ hàng, ở đây có hiện tên họ Font để bạn dùng cho thuộc tính font-
family trong CSS hoặc SCSS
Bootstrap:
1. Cách Tải?
Vào Link https://getbootstrap.com/docs/ để xem tài liệu, muốn thành phần nào lên đây
Copy
Tại mục "Getting started", Tab "Download"
Tùy chọn "Compiled CSS and JS", Click "Download" để tải về File nén, trong File nén này
có 1 thư mục, trong đây lại có 2 thư mục tên "css" và "js", thư mục "css" sẽ chứa tất cả
File CSS bạn cần, Link hết chúng vào HTML, tương tự File "js" chứa tất cả File JS bạn cần,
Link hết chúng vào HTML
Tùy chọn "CDN via jsDelivr", Copy 2 dòng đầu vào HTML để Link File Online
2. Thanh Điều Hướng?
Vào mục "Components", Tab "Navbar"
Electron:
1. Cách Tải?
npm install electron electron-packager electron-builder --save-dev
Khi này, trong thư mục con ".bin" của "node_modules", sẽ có File "electron.cmd",
"electron-packager.cmd", "electron-builder.cmd", Electron hoạt động khác giống Node
JS, là 1 môi trường chạy File JS
2. Chạy 1 File JS Trong Môi Trường Electron?
Dùng File "electron.cmd"
node_modules/.bin/electron.cmd <Đường Dẫn Tới File JS Không Cần Phần Mở Rộng>
Lưu ý nếu không chỉ định File JS, hoặc chỉ định nó là ".", thì Electron sẽ dò trong File
"package.json" trong thư mục làm việc hiện tại, xem có thuộc tính "main" hay không,
nếu không thì lỗi, nếu có thì sẽ chạy đường dẫn tới File JS được chỉ định bởi thuộc tính
"main" này
Khi này sẽ có 3 Process tên "electron.exe" sẽ xuất hiện, File JS dừng thì môi trường
Electron vẫn chạy
3. Tạo Ứng Dụng Trên Windows?
Trước tiên, lệnh Import sau chỉ có tác dụng trên môi trường Electron
Common Module
const <Electron> = require("electron")
ECMA Module
import <Electron> from "electron"
Ngay sau khi Import, <Electron> sẽ tự động khởi tạo để có thể sử dụng
Lệnh sau trả về 1 Promise bất đồng bộ, sẽ Fullfilled khi <Electron> khởi tạo xong
<Electron>.app.whenReady()
<Electron> sẽ có nhiều Event, mỗi Event lại có 1 Stack các Call Back sẽ được gọi lần lượt
khi Event được kích, để thêm 1 Call Back vào 1 Event
<Electron>.app.on(<Tên Event>, <Call Back>)
Ta có bảng Event sau
Trong <Electron>, bạn có thể tạo nhiều cửa sổ Windows, lệnh sau sẽ tạo ra 1 cửa sổ và
trả về <Window Object> ứng với cửa sổ này
<Electron>.BrowserWindow(<Tùy Chọn>)
<Tùy Chọn> là 1 Object viết theo Dictionary, quy định các thuộc tính của cửa sổ, nếu
<Tùy Chọn> không được chỉ định thì nó = {}
Bảng các thuộc tính của <Tùy Chọn>
Mongo DB:
1. Mongo DB Atlas?
Cái này dùng để lưu cơ sở dữ liệu trên máy chủ của nó không cần lưu trên máy của
mình, vào Link https://cloud.mongodb.com, đăng nhập = tài khoản Google
Mỗi tài khoản sẽ thuộc nhiều tổ chức khác nhau, mỗi tổ chức sẽ gồm nhiều thành viên,
trong đó có 1 người làm chủ, các chức vụ khác, cấp thấp nhất là dân đen
Mỗi tổ chức cũng sẽ có nhiều dự án khác nhau, mỗi dự án lại có nhiều Cluster
Người làm chủ 1 tổ chức sẽ có quyền tuyển thành viên vào tổ chức, xóa tổ chức, tạo xóa
dự án, dự án chỉ có thể xóa được khi tất cả Cluster trong nó bị xóa, và tổ chức chỉ có thể
bị xóa khi tất cả dự án trong nó bị xóa
Dân đen không có quyền tuyển thành viên hay xóa tổ chức hay tạo xóa dự án
Mỗi dự án bao gồm một vài thành viên trong tổ chức đảm nhận, với các chức vụ khác
nhau, có thể nhiều người có cùng 1 chức vụ, kể cả chủ dự án, và 1 người có thể đảm
nhận nhiều chức vụ khác nhau, mỗi dự án cũng bao gồm nhiều đội, nhiều cảnh báo và
nhiều cặp Key Value
Mỗi dự án sẽ bao gồm nhiều khách hàng, mỗi khách hàng có 1 khả năng khác nhau,
nhiều khách hàng có thể chung 1 khả năng
Khi mời 1 người vào dự án, mà người đó đã có trong tổ chức, thì người đó sẽ vào ngay
không cần ý kiến, nếu mời người ngoài tổ chức, thì nếu người đó chấp nhận, họ cũng sẽ
vào tổ chức luôn với tư cách dân đen
Replica Set là 1 tập hợp gồm các máy chủ ở những nơi khác nhau, lưu cùng 1 cơ sở dữ
liệu, nghĩa là nếu máy chủ này mất, thì sẽ có máy khác đảm nhận vai trò đọc ghi, khi ghi
vào 1 máy, thì các máy khác cũng ghi theo, Replica Set là 1 kiểu Cluster
Kiểu Replica Set 3 Node, thì sẽ có 1 máy Primary và 2 máy Secondary, máy Primary có
quyền đọc ghi còn 2 máy kia chỉ có thể đọc
1 Cluster sẽ đặt ở 1 khu vực nào đó, như Hồng Kông, được cung cấp bởi 1 nhà cung cấp
dịch vụ điện toán đám mây nào đó, như AWS, và có 1 dung lượng tối đa nhất định, tùy
theo loại Cluster, Cluster có các loại là M0 Sandbox, M10, …, trong đó 1 dự án chỉ có thể
có duy nhất 1 Cluster M0 Sandbox, vì nó miễn phí, những cái còn lại phải bỏ tiền
1 Cluster sẽ có nhiều cặp Key Value, và nó chỉ cho phép 1 số Modem có địa chỉ IP nhất
định có thể kết nối tới nó, theo mô hình MVC, bạn sẽ đặt các IP này là IP của máy chủ
Host trang Web của bạn, để nó có thể truy cập cơ sở dữ liệu
Về phương diện cơ sở dữ liệu, 1 Cluster sẽ bao gồm nhiều cơ sở dữ liệu, mỗi cơ sở dữ
liệu sẽ bao gồm nhiều Collection, mỗi Collection sẽ bao gồm nhiều Document, mỗi
Document giống như 1 Object viết theo Dictionary
Về giao diện, ban đầu bạn sẽ trong trang con tổ chức, Link là
https://cloud.mongodb.com/v2#/org, gồm 3 phần
Thanh trên cùng là thanh hoa tiêu
- Biểu tượng "Atlas", Click vào để về Tab "Projects"
- Mục kế bên là mục chọn tổ chức làm việc hiện tại, Click "View All Organizations" sẽ vào
trang con chỉnh sửa tổ chức tại Tab "Organizations"
- Biểu tượng bánh răng kế, Click vào để sang Tab "Settings"
- Mục "Access Manager" chọn "Organization Access" để sang Tab "Access Manager"
- Mục "Billing", Click để vào Tab "Billing"
- Mục "All Clusters", Click để vào trang con All Cluster
- Mục bên phải cùng là tên đại diện của bạn, Click vào để mở Panel cá nhân
a) Mục "Organizations", Click để vào trang con chỉnh sửa tổ chức tại Tab "Organizations"
b) Mục "Invitations", Click để vào trang con chỉnh sửa tổ chức tại Tab "Invitations"
Panel bên trái là Panel điều hướng
Phần to nhất bên phải là phần làm việc, khác nhau với mỗi Tab trong Panel điều hướng,
mọi Tab thì phần làm việc đều có phần Link điều khoản ở dưới cùng
- Về Tab "Projects", liệt kê tất cả dự án thuộc tổ chức làm việc hiện tại
a) Cột "Project Name", tên dự án, Click vào sẽ chuyển tới trang con dự án chi tiết tương
ứng
b) Cột "Clusters", số Cluster của dự án
c) Cột "Tags", hiện tất cả cặp Key Value của dự án lần lượt, Key in đậm đứng trước, Value
in nhạt đứng sau
d) Cột "Users", hiện số thành viên trong dự án, Click vào để vào trang con dự án chi tiết
tương ứng, nhưng vào phần con Project, tại Tab "Access Manager", Tab con "Users"
e) Cột "Teams", hiện số đội trong dự án, Click vào để vào trang con dự án chi tiết tương
ứng, nhưng vào phần con Project, tại Tab "Access Manager", Tab con "Teams"
f) Cột "Alerts", hiện số cảnh báo trong dự án, Click vào để vào trang con dự án chi tiết
tương ứng, nhưng vào phần con Project, tại Tab "Alerts", Tab con "Open Alerts"
g) Nút "New Project", tạo dự án mới, nhập tên dự án, các cặp Key Value + Click "Next" +
nhập Email mời người khác vào dự án, cơ chế mời đã biết, chỉnh chức vụ trong dự án
cho từng người được mời + Click "Create Project"
Về trang con dự án chi tiết, Link là https://cloud.mongodb.com/v2
Vẫn còn thanh hoa tiêu với chức năng đã biết ở trên cùng
Thêm thanh hoa tiêu phụ ở dưới
- Mục đầu tiên chọn dự án làm việc hiện tại của tổ chức hiện tại
- Nút hình người bên phải, Click để vào phần con Project, tại Tab "Access Manager", phần
mời mọc
Panel điều hướng khác so với cũ
Phần làm việc khác nhau với mỗi Tab ở Panel điều hướng và Tab ở thanh hoa tiêu phụ,
nhưng cũng đều có phần Link điều khoản phía dưới cùng và dòng trên cùng bên trái là
tên tổ chức và tên dự án làm việc hiện tại, ở dưới là tên Tab
- Về Tab "Database" ở Panel điều hướng + Tab "Data Services" ở thanh hoa tiêu phụ
a) Phần bên dưới liệt kê từng Cluster trong dự án hiện tại từ trên xuống dưới trong các
khối, góc trái trên là tên Cluster, Click vào sẽ vào phần chỉnh sửa chi tiết Cluster đó, dòng
kế cuối, mục "VERSION" là phiên bản Cluster, "REGION" là nhà cung cấp và khu vực đặt
Cluster, "CLUSTER TIER" là loại Cluster, "TYPE" là kiểu Cluster, dòng cuối là các cặp Key
Value của Cluster, ô "Data size" hiển thị dung lượng bạn đã dùng / dung lượng tối đa,
nút 3 chấm phía trên, chọn "Terminate" để xóa Cluster này, nút "Connect" góc trái trên,
Click để hiện hướng dẫn kết nối với Cluster này, ví dụ cách để kết nối sử dụng Node JS
b) Ô tìm kiếm góc trái trên, để lọc các Cluster, chọn ra các Cluster có tên chứa chuỗi được
nhập
c) Nút "Create" góc phải trên để tạo thêm Cluster, bạn sẽ chọn loại Cluster, nhà cung cấp,
khu vực, tên Cluster, các cặp Key Value, phương pháp thanh toán bằng Credit Card hoặc
Paypal
- Về Tab "Network Access" ở Panel điều hướng + Tab "Data Services" ở thanh hoa tiêu
phụ
a) Tab con "IP Access List", liệt kê tất cả địa chỉ IP có thể kết nối với các Cluster thuộc dự án
này, cột "IP Address" là địa chỉ IPv4 kèm theo Subnet Mask viết theo kiểu CIDR để mô tả
khoảng địa chỉ IP cho phép, cột "Comment" là mô tả địa chỉ IP, cột "Actions" có nút
"DELETE" để xóa địa chỉ IP này và nút "EDIT" để chỉnh sửa địa chỉ IP và mô tả, nút "ADD
IP ADDRESS" góc phải trên để thêm địa chỉ IP, viết kiểu CIDR, thêm mô tả, Tick "This
entry is temporary and will be deleted in" và chọn khoảng thời gian phù hợp để địa chỉ
IP này tự động xóa, Click "Confirm" để thêm
- Về Tab "Database Access" ở Panel điều hướng + Tab "Data Services" ở thanh hoa tiêu
phụ
a) Tab con "Database Users", liệt kê tất cả khách hàng của dự án làm việc hiện tại, cột
"User Name" là tên khách hàng, Cột "Authentication Method" là phương pháp xác thực
khi khách hàng kết nối với các Cluster của dự án, ví dụ SCRAM, cột "MongoDB Roles" là
khả năng của khách hàng, cột "Resources" là số lượng Cluster khách hàng có thể dùng,
nút "DELETE" bên phải cùng để xóa khách hàng, nút "EDIT" để chỉnh sửa thông tin khách
hàng như mật khẩu mới, khả năng mới, nút "ADD NEW DATABASE USER" góc phải trên,
để tạo khách hàng mới, nhập tên khách hàng, phương thức xác thực là sử dụng mật
khẩu hay cái khác, điền mật khẩu, khả năng, giới hạn các Cluster khách hàng này có thể
dùng, thời gian khác hàng này tồn tại trước khi bị tự động xóa
Về trang con All Cluster, Link là https://cloud.mongodb.com/v2#/clusters
Nút lá góc trái trên, Click vào để về trang con dự án chi tiết
Tên đại diện góc phải trên, cơ chế Panel cá nhân đã biết
Thanh tìm kiếm bên phải
Thanh dưới có 4 mục là thanh lọc
Phần bên dưới liệt kê tất cả Cluster của tất cả dự án của tất cả tổ chức, mỗi dự án trong
1 tổ chức sẽ liệt kê tất cả Cluster trong nó trong 1 khối
- Dòng đầu là <Tên Tổ Chức>/<Tên Dự Án>
- Cột "Name", tên Cluster
Về trang con chỉnh sửa tổ chức, Link là https://cloud.mongodb.com/v2#/preferences,
gồm 3 phần
Thanh trên cùng là thanh hoa tiêu giống với trang con tổ chức, mất 1 số nút
Panel bên trái là Panel điều hướng
Phần to nhất bên phải là phần làm việc, khác nhau với mỗi Tab trong Panel điều hướng
Về phần con Project của trang con dự án chi tiết
Về Tab "Access Manager"
- Nút "Invite to Project" góc phải trên, Click để vào phần mời mọc, tại đây bạn nhập Email
của các người bạn muốn mời vào tham gia dự án kèm theo chức vụ của họ
- Về Tab con "Users", liệt kê tất cả thành viên trong dự án làm việc hiện tại
a) Cột "Display Name", tên đại diện
b) Cột "Email Address", địa chỉ Email
c) Cột "Project Role", các chức vụ người này đảm nhận trong dự án
d) Nút hình thùng rác bên phải cùng, để xóa thành viên này ra khỏi dự án
e) Nút hình bút chì bên phải, để chỉnh sửa chức vụ của thành viên này
2. Phần Chỉnh Sửa Chi Tiết Cluster?
Góc trái trên là tên Cluster, góc phải trên là phiên bản, khu vực và loại Cluster
Về Tab "Overview"
Mục "TAGS" hiển thị các cặp Key Value của Cluster
Mục "REGION" hiển thị khu vực Cluster được đặt
- Đối với kiểu Cluster Replica Set 3 Node, thì nó sẽ liệt kê 3 Link đến phần chi tiết máy chủ
Cluster, 2 máy Secondary và 1 máy Primary
Về URI để kết nối với Cluster, bạn sẽ thấy nó trong phần hướng dẫn kết nối, lưu ý bỏ
phần Query đằng sau
mongodb+srv://<Tên Khách Hàng>:<Mật Khẩu Khách Hàng>@<Tên Cluster
Thường>.<Tên Cluster Thừa>.mongodb.net/
Có thể thấy bạn sẽ kết nối với Cluster với tư cách là 1 khách hàng nào đấy của dự án
chứa Cluster này, và do đó sẽ có thể bị giới hạn quyền đọc, viết tùy theo khả năng của
khách hàng
Khi bạn đặt tên Cluster là "FooBar123", thì đây là <Tên Cluster Thật>, còn <Tên Cluster
Thường> sẽ viết thường tất cả thành "foobar123", <Tên Cluster Thừa> là 1 chuỗi Mongo
DB Atlas đã tự thêm vào, nghĩa là tổ hợp <Tên Cluster Thường>.<Tên Cluster Thừa> là
độc nhất trên thế giới
3. Cách Tải Mongo DB Về Máy?
Cái này dùng để tạo cơ sở dữ liệu trên chính máy tính của bạn luôn, máy của bạn sẽ vừa
là Server máy chủ, vừa là máy khách
Vào Link https://www.mongodb.com/try/download/community, cuộn xuống Click
"Download" + chờ tải + chạy File vừa tải + Click "Next" + Tick chấp nhận điều khoản +
Click "Next" + chọn "Complete" + Click "Next" + bỏ Tick "Install MongoDB Compass" +
Click "Next" + Click "Install" + chờ cài đặt + Click "Finish"
Sau khi làm xong, trong thư mục "C:\Program Files" sẽ xuất hiện thư mục "MongoDB",
trong đây có thư mục "Server", trong nữa có thư mục tên phiên bản Mongo DB, trong
nữa có thư mục "bin", trong đây chứa 2 File lệnh "mongod.exe" và "mongos.exe", nên
thêm thư mục "bin" vào biến môi trường Path
4. Mongo DB Compass?
Vào Link https://www.mongodb.com/try/download/compass, cuộn xuống phần
"MongoDB Compass Download" + Click "Download" + chờ tải + chạy File vừa tải để cài
đặt và mở luôn phần mềm Mongo DB Compass
Khi này, trong thư mục "C:\Users\<Tên Người Dùng>\AppData\Local" sẽ xuất hiện thư
mục "MongoDBCompass", trong đây có File "MongoDBCompass.exe" là phần mềm
Mongo DB Compass
Về giao diện, có 2 loại cửa sổ là cửa sổ tổng quan và cửa sổ làm việc, ban đầu ở cửa sổ
tổng quan, cửa sổ làm việc sẽ chỉ làm việc trên 1 Cluster được kết nối
Về cửa sổ tổng quan
- Thanh trên cùng là thanh tiêu đề
- Thanh dưới là thanh điều hướng
a) Tab "Connect", chọn mục "Exit" = nhấn "Ctrl" + "Q", rồi nhấn "Enter" để đóng cửa sổ,
chọn mục "New Window" = nhấn "Ctrl" + "N" để mở thêm cửa sổ tổng quan mới
b) Tab "Edit", chọn mục "Settings" = nhấn "Ctrl" + "," để mở cửa sổ cài đặt
- Panel bên trái là Panel kết nối
a) Nút bánh răng, Click để mở cửa sổ cài đặt
b) Mục "Saved connections", liệt kê các Connection đã lưu, đã lưu thì khi đóng cửa sổ mở
lại vẫn còn đó, có thể Click vào để chọn Connection, nút 3 chấm bên phải mỗi
Connection, Click để hiện 3 tùy chọn, "Copy connection string" để Copy URI của
Connection này, "Duplicate" để tạo ra bản sao của Connection này và lưu nó, "Remove"
để xóa Connection, nút 3 chấm bên phải dòng "Saved connections", Click để hiện 2 tùy
chọn, "Export saved connections", bạn sẽ chọn các Connection đã lưu để xuất ra File
JSON, nút "Select a file…" để chọn nơi lưu File và tên File, mục "Encryption Password"
điền mật khẩu bất kì để mã hóa File JSON, nếu không muốn mã hóa, Tick "Remove
Secrets", khi này bạn không cần đặt mật khẩu gì hết, sau đó Click "Export" để xuất, tùy
chọn thứ 2, "Import saved connections", mục "Select a file…" bạn sẽ chọn File JSON đã
xuất, mục "Decryption Password" nhập mật khẩu mã hóa File JSON nếu có, sau đó chọn
các Connection đã lưu trong File JSON này để Import vào phần "Saved connections" rồi
Click "Import", có thể sẽ ghi đè, lưu ý nếu bạn đặt mật khẩu mã hóa cho File JSON, thì
khi Import vào các URI của các Connection sẽ được giữ nguyên, nghĩa là bao gồm luôn cả
phần mật khẩu khách hàng, nhưng nếu chọn xuất ra mà không đặt mật khẩu mã hóa, thì
khi Import vào phần mật khẩu khách hàng sẽ biến mất
c) Mục "Recents", liệt kê các Connection được kết nối gần đây
d) Nút "New connection", Click để tạo thêm Connection, các thông tin điền ở phần chỉ định
kết nối
- Panel bên phải là Panel quảng cáo
- Phần ở giữa là phần chỉ định kết nối, sẽ ứng với 1 Connection được chọn
a) Góc trái trên là tên của Connection
b) Mục "URI", điền URI của Connection, chỉ chỉnh sửa được khi gạt "Edit Connection String"
sang phải, bạn có thể điền URI của Cluster trên Mongo DB Atlas để kết nối với nó, hoặc
URI của Mongo DB Server cục bộ, với Mongo DB Atlas thì Scheme là mongodb+srv,
nhưng Scheme của cục bộ sẽ chỉ là mongodb, ví dụ mongodb://localhost:27017/
c) Nút "Save", Click rồi đặt tên cho Collection rồi lưu
d) Nút "Connect" để tiến hành kết nối với Connection này và chuyển sang cửa sổ làm việc
tương ứng
e) Nếu là tạo mới 1 Connection thì còn có thêm nút "Save & Connect" để lưu rồi kết nối
luôn
Về cửa sổ làm việc
- Thanh trên cùng là thanh tiêu đề, chứa đường dẫn tới cơ sở dữ liệu, Collection,
Document, kể từ tên Connection, ví dụ "tenconnection/coso1/collection1/doc1"
- Thanh dưới là thanh điều hướng giống cửa sổ tổng quan
- Phần dưới cùng là cửa sổ Mongo DB Shell
- Panel bên trái là Panel cơ sở
a) Nút 3 chấm góc phải trên, Click để ra các tùy chọn, "Copy connection string" để Copy URI
của Connection, "Edit favorite" để đổi tên Connection, "Connection info" để hiện cửa sổ
thông tin Cluster, "Compass Settings" để mở cửa sổ cài đặt
b) Ô "Search" và phần bên dưới, phần bên dưới liệt kê tất cả cơ sở dữ liệu của Cluster hiện
tại, chúng giống như cấu trúc thư mục, bên trong lại có các Collection giống như File, mỗi
File này lưu các Document bên trong, gõ vào ô "Search" để lọc các cơ sở dữ liệu và
Collection, cái nào mà tên chứa chuỗi được gõ thì hiển thị, bên phải mỗi cơ sở dữ liệu có
nút thùng rác, Click + nhập tên cơ sở dữ liệu này + Click "Drop Database" để xóa cơ sở
dữ liệu này, ngoài ra còn có nút dấu cộng, Click + nhập tên Collection mới + Click "Create
Collection" để tạo Collection mới, nút 3 chấm bên phải mỗi Collection, Click để hiện 3
tùy chọn, "Open in new tab", để mở Tab liệt kê Document ứng với Collection này ở phần
chỉnh sửa cơ sở, "Rename collection" để đổi tên Collection, "Drop collection", Click rồi
nhập tên Collection + Click "Drop Collection" để xóa nó
c) Mục "Databases", Click vào để mở Tab liệt kê cơ sở dữ liệu trong phần chỉnh sửa cơ sở,
nút 2 mũi tên vòng tròn bên phải để cập nhật lại dữ liệu từ Server và cập nhật lại các
thống kê, nút dấu cộng, Click + điền tên cơ sở dữ liệu mới và Collection đầu tiên trong nó
+ Click "Create Database" để tạo cơ sở dữ liệu mới
- Phần bên phải là phần chỉnh sửa cơ sở, giống VS Code
Về Tab liệt kê cơ sở dữ liệu
Tiêu đề Tab là "Databases"
Thanh trên cùng là thanh công cụ
- Nút "Create database" để tạo cơ sở dữ liệu mới, cơ chế đã biết
- Nút "Refresh" để cập nhật lại các cơ sở dữ liệu từ Server và tính toán lại các thống kê
- Mục "View", chọn biểu tượng 3 sọc để liệt kê từ trên xuống dưới, 4 ô vuông để liệt kê
theo lưới ô
- Mục "Sort by"
a) "Database Name" để sắp xếp theo tên cơ sở dữ liệu
b) "Storage size" để sắp xếp theo lượng dữ liệu mà cơ sở dữ liệu chiếm
c) "Collections" để sắp xếp theo số lượng Collection của cơ sở dữ liệu
d) "Indexes" để sắp xếp theo số lượng Index của 1 cơ sở dữ liệu
- Nút bên phải cùng, Click để thay đổi trạng thái của nó, nếu nó đang là mũi tên chĩa
xuống thì từ trên xuống sắp xếp giảm dần, ngược lại tăng dần
Phần dưới là phần liệt kê, với mỗi ô cơ sở dữ liệu liệt kê
- Nút thùng rác bên phải cùng để xóa cơ sở dữ liệu, cơ chế đã biết
- Trên cùng là tên cơ sở dữ liệu
- Mục "Storage size" là lượng dữ liệu đã chiếm
- Mục "Collections" là số Collection
- Mục "Indexes" là số Index
- Click vào 1 ô sẽ mở Tab liệt kê Collection của cơ sở dữ liệu tương ứng
Về Tab liệt kê Collection
Tiêu đề Tab là tên cơ sở dữ liệu
Thanh dưới chứa đường dẫn tới cơ sở dữ liệu, cơ chế đường dẫn đã biết
Thanh dưới là thanh công cụ
- Nút "Create collection" để tạo thêm Collection, cơ chế đã biết
- Nút "Refresh" để cập nhật lại dữ liệu từ Server và tính toán lại các thống kê
- Mục "View", tương tự như của Tab liệt kê cơ sở dữ liệu
- Mục "Sort by"
a) "Collection name", sắp xếp theo tên Collection
b) "Documents", sắp xếp theo số lượng Document của Collection
c) "Avg. document size", sắp xếp theo dung lượng trung bình của 1 Document trong
Collection
d) "Storage size", sắp xếp theo dung lượng của Collection, dung lượng Collection = tổng
dung lượng Document bị nén lại
e) "Indexes", sắp xếp theo số lượng Index của Collection
f) "Total index size", sắp xếp theo tổng dung lượng các Index của Collection
- Nút bên phải như để sắp xếp tăng dần hoặc giảm dần, cơ chế đã biết
Phần dưới là phần liệt kê, với mỗi ô Collection liệt kê
- Nút thùng rác bên phải cùng để xóa Collection, cơ chế đã biết
- Trên cùng là tên Collection
- Mục "Storage size" là dung lượng Collection
- Mục "Documents" là số Document
- Mục "Avg. document size" là dung lượng trung bình của 1 Document
- Mục "Indexes" là số lượng Index
- Mục "Total index size" là tổng dung lượng các Index của Collection
- Click vào 1 ô sẽ mở Tab liệt kê Document của Collection đó
Về Tab liệt kê Document
Tiêu đề Tab là tên Collection
Thanh dưới chứa đường dẫn tới Collection, cơ chế đường dẫn đã biết
Thanh dưới là thanh điều hướng
Phần bên dưới khác nhau với mỗi Tab ở thanh điều hướng
- Về Tab "Documents"
a) Thanh trên cùng là thanh Query, ô Input bạn sẽ nhập chuỗi Query, nút "Option" bên phải
cùng, Click để ẩn hiện Panel Projection, trong đây có mục "Project" bạn điền chuỗi
Projection
b) Thanh dưới là thanh công cụ, chùm 3 nút phải cùng là 3 chế độ hiển thị liệt kê, nút 3 sọc
là liệt kê trên xuống, nút ngoặc nhọn là liệt kê kiểu JSON, nút 4 ô vuông là liệt kê dạng
bảng, bên trái chùm 3 nút, có cú pháp <A> - <B> of <C>, tức là đang liệt kê Document có
số thứ tự là <A> đến Document có số thứ tự là <B>, trong tổng cộng <C> Document
được Query ra của Collection, nút mũi tên để thay đổi <A> và <B>, tức hiển thị liệt kê các
Document tiếp theo hoặc trước đó, nút 2 mũi tên tròn để tính toán lại các thống kê của
Document, nút "DELETE" ở giữa, Click + chọn "Delete <C> documents" 2 lần để xóa toàn
bộ Document được Query ra này
c) Phần bên dưới liệt kê tất cả Document của Collection thỏa mãn Query đã thực hiện gần
nhất, chỉ liệt kê các thuộc tính trong Document dựa vào Projection, và cách hiển thị liệt
kê tùy thuộc vào chế độ được chọn ở thanh công cụ, lưu ý chỉ liệt kê 1 vài Document khi
số lượng Document quá lớn, liệt kê phần nào tùy thuộc vào thanh công cụ
Về các kiểu dữ liệu của Value trong Document
Int32, số nguyên từ -2147483648 tới 2147483647
Int64, số nguyên từ -9223372036854775808 tới 9223372036854775807
Double, số thực bất kì với độ chính xác nhỏ, vô cực sẽ là Infinity, âm vô cực là -Infinity,
có thêm giá trị đặc biệt là NaN, tức không phải số
Boolean, true hoặc false
Null, chỉ có giá trị null
Undefined, chỉ có giá trị undefined
Decimal128, số thực bất kì với độ chính cao, vô cực sẽ là Infinity, âm vô cực là -Infinity,
có thêm giá trị đặc biệt là NaN, tức không phải số
String, chuỗi kí tự với độ dài không giới hạn
Array, mảng chứa phần tử thuộc kiểu dữ liệu bất kì
Date, 1 chuỗi chỉ định thời điểm có cú pháp sau
<Năm>-<Tháng>-<Ngày>T<Giờ>:<Phút>:<Giây>.<Mili Giây>+<Lệch Giờ>:<Lệch Phút>
- Nếu <Năm> từ 0 đến 9999, thì sẽ giữ nguyên 4 chữ số, bù 0 vào bên trái để đủ 4 số, ví dụ
1234 vẫn giữ 1234, 123 thì thành 0123, nếu <Năm> nằm ngoài khoảng này, thì nó sẽ
phải có 6 chữ số, bù 0 nếu chưa đủ 6, và thêm dấu đằng trước, + nghĩa là dương, hay sau
công nguyên, - tức là âm, hay trước công nguyên, ví dụ năm 12345 sau công nguyên sẽ
thành +012345, năm 456 trước công nguyên sẽ thành -000456
- <Tháng> phải từ 1 đến 12, nếu có 1 chữ số thì thêm 0 đằng trước
- <Ngày> phải từ 1 đến 28, 29, 30, hoặc 31 tùy vào tháng và năm, nếu có 1 chữ số thì
thêm 0 đằng trước
- <Giờ>:<Phút>:<Giây>.<Mili Giây> phải từ 00:00:00.000 đến 23:59:59.999
- <Lệch Giờ>:<Lệch Phút> tượng trưng cho múi giờ, phải từ 00:00 đến 23:59
Object, lại là 1 Object viết theo Dictionary
ObjectID, là 1 số nguyên từ 000000000000000000000000 tới ffffffffffffffffffffffff, nghĩa là
nó sẽ được biểu diễn dưới dạng thập lục phân 24 chữ số
Về dung lượng của 1 Document, nó sẽ = 5 Byte + tổng dung lượng các cặp Key Value,
dung lượng của 1 cặp Key Value = dung lượng Initial + số kí tự của Key + dung lượng
Value
Kiểu dữ liệu
Cả 2 toán hạng thuộc 1 trong 4 kiểu Int32,
So sánh số học bình thường
Int64, Double, Decimal
Cả 2 đều là String So sánh bình thường theo từ điển
1 thằng là null hoặc undefined Luôn False
6. Cách Viết Projection?
Viết như Object theo Dictionary, tất cả Value phải cùng có giá trị = 1 hoặc cùng có giá trị
=0
Nếu chuỗi Projection rỗng, tức là {}, thì hiển thị tất cả
Nếu Value Full 1, thì chỉ hiển thị các Key có trong chuỗi Projection, ví dụ
{foo: 1, bar: 1}
- Thì các Document được Query ra, chỉ hiển thị thuộc tính foo và bar của chúng, còn lại ẩn
hết
Nếu Value Full 0, thì ẩn các Key có trong chuỗi Projection, các Key còn lại hiện hết
Trường hợp 1 Value nào đó là Array, chịu ảnh hưởng của 1 phép Query trên từng phần
tử, ví dụ phép Query "trong Array này phải có ít nhất 1 phần tử < 10", thì nếu muốn, bạn
có thể chỉ hiển thị phần tử đầu tiên thỏa mãn Query, bằng cách thêm .$ vào Key, bọc
dấu nháy, Value vẫn = 1, ví dụ
{a: 1, "foo.$": 1}
Nghĩa là, chỉ hiện thị thuộc tính a và foo, trong đó foo là Array và chỉ hiện thỉ phần tử
đầu tiên thỏa mãn Query, ví dụ kết quả hiển thị có thể là
{
a: 123,
foo: [80]
}
7. Khởi Chạy Mongo DB Server Cục Bộ?
Để chỉ định đường dẫn đến thư mục Cluster, nghĩa là bây giờ ta sẽ coi 1 thư mục là 1
Cluster, gọi thư mục này là A, đồng thời khởi chạy Server luôn và kết nối với Cluster này,
mở Task Manager ra, bạn sẽ thấy có Process "mongod.exe" chính là Server
mongod --dbpath <Đường Dẫn Đến A>
<Đường Dẫn Đến A> phải đã tồn tại
Địa chỉ mặc định của Server là localhost:27017
Ví dụ
mongod --dbpath C:\data\db
1. MySQL?
Giống Mongo DB, là hệ quản trị cơ sở dữ liệu, dùng ngôn ngữ SQL, để cài đặt
Vào Link https://dev.mysql.com/downloads/mysql/, Click "Download" ứng với cái MSI
Installer + Click "No thanks, just start my download." + chờ tải + chạy File vừa tải + Click
"Next" + đồng ý điều khoản + Click "Next" + Click "Typical" + Click "Install" + chờ cài đặt +
Click "Finish" + Click "Next" 3 lần + tại mục "MySQL Root Password" điền mật khẩu đăng
nhập, gọi là Root Password, khi này tên người dùng là root + tại mục "Repeat Password"
điền lại mật khẩu + Click "Next" + Untick "Start the MySQL Server at System Startup" +
Click "Next" 3 lần + Click "Execute" + Click "Next" + Click "Finish"
Khi này trong thư mục "C:\Program Files" sẽ xuất hiện thư mục "MySQL", trong đây chứa
1 thư mục có tên là phiên bản MySQL bạn đã cài đặt, và có thể chứa nhiều thư mục ứng
với nhiều phiên bản khác nhau
Đồng thời trong thư mục "C:\ProgramData" cũng sẽ xuất hiện thư mục "MySQL", trong
đây có chứa các thư mục với tên là các phiên bản MySQL, bên trong mỗi thư mục sẽ
chứa các File và thư mục liên quan đến Database
Trong thư mục "C:\ProgramData\Microsoft\Windows\Start Menu\Programs" cũng xuất
hiện thư mục "MySQL", bên trong là 1 hoặc nhiều thư mục có tên là các phiên bản bạn
đã tải + bên trong mỗi thư mục này sẽ chứa File EXE "Command Line Client", giúp bạn
giao tiếp với MySQL
Bạn cần thêm đường dẫn "C:\Program Files\MySQL\MySQL Server 8.3\bin" vào biến môi
trường Path để có thể dùng lệnh thông qua CMD
2. Command Line Client (CLC)?
Ban đầu, nó sẽ bắt bạn nhập mật khẩu, khi này bạn sẽ nhập Root Password, sau đó nó sẽ
kết nối với Server MySQL đang chạy trên máy, nếu Server chưa chạy thì không có gì xảy
ra
Để bắt đầu chạy Server MySQL, vào ứng dụng Services (giống như khi vào Settings) +
cuộn xuống cho đến khi thấy tên MySQL + chọn nó + Click "Start the service" để chạy
hoặc "Stop the service" để đóng Server, Server sẽ được chạy ở Port 3306
Sau khi CLC đã kết nối với Server MySQL, bạn có thể bắt đầu sử dụng lệnh của ngôn ngữ
SQL
3. PopSQL?
Là giao diện thân thiện với người dùng, dùng để giao tiếp với Server MySQL chạy trên
máy bạn, ngon hơn CLC, để cài đặt
Vào Link https://popsql.com/download, Click "Download for Windows" + chờ tải + chạy
File vừa tải + thoát
Khi này, trong thư mục
"C:\Users\<Tên Người Dùng Hiện Tại>\AppData\Local\Programs" sẽ xuất hiện thư mục
"@popsqldesktop", trong đây lại chứa File EXE "PopSQL" là phần mềm bạn muốn chạy
Sau đó, chạy phần mềm PopSQL lên, đăng nhập bằng tài khoản Google + nó chuyển
hướng đến trang đăng ký + điền thông tin + xác nhận Email + mở lại phần mềm PopSQL
rồi đăng nhập bằng tài khoản Google hồi nãy + điền tên công ty + điền số người trong
công ty + Click "Create organization" + Click "Skip this" + chọn 1 vài thông tin cá nhấn +
Click "Next" + chọn mục tiêu làm việc hôm nay + Click "Next" + Click "Start querying" +
đóng phần mềm
Như vậy là xong bước cài đặt, từ giờ chỉ cần mở phần mềm và làm việc
4. Cấu Trúc Database Trong MySQL?
1 Port sẽ chứa nhiều Database, mỗi Database là 1 thư mục, và mỗi cái lại chứa nhiều
bảng, mỗi bảng là 1 File có phần mở rộng là ".ibd"
Nếu bạn lưu Database trong máy, ứng với localhost và Port 3306, thì các Database ứng
với Port này được lưu trong thư mục "C:\ProgramData\MySQL\<Phiên Bản MySQL>\
Data"
5. Cách Dùng PopSQL?
Cửa sổ PopSQL bao gồm thanh tác vụ trên cùng và thanh công cụ bên trái, khi Click vào 1
biểu tượng ở thanh công cụ thì cửa sổ tương ứng với công cụ đó sẽ hiện trồi ra hoặc rút
vào
Quá tình làm việc với PopSQL sẽ giống như chỉ làm trên 1 dự án duy nhất, bạn không cần
nhấn lưu File hay gì hết, tất cả tự động lưu và mỗi khi bạn mở PopSQL lên thì sẽ tiếp tục
với phần việc dở dang trước đó
Phần 1, cài đặt
Để vào cài đặt
Vào Tab "File" + chọn "Preferences…" = nhấn "Ctrl" + ","
Để thoát cài đặt, Click "Preferences" to đùng
Phần 2, danh sách có thể kết nối, nằm trong phần cài đặt
Để vào danh sách có thể kết nối, vào thẻ "Connections"
Để thêm 1 Port vào danh sách có thể kết nối, lưu ý bản PopSQL Free chỉ được phép có
tối đa 2 Port trong danh sách
Click "New connection" + chọn "MySQL" + tại mục "Connection name" điền tên sẽ hiển
thị ở danh sách có thể kết nối, tạm gọi là tên kết nối + tại mục "Hostname/Port" lần lượt
điền tên miền và Port lưu trữ các Database, nếu cục bộ thì điền localhost và Port 3306 +
tại mục "Database" điền tên Database muốn kết nối + tại mục "Username/Password"
điền tên người dùng và mật khẩu, tên người dùng và mật khẩu này phải có quyền truy
cập vào các Database tại Port, ví dụ root và matkhau123 + tại mục "Connection Type"
gạt sang phải để chỉ định Port nằm trên máy mình + Click "Save"
Phần 3, bố cục, vào Tab "Schemas" ở thanh công cụ
Ở đây sẽ hiển thị bố cục tổng thể của 1 Database nào đó
Bước 1, chọn tên kết nối ứng với Port chứa Database muốn hiện bố cục
Bước 2, chọn Database muốn hiện bố cục
Bước 3, xem bố cục ở bên dưới
Bạn có thể đồng bộ lại cấu trúc Database bằng cách Click biểu tượng 2 mũi tên tròn bên
phải tên kết nối, khi này PopSQL sẽ cập nhật các File và thư mục trong Port tương ứng
vào trong PopSQL
Phần 4, mẫu hỏi, nằm ở Tab "Queries" ở thanh công cụ
Mẫu hỏi tương đương 1 File, chạy File này sẽ trích xuất dữ liệu trong Database nào đó và
hiển thị lên màn hình PopSQL, phần bên trái là Code, bên phải là màn hình thông báo kết
quả chạy lệnh
Dự án bao gồm 3 thư mục to nhất là "Team queries", các File nằm ở đây sẽ được dùng
chung bởi tất cả thành viên trong công ty, "My queries", chỉ có người dùng hiện tại mới
truy cập được, "Drafts", các bản nháp
Để tạo 1 File mẫu hỏi trong 1 thư mục, Click dấu cộng bên phải thư mục đó + chọn "New
query" để tạo 1 File mẫu hỏi, hoặc chọn "New folder" để tạo 1 thư mục con + đặt tên
File hoặc thư mục
Để chỉnh sửa 1 File mẫu hỏi, Click vào File đó, khi này Tab ứng với nó sẽ được chèn vào
thanh trên cùng, Click dấu x trên Tab để đóng File tương ứng
Để chạy 1 File mẫu hỏi trên 1 Database nào đó
Bước 1, vào Tab của nó
Bước 2, chọn tên kết nối ứng với Port chứa Database đích, nằm ở góc phải trên
Bước 3, chọn Database đích trong Port này, nằm ở góc phải trên
Bước 4, Click mũi tên chỉ xuống bên phải nút "Run" + Tick "Run all statements" nếu
muốn chạy nguyên File mẫu hỏi, Untick nó để chỉ chạy câu lệnh ở vị trí con trỏ văn bản
hoặc nguyên đoạn Code đang được bôi đen
Bước 5, Click nút "Run", Database sẽ bị thay đổi trực tiếp
Phần 5, tạo File Database thủ công
Không được tạo hay thay đổi File Database thủ công, khi này bạn sẽ không được phép
chạy Server MySQL, tất cả phải thông qua lệnh
6. Cú Pháp SQL?
Không phân biệt hoa thường
Kết thúc lệnh bằng chấm phẩy
String được đặt trong cặp dấu nháy đơn hoặc kép
7. Tạo 1 Database Mới?
create database <Tên Database>;
Khi này trong Port sẽ xuất hiện thư mục rỗng có tên là <Tên Database> nếu chưa tồn tại,
và báo lỗi nếu đã tồn tại
Ví dụ
create database foo;
8. Các Kiểu Dữ Liệu?
varchar(<Số Kí Tự Tối Đa>)
<Số Kí Tự Tối Đa> phải là số nguyên trong đoạn từ 0 đến 16383
Giá trị hợp lệ là String với số kí tự không vượt quá <Số Kí Tự Tối Đa>
int
Giá trị hợp lệ là số nguyên có dấu 32 Bit, nằm trong đoạn từ -2147483648 tới
2147483647
Giá trị mặc định cho 1 ô trong bảng là null
9. Tạo 1 Bảng Rỗng?
create table <Tên Bảng>(<Các Cột>);
<Các Cột> ngăn cách nhau bởi dấu phẩy, mỗi cột sẽ có cú pháp
<Tên Cột> <Kiểu Dữ Liệu> <Hiệu Ứng>
<Hiệu Ứng> có thể có hoặc không
Đồng thời ta có thể chỉnh định các cột nào sẽ làm khóa chính bằng cách đặt lệnh sau vào
bất kì chỗ nào trong <Các Cột>
primary key(<Tên Các Cột Làm Khóa Chính>)
Các cột làm khóa chính không được phép chứa dù chỉ 2 tổ hợp giá trị giống nhau, ví dụ
cột A và B làm khóa chính, thì không được phép có 2 bản ghi mà thuộc tính A của chúng
đều = 2 và B của chúng đều = 5, nhưng sẽ hợp lệ khi 1 thằng có A = 2, B = 5, 1 thằng có A
= 3, B = 5
Các cột làm khóa chính sẽ phân ra khóa cấp 1, cấp 2, … dựa theo thứ tự ghi trong <Tên
Các Cột Làm Khóa Chính>
Mỗi khi chèn 1 bản ghi vào bảng, thì nó sẽ được đặt ở vị trí sao cho khóa cấp 1 tăng dần
từ trên xuống, nếu 2 giá trị bằng nhau, thì sắp xếp tăng dần theo khóa cấp 2, nếu 2 giá trị
trong khóa cấp 2 bằng nhau, thì tiếp tục xét đến khóa cấp 3, …
Ví dụ
primary key(bar, alice, john)
Thì bar là khóa cấp 1, alice cấp 2, john cấp 3
Bạn cũng có thể đặt cụm từ primary key ở cột làm khóa chính, khi này chỉ được phép đặt
ở 1 cột, nghĩa là khóa chính chỉ gồm 1 cột
Danh sách <Hiệu Ứng>
Báo lỗi khi chèn thêm 1 bản ghi mà thiếu giá trị của cột này
Nếu bạn đã tạo bảng rồi, và nó có vài bản ghi rồi, mà bạn lại tạo
not null
cột mới có hiệu ứng này, thì giá trị cột này thay vì là null sẽ = 0
nếu kiểu số nguyên và = "" nếu là String
Báo lỗi khi chèn thêm 1 bản ghi mà giá trị của cột này bị lặp
unique
Cho phép giá trị null có thể bị lặp
Khi chèn thêm 1 bản ghi mà không chỉ định giá trị của cột này thì
default <Giá Trị>
mặc định nó có giá trị là <Giá Trị>
auto_increment Cột có hiệu ứng này phải thuộc khóa chính, và là khóa cấp 1, có
kiểu dữ liệu số nguyên
Khi chèn thêm 1 bản ghi mới mà không có chỉ định giá trị cho cột
này, thì giá trị của nó tự động = giá trị lớn nhất hiện tại của cột
này + 1, nếu đang là giá trị tối đa của kiểu dữ liệu tương ứng thì
không tăng
Cho 1 bảng đã có vài bản ghi, nếu bạn chèn thêm cột có hiệu ứng
này vào thì cột đó sẽ tự động đánh số tăng dần từ 1
Khi này trong thư mục Database hiện tại sẽ xuất hiện File có tên là
"<Tên Bảng>.ibd" nếu chưa tồn tại, và báo lỗi nếu đã tồn tại
Ví dụ tạo bảng foo, có 3 cột là bar, alice và john, trong đó bar và alice làm khóa chính,
bar là cột số thứ tự, john là cột có giá trị mặc định 4
create table foo(
bar int auto_increment,
primary key(bar, alice),
alice varchar(100),
john int default 4
);
Ví dụ khóa chính chỉ gồm 1 cột là bar
create table foo(
bar int auto_increment primary key,
alice varchar(100),
john int default 4
);
Để hiện thị thông tin về toàn bộ cột của bảng, như tên cột, kiểu dữ liệu, giá trị mặc định,
…
describe <Tên Bảng>;
Để xóa 1 bảng ra khỏi thư mục Database
drop table <Tên Bảng>;
Nếu không tồn tại bảng để xóa thì báo lỗi
10. Thêm 1 Cột Mới Vào Bảng?
alter table <Tên Bảng> add <Thông Tin Cột Mới>;
Bản chất là đặt nguyên cái <Thông Tin Cột Mới> vào cuối phần cấu hình khi bạn create
table
Ví dụ
create table foo(
alice int,
john varchar(10),
primary key(alice)
);
alter table foo add bar int not null;
Tương đương
create table foo(
alice int,
john varchar(10),
primary key(alice),
bar int not null
);
11. Xóa 1 Cột Trong Bảng?
alter table <Tên Bảng> drop column <Tên Cột Muốn Xóa>;
Ví dụ
alter table foo drop column bar;
12. Thêm 1 Bản Ghi Vào Bảng?
insert into <Tên Bảng> values(<Tất Cả Các Giá Trị Của Các Cột>);
Ví dụ
insert into foo values(20, "daubuoi", 4);
Để thêm 1 bản ghi mới nhưng chỉ xác định giá trị cho 1 số cột thay vì toàn bộ
insert into <Tên Bảng>(<Tên Các Cột>) values(<Giá Trị Các Cột Tương Ứng>);
Ví dụ
insert into foo(bar, alice) values(4, "daubuoi");
13. Trích Xuất Các Cột Và Bản Ghi Trong Bảng Thỏa Mãn Điều Kiện Gì Đó Rồi In Ra Màn
Hình?
Để trích xuất 1 số cột
select <Tên Các Cột> from <Tên Bảng>;
Các cột sẽ sắp đúng thứ tự trong <Tên Các Cột>
Ví dụ
select alice, bar from foo;
Nếu <Tên Các Cột> là *, thì tương đương trích xuất tất cả cột, hay toàn bộ bảng
Ví dụ
select * from foo;
Bạn cũng có thể đổi tên cột khi trích xuất ra bằng cú pháp
<Tên Cột Cũ> as <Tên Cột Mới>
Ví dụ
select alice as kenny, bar as bob from foo;
Để trích xuất 1 số bản ghi từ trích xuất cột
select <Tên Các Cột> from <Tên Bảng> where <Điều Kiện>;
Ví dụ
select bar, alice from foo where john = 5 and bob <> 9;
Nghia là trích xuất cột bar và alice trong bảng foo, từ 2 cột này, trích những hàng mà có
ô john = 5 và ô bob khác 9
Để trích xuất sau đó sắp xếp các cột theo thứ tự nào đó
select <Tên Các Cột> from <Tên Bảng> where <Điều Kiện>
order by <Chiều Sắp Xếp Các Cột>;
<Chiều Sắp Xếp Các Cột> là 1 dãy các phần tử có cú pháp sau
<Tên Cột> <Tăng Hay Giảm Dần>
<Tăng Hay Giảm Dần> chỉ có thể là asc hoặc desc, asc là tăng dần, desc là giảm dần
Nếu không chỉ định <Tăng Hay Giảm Dần> thì nó mặc định là asc
Thứ tự ưu tiên sắp xếp theo đúng thứ tự cột ghi trong <Chiều Sắp Xếp Các Cột>
Ví dụ
select bar, alice from foo order by john desc, alice;
Nghĩa là sắp xếp lại bảng foo thành 1 bảng sao cho cột john của nó giảm dần, nếu 2 giá
trị bằng nhau thì xét đến cột alice tăng dần, sau đó trích xuất cột bar và alice từ bảng đã
sắp xếp này
Để chỉ lấy N cột trích xuất đầu tiên
select <Tên Các Cột> from <Tên Bảng> where <Điều Kiện>
order by <Chiều Sắp Xếp Các Cột> limit <N>;
Ví dụ
select bar, alice from foo order by alice limit 10;
Tức là trích xuất cột bar và alice từ bảng foo, sau đó sắp xếp tăng dần theo alice rồi cắt
lấy 10 bản ghi đầu tiên
Để kết quả trích xuất không có 2 bản ghi nào có tổ hợp giá trị hoàn toàn giống nhau thì
thêm distinct vào trước <Tên Các Cột>
Ví dụ
select distinct bar, alice, john from foo;
Nghĩa là giả sử trích xuất được các tổ hợp giá trị là (4, 5, 6), (4, 5, 6), (4, 5, 7) thì sẽ chỉ
còn (4, 5, 6), (4, 5, 7)
14. Cập Nhật Lại Giá Trị Cho 1 Số Ô Thỏa Mãn Điều Kiện Nào Đó Trong Bảng?
update <Tên Bảng> set <Các Lệnh Gán Lại Giá Trị> where <Điều Kiện>;
ví dụ
update foo set bar = 4, alice = "haha" where john = 6 or bob > 8;
Lệnh trên nghĩa là xét trong bảng foo, hàng nào có ô ứng với cột john có giá trị = 6 hoặc
ô ứng với cột bob có giá trị > 8 thì ô ứng với cột bar của hàng đó sẽ bị chuyển thành 4 và
ô ứng với cột alice sẽ bị chuyển thành "haha"
Nếu không có vế where, thì tương đương tất cả các ô trong cột sẽ bị thay đổi giá trị
Ví dụ
update foo set bar = 4, alice = "haha";
Tất cả các ô thuộc cột bar sẽ có giá trị = 4 và các ô thuộc cột alice sẽ có giá trị là "haha"
15. Xóa 1 Số Bản Ghi Thỏa Mãn Điều Kiện Nào Đó Trong Bảng?
delete from <Tên Bảng> where <Điều Kiện>;
Ví dụ
delete from foo where bar = 6 and alice >= 8;
Nghĩa là xóa tất cả bản ghi trong bảng foo nếu bản ghi đó có ô ứng với cột bar mang giá
trị 6 và ô ứng với cột alice mang giá trị >= 8
Nếu không có vế where thì xóa hết mẹ bản ghi trong bảng
Ví dụ
delete from foo;
16. Toán Tử?
= Bằng
<> Khác
>= Lớn hơn hoặc bằng
Tương đương biểu thức
A in (B, C, D, …)
A = B or A = C or A = D or …
Tương đương biểu thức
A=B
A like B
Trong đó B phải là 1 String Regex, A tự
động được ép kiểu sang String
B là trích xuất gồm duy nhất 1 cột
Trả về True nếu chỉ cần A có giá trị = 1 ô
A in (B) trong B, nếu không thì False
Ví dụ
foo in (select bar from bob)
B là trích xuất gồm duy nhất 1 ô
Trả về True nếu A có giá trị = ô này, nếu
A = (B) không thì False
Ví dụ
foo = (select count(bar) from bob)
Regex
Sandbox:
1. Sandbox?
Là nơi thực thi Code mà không sợ ảnh hưởng tới môi trường xung quanh, nghĩa là mã
độc sẽ vô tác dụng
2. WASM (Web Assembly)?
Giả sử bạn muốn chạy Code C++ trên trình duyệt, thì khi này, đoạn Code bạn nhập vào
sẽ được gửi đến máy chủ, sau đó nó biên dịch thành mã WASM và được lại trình duyệt
của bạn để chạy, nghĩa là nó khá giống JS, nhưng ngôn ngữ bậc thấp hơn
React:
1. Cách Tải?
Đặt Tag Script vào File HTML, đây là React dành cho phát triển, có tích hợp thêm vài hàm
phục vụ cho Debug
<script src = "https://unpkg.com/react@<Phiên
Bản>/umd/react.development.js"></script>
Tương tự như trên, nhưng dùng khi triển khai dự án, đã được tối giản
<script src = "https://unpkg.com/react@<Phiên
Bản>/umd/react.production.min.js"></script>
Khi này bạn có thể dùng được biến toàn cục React, để trả về String phiên bản React
React.version
Đặt Tag Script vào File HTML, đây là React DOM dành cho phát triển, lưu ý phiên bản =
phiên bản của React, phải đặt sau Tag Script của React
<script src = "https://unpkg.com/react-dom@<Phiên Bản>/umd/react-
dom.development.js"></script>
Tương tự như trên, nhưng tối giản
<script src = "https://unpkg.com/react-dom@<Phiên Bản>/umd/react-
dom.production.min.js"></script>
Khi này bạn có thể dùng được biến toàn cục ReactDOM
2. Tạo React Element?
Lệnh sau sẽ trả về 1 Object, tạm gọi là <React Element>
React.createElement(<Type>, <Props>, <Các React Element Con>)
<Type> phải là String hoặc hàm, chính là thuộc tính Type của <React Element>
<Props> là null hoặc 1 Object viết theo Dictionary, nó chính là thuộc tính Props của
<React Element>, nếu không chỉ định thì = null
<Các React Element Con> không chỉ định cũng được, các React Element được liệt kê ở
đây sẽ trở thành con của <React Element>, chúng có thể là String
Ví dụ
const foo = React.createElement(
"ggnore", {concac: 1, daubuoi: 2},
React.createElement("haha"),
React.createElement("haha", null),
"concucac"
)
3. Tạo React DOM Root?
Lệnh sau sẽ trả về 1 Object, tạm gọi là <React DOM Root>, nó sẽ ứng với 1 Node trong
DOM
ReactDOM.createRoot(<DOM Element>)
Ví dụ
const root = ReactDOM.createRoot(document.getElementById("ggnore"))
Để Node tương ứng với <React DOM Root> trong DOM bị mất hết Node con, thay vào
đó là 1 <React Element>, khi này thuộc tính Type của <React Element> sẽ là tên Tag,
thuộc tính Props bao gồm các cặp Key Value chính là thuộc tính của Tag, và các React
Element con cũng được triển khai tương tự
<React DOM Root>.render(<React Element>)
4. JSX?
Để sử dụng cú pháp JSX, trước tiên cần đặt Tag Script sau vào File HTML để sử dụng thư
viện Babel
<script src="https://unpkg.com/babel-standalone@<Phiên Bản>/babel.min.js"></script>
Code của thư viện trên sẽ chỉ được chạy sau khi DOM tải xong, nên bạn đặt Tag Script
trên chỗ nào cũng được, khi Code của thư viện này chạy, nó sẽ dò tất cả Tag Script của
DOM, gặp Tag Script A nào có thuộc tính type = "text/babel", nó sẽ ngay lập tức thêm 1
Tag Script B vào cuối Node Head, lưu ý A sẽ không bao giờ được chạy do thuộc tính type
của nó không phải "text/javascript", B có được bằng cách biên dịch A từ JSX sang JS
thông thường và B sẽ có thuộc tính type = "text/javascript", do được thêm bằng
document.createElement, nên thời khắc thêm, B sẽ chạy ngay lập tức, lưu ý cần có thư
viện React và React DOM do Babel biên dịch ra cú pháp JSX sang React Element
Về cú pháp JSX, bạn có thể viết HTML ngay bên trong Code, và nó tự biên dịch thành
React.createElement, ví dụ
const foo = <ul>
<li>foo</li>
<li>bar</li>
<ul>
Trong chuỗi HTML trên, bạn có thể lồng vào nó Code JS, giống như nội suy, bằng cách
đặt Code JS vào cặp dấu {}, ví dụ
const foo = <div>ggnore{"haha" + 1}</div>
Tương đương
const foo = <div>ggnorehaha1</div>
Nếu giá trị nội suy thuộc kiểu Boolean, Undefined, Null, Symbol, Function thì không hiển
thị, còn là Number hoặc String thì sẽ ép về String để hiển thị, nếu là Object thì lỗi, nếu là
1 React Element thì hiển thị, nếu là Array thì phần tử nào hiển thị được thì hiển thị, tuy
nhiên, mỗi phần tử trong Array, nếu là 1 React Element thì tất cả chúng phải có thuộc
tính Props, và trong Props phải có thuộc tính key, với giá trị độc nhất không giống các
React Element còn lại trong Array
Khi chỉ định thuộc tính cho Tag bằng JSX, thì giá trị của thuộc tính có thể viết bằng String,
hoặc phải bằng kiểu dữ liệu khác, tùy vào thuộc tính, và tên thuộc tính có thể bị thay đổi
- Với các thuộc tính sự kiện, ví dụ onclick, onmouseup, …, thì phải viết theo Camel Case, ví
dụ onClick, onMouseUp, và giá trị của chúng phải viết = Call Back, ví dụ
const foo = <span onClick = {(e) => console.log(9)}>ggnore</span>
- Với thuộc tính style, phải viết = Object theo Dictionary, và các thuộc tính CSS phải viết
theo Camel Case, ví dụ
const foo = <span style = {{color: "red", fontSize: "16px"}}>ggnore</span>
- Với thuộc tính for của Tag Label, phải đổi nó thành htmlFor
- Với thuộc tính class, phải đổi nó thành className
- Mọi Tag có thể thêm thuộc tính ref, giá trị của nó phải là tham chiếu đến 1 Object có
thuộc tính current, một khi Tag này được Mount vào DOM, thì thuộc tính current của
Object này sẽ được gán giá trị = tham chiếu đến Tag này, tức DOM Element
Có thể dùng toán tử Spread để ghi nhanh các thuộc tính trong Tag, ví dụ
const foo = {
id: "thanglon",
className: "ggnore"
}
const bar = <span {...foo}>haha</span>
5. Function Component?
Là 1 hàm trả về 1 React Element, khi này bạn có thể dùng cú pháp JSX với Function
Component như sau
<<Function Component> <Các Đối Số> />
Lệnh trên sẽ trả về 1 React Element, là thứ được trả về bởi <Function Component> sau
khi xử lí <Các Đối Số>
<Các Đối Số> viết giống thuộc tính của Tag, kiểu dữ liệu gì cũng được, nếu không phải là
String thì phải bọc trong cặp dấu {}, khi này thứ được truyền vào <Function Component>
sẽ là 1 Object viết theo Dictionary, tuy nhiên, đối số có Key là ref trong <Các Đối Số> sẽ
không được truyền vào, để có thể truyền vào ref, ta phải dùng lệnh sau, lệnh này sẽ trả
về 1 Function Component có khả năng được truyền ref, nhưng ref không truyền vào
trong Object đầu tiên, mà nó sẽ được truyền với tư cách là đối số thứ 2
React.forwardRef(<Function Component>)
Tên của <Function Component> phải bắt đầu = 1 chữ cái viết hoa
Ví dụ 1
function Foo(bar){
console.log(bar.ref) // Dòng này in ra undefined, do ref không thể truyền vào
return <div>{bar.alice + bar.john}</div>
}
<Foo alice = "haha" john = {1} ref = {456} />
- Dòng cuối ở ví dụ trên trả về <div>haha1</div>
Ví dụ 2
function Foo(bar, naruto){
console.log(naruto) // Dòng này in ra 456
return <div>{bar.alice + bar.john}</div>
}
const Boo = React.forwardRef(Foo)
<Boo alice = "haha" john = {1} ref = {456} />
Ta có thể sử dụng cặp Tag Function Component, phần ở giữa sẽ là thuộc tính children
của Object truyền vào, lưu ý phần ở giữa chỉ là đối số, nên nó không được hiển thị, nếu
phần ở giữa chỉ có 1 thằng, thì children = giá trị thằng đó, nhưng nếu nó là nhiều React
Element, thì children sẽ là Array chứa các React Element đó, ví dụ
function Foo(bar){
console.log(bar.children)
return <span></span>
}
<Foo>ggnore<span>haha</span></Foo>
- Màn hình Console sẽ là 1 Array gồm phần tử thứ nhất là "ggnore", thứ 2 là React
Element <span>haha</span>
Lệnh sau trả về 1 Function Component, nó vô hình, tức chỉ có tác dụng bọc các React
Element lại với nhau
React.Fragment
Ví dụ
const foo = <React.Fragment>
<span>foo</span>
<span>bob</span>
</React.Fragment>
Có thể viết ngắn gọn cặp Tag React.Fragment thành <> và </>, ví dụ
const foo = <>
<span>foo</span>
<span>bob</span>
</>
Lệnh sau cũng trả về 1 Function Component vô hình, nhưng nó sẽ khiến cho các Function
Component con của nó phải viết với cú pháp như trong Strict Mode, đồng thời nếu trong
chế độ phát triển thì nó sẽ được Render 2 lần mỗi lần Render lại
React.StrictMode
6. Thư Viện React Và React DOM Với Node JS?
Thư viện React
Để cài đặt
npm install react
Để Import
- Common Module
const <React> = require("react")
- ECMA Module
import <React> from "react"
Thư viện React DOM
Để cài đặt
npm install react-dom
Để Import
- Common Module
const <React DOM> = require("react-dom/client")
- ECMA Module
import <React DOM> from "react-dom/client"
7. Thư Viện CRA (Create React App)?
Để cài đặt
npm install create-react-app
Khi này, trong thư mục con ".bin" của "node_modules", sẽ có File "create-react-
app.cmd"
Để tạo 1 dự án React, ta sẽ dùng File "create-react-app.cmd"
node_modules/.bin/create-react-app.cmd <Tên Dự Án>
Khi này, trong thư mục làm việc hiện tại sẽ xuất hiện thư mục con có tên là <Tên Dự Án>
Bên trong nó là cấu trúc đầy đủ của 1 dự án React, bao gồm
- File "README.md", là File hướng dẫn
- File "package.json" và "package-lock.json", cơ chế đã biết, ở đây nó cài các thư viện sau
và thêm 1 số thư viện đéo cần quan tâm khác
a) React
b) React DOM
c) React Scripts, trong File "package.json" cũng đã ghi sẵn các lệnh để chạy React Scripts,
bao gồm "npm start" = "react-scripts start", "npm rub build" = "react-scripts build"
- File ".gitignore", nó Ignore thư mục "node_modules", "build" và 1 số thứ khác
- Thư mục "src", chứa File "index.js" là ngõ vào chương trình, kèm theo 1 số File khác có
thể xóa đi nếu muốn
- Thư mục "public" chứa File "index.html" là ngõ vào chương trình, kèm theo 1 số ảnh
khác có thể xóa nếu muốn
- Thư mục "node_modules" chứa các thư viện
Tóm lại, bây giờ bạn có thể tiến hành phát triển, sử dụng React Scripts để Build
8. Hook?
Là các hàm như useState, useEffect, …, chỉ được sử dụng trong Function Component, ta
phải tuân theo các quy tắc sau
Các lệnh Hook phải đặt ở Scope cao nhất trong Function Component, ví dụ sau là đúng
function foo(){
const [state1, setState1] = React.useState(1) // Scope cao nhất
const [state2, setState2] = React.useState(2) // Scope cao nhất
return <span>gg</span>
}
- Ví dụ sau là sai
function foo(){
if (true){
const [state1, setState1] = React.useState(1) // Đặt trong Scope của if
}
const [state2, setState2] = React.useState(2) // Scope cao nhất
return <span>gg</span>
}
Về Hook useState, lệnh sau sẽ trả về 1 Array có đúng 2 phần tử, phần tử thứ nhất tạm
gọi là <State>, thứ 2 gọi là <Set State>
<React>.useState(<Giá Trị Khởi Đầu>)
Lần đầu Function Component được Render, lệnh trên sẽ tạo ra 1 State bên trong
Function Component, có giá trị = <Giá Trị Khởi Tạo>, nếu nó là 1 Call Back, thì Call Back
này sẽ được gọi, giá trị trả về cũng sẽ được gán cho State bên trong, <State> cũng sẽ =
giá trị của State bên trong, còn <Set State> là 1 hàm có tác dụng ta sẽ nói sau
Khi có 1 Call Back A bất kì nào đó được trình duyệt chạy, mà trong đó có sử dụng hàm
<Set State>, thì sẽ có cơ chế như sau, <Set State> là 1 hàm nhận 1 đối số, khi nó được
gọi, thì State bên trong Function Component tương ứng sẽ bị thay đổi = giá trị của đối
số, nếu đối số này là 1 Call Back B, thì B sẽ được gọi, được truyền vào 1 đối số là giá trị
hiện tại của State bên trong Function Component tương ứng, giá trị trả về của B sẽ được
gán lại cho State bên trong, trong suốt quá trình A chạy, thì sẽ có 1 đồ thị biến động
State bên trong vì có thể có nhiều lần <Set State> được gọi, sau khi A chạy xong, nó sẽ
phân tích đồ thị biến động này, nếu có ít nhất 1 biến động hoặc bộ các State bên trong
ngay sau lần Render gần nhất khác với bộ các State bên trong ngay sau lần Render gần
nhì, thì Function Component sẽ Render lại 1 lần, tức bị gọi lại 1 lần, và khi này, lệnh
useState ở trên sẽ bị lơ đi, tuy nhiên phần <Giá Trị Khởi Đầu> vẫn được tính toán 1 cách
vô nghĩa nếu nó là biểu thức, còn nếu nó là Call Back thì Call Back không được gọi, khi
này <State> lệnh trên trả về sẽ = State bên trong hiện tại của Function Component
Có thể tạo ra nhiều State bên trong cùng lúc, cho dù dùng <Set State> tùm lum, nhưng
chỉ cần đặt chung trong 1 Call Back thì phải đợi Call Back chạy xong mới Render lại 1 lần
Ví dụ
function App() {
const [a, seta] = React.useState(1)
const [b, setb] = React.useState(2)
const [c, setc] = React.useState(3)
console.log(a)
console.log(b)
console.log(c)
function foo(){
seta(a + 1)
setb(prev => prev + 1)
setc(c + 2)
setc(prev => prev + 3)
}
Webpack:
1. Cách Tải?
npm install webpack webpack-cli
Khi này, trong thư mục con ".bin" của "node_modules", sẽ có File "webpack.cmd"
2. Gộp Chung Nhiều File JS Liên Quan Thành 1 File JS Duy Nhất?
Đảm bảo trong thư mục làm việc không có File nào tên "webpack.config.js", rồi chạy
lệnh sau, dùng File "webpack.cmd"
node_modules/.bin/webpack.cmd --entry <File Entry> --output-filename <Tên File
Output> --output-path <Thư Mục Lưu> --mode <Mode>
<File Entry> là đường dẫn tới File JS không cần phần mở rộng, tương đối hoặc tuyệt đối,
đây sẽ là File đầu vào của chương trình, nó có thể Import nhiều File xung quanh, nếu
không chỉ định thì mặc định = "./src/index"
<Tên File Output> là tên File JS có phần mở rộng, chính là 1 File duy nhất được gộp bởi
tất cả File JS trong dự án, bắt đầu từ File đầu vào, nếu không chỉ định thì mặc định =
"main.js"
<Thư Mục Lưu> là đường dẫn tới thư mục để lưu File gộp, tuyệt đối hoặc tương đối, nếu
không chỉ định thì mặc định = "./dist"
<Mode> nếu là production, thì File JS gộp sẽ được tối giản hóa, nếu là development thì
không, dễ đọc Code hơn, nếu không chỉ định thì = production
Lưu ý đây chỉ là lệnh biên dịch, tức nó đéo quan tâm Code có chạy hay không, đồng thời
các lệnh import, require, module.exports, export, bạn muốn chạy cái nào cũng được,
nhưng khi Export bằng lệnh gì thì phải Import bằng lệnh tương ứng, không được thằng
import, thằng module.exports, đồng thời lệnh trên còn xem xét cả thư mục
"node_modules" trong trường hợp Import thư viện
Không thể đóng hộp các File JS nếu có sử dụng thư viện Express
3. File Config?
Khi chạy lệnh sau
node_modules/.bin/webpack.cmd --mode <Mode>
Thì nó sẽ dò trong thư mục làm việc hiện tại xem có File "webpack.config.js" hay không,
nếu có thì nó sẽ xét Object được xuất ra từ File này, nếu là Common Module thì không
có gì để nói, nếu là ECMA Module thì xét Object được xuất ra bởi export default
Object này phải chứa các Key Value sau, các Value như tham số khi dùng CMD
{
entry: <Đường Dẫn Tương Đối Hoặc Tuyệt Đối Tới File Entry>,
output: {
path: <Đường Dẫn Tuyệt Đối Tới Thư Mục Lưu>,
filename: <Tên File Output>
}
}
Cơ chế <Mode> đã biết
Để các File JS được hiểu là viết theo JSX, để nó biên dịch ra JS, và đồng thời cũng biên
dịch ra phiên bản JS thấp hơn để tương thích với nhiều trình duyệt, ta cần sử dụng thư
viện Babel kết hợp với Webpack, trước tiên là cài đặt
npm install babel-loader @babel/preset-react @babel/preset-env @babel/core --save-
dev
Sau đó thêm thuộc tính này vào Object được xuất ra ở File "webpack.config.js", nó nghĩa
là chỉ có các File JS không nằm trong thư mục "node_modules" là được biên dịch, còn
trong "node_modules" giữ nguyên không cần dịch
module: {
rules: [
{
loader: "babel-loader",
test: /\.js$/,
exclude: /node_modules/,
options: {
presets: [
"@babel/preset-env",
"@babel/preset-react"
]
}
}
]
}
Cách khác, thêm thuộc tính sau thay cho thuộc tính trên
module: {
rules: [
{
use: ["babel-loader"],
test: /\.js$/,
exclude: /node_modules/
}
]
}
- Sau đó, tạo File ".babelrc" trong thư mục làm việc hiện tại, File này viết giống JSON,
thêm thuộc tính sau vào nó
"presets": [
"@babel/preset-env",
"@babel/preset-react"
]
Thư viện @babel/preset-react có tác dụng chuyển đổi JSX về JS, nếu bỏ đi thì bạn không
thể dùng JSX, còn thư viện @babel/preset-env có tác dụng chuyển JS về phiên bản thấp
hơn để tương thích với nhiều trình duyệt, ví dụ chuyển cú pháp của hàm mũi tên sang cú
pháp thông thường, nếu bỏ đi thì vẫn để hàm mũi tên, và @babel/preset-env cần
@babel/core để hoạt động
Ngoài ra, khi sử dụng cách Load File ".babelrc", thì ta trong File ".babelrc", ta còn có thể
cấu hình thêm 1 số tiện ích khác, bao gồm
- Thư viện Babel Plugin Module Resolver, để cài đặt
npm install babel-plugin-module-resolver --save-dev
a) Tiếp theo, thêm thuộc tính sau vào File ".babelrc"
"plugins": [
[
"module-resolver",
{
"alias": {
<Alias 1>: <Thế 1>,
<Alias 2>: <Thế 2>,
…
}
}
]
b) Khi này, mỗi khi bạn dùng lệnh import hay require, thì cái đường dẫn bên trong sẽ được
xử lí như sau, các chuỗi con <Alias 1> trong nó sẽ được thế = <Thế 1>, các chuỗi con
<Alias 2> trong nó sẽ được thế = <Thế 2>, …, và đường dẫn sau khi thế sẽ tính từ File
".babelrc", không phải File JS chứa lệnh import hay require đó, ví dụ
"plugins": [
[
"module-resolver",
{
"alias": {
"~": "./src",
}
}
]
c) Nghĩa là ví dụ bạn truyền đường dẫn "~/foo/bar" cho import hay require thì nó sẽ được
biến thành "./src/foo/bar", và đường dẫn này tính từ File ".babelrc", không phải từ File
JS
Để khi biên dịch ra File JS gộp, thì tự động Link File này vào File HTML nào đó, trước tiên
cần cài đặt thư viện HTML Webpack Plugin
npm install html-webpack-plugin --save-dev
Sau đó vào File "webpack.config.js", Import thư viện này
- Common Module
const <HTML Webpack Plugin> = require("html-webpack-plugin")
- ECMA Module
import <HTML Webpack Plugin> from "html-webpack-plugin"
Cũng trong File "webpack.config.js", thêm thuộc tính sau vào Object nó xuất ra
plugins: [
new <HTML Webpack Plugin>({
template: <File HTML>
})
]
- <File HTML> là đường dẫn tương đối hoặc tuyệt đối tới File HTML bản mẫu, có phần mở
rộng
Khi này, bất cứ khi nào biên dịch, thì bên cạnh File JS gộp cũng sẽ có 1 File tên
"index.html", nó y chang File HTML bản mẫu, nhưng có Tag Script Link tới File JS gộp bên
trong, Tag Script này nằm cuối Node Head, và có thuộc tính defer
Để tạo 1 Server giống Live Server tại nơi lưu File JS gộp và File "index.html", nhưng khác
Live Server, mỗi lần mỗi lần ta chỉnh sửa File JS liên quan đến File JS gộp hoặc File HTML
bản mẫu, thì lập tức Webpack sẽ biên dịch lại, tuy nhiên bản chất nó biên dịch rồi chạy
luôn, chứ không lưu File JS gộp và HTML vào thư mục nào hết, và bất cứ thứ gì ở thư
mục "public", đều có thể truy cập được bằng cách thêm Path trên URL, trước tiên cài thư
viện Webpack Dev Server, lưu ý thư viện này cần thư viện Webpack đã cài thì mới sử
dụng được, nó cũng sẽ dựa vào File "webpack.config.js" để biên dịch
npm install webpack-dev-server --save-dev
Khi này, trong thư mục con ".bin" của "node_modules", sẽ có File "webpack-dev-
server.cmd", ta sẽ dùng File này để khởi tạo Server
node_modules/.bin/webpack-dev-server.cmd --mode <Mode>
- Cơ chế <Mode> đã biết, cái này liên quan đến biên dịch chứ không phải Server
- 1 Server sẽ được khởi tạo ở địa chỉ localhost:8080, vào địa chỉ này sẽ nhận được File
"index.html"
- Để khi chạy lệnh trên thì mở luôn trình duyệt và nhập URL http://localhost:8080, thì
thêm cờ --open
- Để không phải biên dịch lại toàn bộ mà chỉ biên dịch 1 phần khi chỉ có 1 bộ phận nhỏ của
1 File thay đổi, thêm cờ --hot
4. Thư Viện React Scripts?
Có tác dụng giúp bạn không cần phải tạo File "webpack.config.js", nói rộng ra là đéo cần
Webpack, đéo cần Babel, đéo cần tất cả các thư viện khác liên quan, tất cả chúng nó đều
đã nằm trong thư viện React Scripts và cấu hình đều đã chỉ định trong thư viện này,
trước tiên cài đặt như sau
npm install react-scripts
Khi này, trong thư mục con ".bin" của "node_modules", sẽ có File "react-scripts.cmd"
Sau đó vào File "package.json", thêm thuộc tính sau
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
- Cái này là để khi ta chạy React Scripts, nó sẽ biên dịch như thế nào và lựa chọn trình
duyệt nào để mở, mục "production" liên quan đến khi Build ra thành phẩm cuối, mục
"development" là trong quá trình phát triển
Sau khi xong xuôi, để khởi chạy Server trong chế độ phát triển, dùng lệnh sau
node_modules/.bin/react-scripts.cmd start
Trình duyệt ngay lập tức mở lên, lưu ý lệnh trên không tạo File JS gộp và HTML, tức là nó
biên dịch rồi chạy luôn, ngõ vào JS sẽ là File "index.js" nằm trong thư mục "src" trong thư
mục làm việc hiện tại, File HTML bản mẫu sẽ là File "index.html" nằm trong thư mục
"public" trong thư mục làm việc hiện tại
Bạn có thể sử dụng cú pháp JSX tùy ý, khi thay đổi File thì Server cũng sẽ biên dịch và cập
nhật lại
Bạn có thể Import File CSS vào File JS nếu nó là ECMA Module, khi biên dịch, những dòng
Import này đều được chuyển thành Tag Style với mã CSS bên trong ở cuối Node Head, ví
dụ
import "./App.css"
Địa chỉ mặc định của Server là localhost:3000, bạn có thể thay đổi Port 3000 thành Port
khác bằng cách thêm File ".env.local" vào thư mục làm việc hiện tại, và thêm dòng PORT
= <Port Mặc Định Mới> vào, ví dụ PORT = 4000
Có thể truy cập các File trong thư mục "public" bằng cách nhập Path lên URL
Để Build ra trong chế độ thành phẩm, dùng lệnh sau
node_modules/.bin/react-scripts.cmd build
Ngõ vào các File thì đã nói, khi này nó sẽ tạo ra thư mục "build" ở thư mục làm việc hiện
tại, trong đó có File "index.html" thành phẩm cùng với 1 số File liên quan, nghĩa là các
File CSS, ảnh, … trong thư mục "public" được Link vào File HTML cũng sẽ được thêm vào
thư mục "build"
Tương tự như start, bạn có thể Import CSS vào File JS, nhưng khi biên dịch ra thì nó
không tạo Tag Style, mà gộp tất cả File CSS bị Import thành 1 File CSS duy nhất, File CSS
này được tối giản tối đa, sau đó Link File CSS này vào File "index.html"
Ở cả 2 chế độ start và build, bạn đều có thể sử dụng CSS Module, chúng là các File với
phần mở rộng ".module.css", khi biên dịch, chúng cũng giống như File CSS bình thường,
là biến thành Tag Style hoặc bị gộp vào File CSS duy nhất, cách viết CSS Module đéo khác
gì CSS thông thường, nhưng với các Selector có dạng .<Tên Class> hoặc chứa .<Tên
Class>, thì các .<Tên Class> đều bị biến thành .<Tên Class Biến Đổi>, ví dụ .foo trở
thành .Bar_foo__abc123, mỗi File CSS Module sẽ có cách mã hóa tên khác nhau, do
đó .foo trong File này có thể là .Bar_foo__abc123 nhưng .foo trong File kia thì
là .Bob_foo__def456, tất cả các Selector còn lại không bị biến đổi
import <Style> from <Đường Dẫn Đến File CSS Module Có Phần Mở Rộng>
Ví dụ
import style from "./App.module.css"
Thông qua <Style> ta có thể biết tên Class biến đổi ứng với mỗi tên Class gốc trong File
CSS Module được Import, lệnh sau trả về String tên Class biến đổi ứng với <Tên Class
Gốc>
<Style>.<Tên Class Gốc>
- Ví dụ
const bar = style.foo
- Lệnh trên trả về "Bar_foo__abc123"
Ngoài ra, bạn cũng có thể sử dụng SCSS hoặc SCSS Module, React Scripts đã tự cấu hình
để chạy SCSS và SCSS Module rồi, bạn chỉ cần cài đặt thư viện SASS là được, File SCSS sẽ
được Import như File CSS, còn File SCSS Module có phần mở rộng là ".module.scss",
cách hoạt động y chang CSS Module, chỉ khác là có thể sử dụng cú pháp SCSS, để cài đặt
thư viện SASS
npm install sass
Về thư viện CLSX
Để cài đặt
npm install clsx
Để Import
- Common Module
const <CLSX> = require("clsx")
- ECMA Module
import <CLSX> from "clsx"
Lệnh sau chỉ đơn giản là nối tất cả các String lại, cách nhau = 1 dấu cách, rồi trả về String
nối
<CLSX>(<Các String>)
- Ví dụ
clsx("gg", "nore", "foo")
- Lệnh trên trả về "gg nore foo"
Ngoài ra, ta cũng có thể nối cả String và Object lại với nhau, các Object này phải viết theo
Dictionary, có Value chỉ là true hoặc false, cái nào true thì được nối vào String, ngược lại
không nối, ví dụ
clsx("Gg", {"buma": true, "haha": false}, "taro", {"gg": true})
- Lệnh trên trả về "Gg buma taro gg"
5. Thư Viện React App Rewired?
React App Rewired bản chất đã chứa thư viện React Scripts luôn rồi, có tác dụng cho
phép bạn ghi đè cấu hình Webpack mặc định của React Scripts, trước tiên ta cần cài đặt
thư viện React App Rewired cùng với Customize CRA
npm install react-app-rewired customize-cra --save-dev
Khi này, trong thư mục con ".bin" của "node_modules", sẽ có File "react-app-
rewired.cmd"
Sau đó vào File "package.json", thêm thuộc tính sau
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
- Cái này y chang như của React Scripts
Sau khi xong xuôi, để khởi chạy Server trong chế độ phát triển, dùng lệnh sau
node_modules/.bin/react-app-rewired.cmd start
Lệnh trên y chang như start của React Scripts, chỉ có điều trước khi biên dịch nó sẽ dò
trong thư mục làm việc hiện tại xem có File "config-overrides.js" hay không, nếu không
tồn tại thì lỗi, nếu có thì nó sẽ xét thứ được xuất ra từ File này, File này phải là Common
Module, thứ được xuất ra sẽ chứa các cấu hình ghi đè lên Webpack
Thứ này sẽ phải được tạo ra từ thư viện Customize CRA, do đó trước tiên trong File
"config-overrides.js" ta cần Import thư viện này
const <Customize CRA> = require("customize-cra")
- Tiếp theo, thứ được xuất ra phải là giá trị trả về của lệnh sau
<Customize CRA>.override(<Các Cấu Hình Ghi Đè>)
- <Các Cấu Hình Ghi Đè> nếu không chỉ định thì xài cấu hình Webpack mặc định, nếu chỉ
định thì nó sẽ là 1 loạt các đối số, mỗi thằng sẽ có 1 chức năng khác nhau, ví dụ
module.exports = cra.override(cra.useBabelRc(), cra.disableEsLint())
Mấy lệnh build cũng tương tự React Scripts, thay react-scripts thành react-app-rewired,
nó vẫn sẽ xem xét File "config-overrides.js" để biên dịch cho phù hợp
Các đối số bạn có thể truyền vào <Các Cấu Hình Ghi Đè> bao gồm
Thằng dưới này sẽ khiến cho React App Rewired đọc thêm cấu hình trong File ".babelrc"
trong thư mục làm việc hiện tại, và cấu hình trong File này sẽ được ghi đè vào cấu hình
của File ".babelrc" nội bộ bên trong thư viện React Scripts
<Customize CRA>.useBabelRc()
Development:
1. Front End?
Ta có cấu trúc thư mục sau
public
index.html Ngõ vào Web
src
index.js File được chạy đầu tiên
routes Định nghĩa các tuyến đường, công khai và ẩn, công
khai thì không cần đăng nhập vẫn xem được, ẩn thì
phải đăng nhập
App.js Function Component bao toàn dự án, sử dụng các
tuyến đường trong routes
components
GlobalStyle Chứa CSS bao toàn dự án
Layout
DefaultLayout Chứa các thành phần cơ bản của Layout như
Header, Footer, Panel, dùng để bao Function
Component con
<Các Layout Khác>
pages
Home Trang đầu tiên khi vào Web
<Các Trang Con Khác>
Nginx:
Hosting:
1. Vietnix?
Vào Link https://portal.vietnix.vn/ + đăng nhập bằng tài khoản Google
Mỗi tài khoản Vietnix sẽ độc lập, nhưng khi nhiều tài khoản hợp lại với nhau, thì chúng
sẽ như dùng chung 1 tài khoản, trong có ít nhất 1 người làm chủ, người chủ có thể xóa
các thành viên khác ra khỏi tổ chức, khi này họ sẽ lại được tự do độc lập
Dịch vụ Hosting có nghĩa là bạn thuê 1 phần của máy chủ để lưu trữ Web, nghĩa là đéo
thể truy cập được máy chủ này, do đó cần thêm việc dịch vụ đăng ký tên miền, 1 tên
miền được đăng ký sẽ phải chĩa đến địa chỉ IP của máy chủ lưu trữ Web thì mới dùng tên
miền này truy cập được Web, như vậy, bạn phải bỏ tiền riêng để thuê dịch vụ Hosting,
và bỏ tiền riêng để thuê dịch vụ tên miền
Các dịch vụ có thể thuê là Hosting, VPS, tên miền, …
Về giao diện, gồm 3 phần
Thanh trên cùng là thanh lối tắt
- Nút hình cái giỏ góc phải trên, Click vào để vào trang giỏ hàng
Thanh dưới là thanh điều hướng chính
- Nút tên tài khoản bên phải cùng, Click vào
a) "Chi tiết tài khoản", chuyển tới Tab "Thông tin tài khoản", Tab con "Chi tiết tài khoản"
b) "Quản lí người dùng", chuyển tới Tab "Thông tin tài khoản", Tab con "Quản lí người
dùng"
c) "Chi tiết liên hệ", chuyển tới Tab "Thông tin tài khoản", Tab con "Chi tiết liên hệ"
d) "Quản lí đăng nhập", chuyển tới Tab "Thông tin tài khoản", Tab con "Quản lí đăng nhập"
e) "Lịch sử Email", chuyển tới Tab "Thông tin tài khoản", Tab con "Lịch sử Email"
f) "Mật khẩu", chuyển tới Tab "Thông tin tài khoản", Tab con "Mật khẩu"
g) "Thiết lập bảo mật", chuyển tới Tab "Thông tin tài khoản", Tab con "Thiết lập bảo mật"
- Nút "Đăng ký dịch vụ", Click vào để vào trang con đăng ký dịch vụ, Tab "Hosting"
Panel bên trái là Panel hoa tiêu
Phần ở giữa khác nhau với từng Tab trong Panel hoa tiêu
- Về Tab "Thông tin tài khoản"
a) Tab con "Chi tiết tài khoản", chỉnh sửa thông tin cá nhân, có mục "Phương thức thanh
toán" chọn "Momo Payment" để thanh toán mọi dịch vụ bằng Momo
- Về Tab "Dịch vụ của tôi", liệt kê các dịch vụ bạn đã đăng ký trừ dịch vụ tên miền, nó có
thống kê số lượng dịch vụ đang chạy với mỗi loại Hosting, VPS, …
a) Cột "Gói đăng ký", tên gói dịch vụ
b) Cột "Giá", là giá gốc chưa bao gồm thuế VAT
c) Cột "Chu kỳ", là khoảng thời gian giữa mỗi lần thanh toán để duy trì dịch vụ
d) Cột "Ngày hết hạn", ngày bạn phải thanh toán để duy trì
e) Cột "Trạng thái" , hiển thị trạng thái dịch vụ
f) Khi Click vào 1 dịch vụ, sẽ vào phần chỉnh sửa dịch vụ đó
- Về Tab "Quản lý tên miền", liệt kê tất cả tên miền đã đăng ký, nó có thống kê số lượng
tên miền ứng với mỗi đuôi ".com", ".vn", …
a) Cột "Tên miền" là tên miền
b) Cột "Ngày đăng ký" là ngày đăng ký tên miền
c) Cột "Ngày hết hạn" là ngày cần gia hạn
d) Cột "Tình trạng" là trạng thái tên miền
e) Nút "Quản lý", Click vào để vào phần chỉnh sửa tên miền đó
Về phần chỉnh sửa tên miền
Thanh trên cùng là tên miền đang chỉnh sửa, nút mũi tên bên trái để quay về
Tab "Tổng quan", hiển thị tên miền, trạng thái, ngày đăng ký, gia hạn, số tiền thanh toán
lần đầu, số tiền cần để gia hạn, hình thức thanh toán
Tab "Hồ sơ tên miền", sau khi đăng ký tên miền bạn cần vào Tab này ngay lập tức để tải
ảnh CCCD lên, mặt trước và mặt sau, sau đó Click nút "Tải bản khai" + vào File vừa tải để
ký tên lên đó, màu đen, dùng phần mềm chỉnh sửa PDF, rồi nộp File PDF đó lên
Tab "Nameservers", tại đây sẽ hiển thị các ANS của tên miền bạn, có thể chỉnh sửa,
chúng là các NS Record trong TLD Server
Tab "Quản lý DNS", tại đây liệt kê tất cả DNS Record trong Zone File ứng với tên miền
của bạn trong ANS
- Cột "NAME", là tên miền của bạn hoặc các tên miền cùng nó với nó
- Cột "TYPE", loại DNS Record
- Cột "CONTENT", giá trị của DNS Record
- Cột "TTL", là TTL của DNS Record, lưu ý nếu < Minimum TTL của SOA Record thì sẽ chọn
Minimum TTL
- Bạn có thể xóa DNS Record bằng nút thùng rác bên phải cùng, không thể xóa SOA
Record, Email quản trị trong SOA Record này là hostmaster.<Tên Miền>, dấu chấm ở đây
thay cho @, nghĩa là bạn phải tự tạo Email hostmaster@<Tên Miền> để làm Email quản
trị, chứ nó không tạo giúp bạn
- Bạn có thể chỉnh sửa DNS Record bằng cách Click vào nút bút chì + nhập lại thông tin +
Click nút chữ V
- Bạn có thể thêm DNS Record bằng cách Click dấu cộng góc phải trên + điền thông tin +
Click "Add", mới khi tạo tên miền, bạn cần phải tạo 1 A Record, ánh xạ tên miền của bạn
tới địa chỉ IP của máy chủ đang Host trang Web của bạn thì mới sử dụng được tên miền
này
Về phần chỉnh sửa dịch vụ loại Hosting
Thanh trên cùng là tên gói dịch vụ, nút mũi tên bên trái hoặc nút "Quản lí dịch vụ" để
quay trở lại
Khối phía dưới, chứa tên dịch vụ, trạng thái dịch vụ, tên miền Fake tương ứng, lưu ý tên
miền Fake đéo có tác dụng gì ngoài việc làm phần mở rộng cho các Email thuộc trang
Web của bạn, bạn chỉnh cái mẹ gì cũng được, số tiền không bao gồm thuế VAT đã thanh
toán lần đầu và cần thanh toán định kỳ, chu kỳ thanh toán, hình thức thanh toán, ngày
đăng ký dịch vụ và ngày cần gia hạn
Khối dưới nữa
- Nút "Đổi tên miền chính", Click rồi nhập tên miền mới để đổi tên miền Fake, các Email
với tên miền cũ cũng tự động được cập nhật thành tên miền Fake
- Nút "Cài đặt lại hosting", Click vào rồi nhập đúng tên miền Fake sau đó Click "Xác nhận"
để xóa hết tất cả Web của bạn ở máy chủ Host, nghĩa là làm lại như mới, các Email thuộc
Host cũng xóa luôn
- Nút "Tải lại hosting", Click + Click "Xác nhận" để làm mới lại RAM của máy chủ Host
Khối "Liên kết nhanh"
- "Đăng nhập vào cPanel", Click để vào trang C Panel, Tab "Tools"
- "Đăng nhập vào Webmail", Click để vào trang Web Mail
Khối "Tạo nhanh tài khoản Email"
- Ô "Tên tài khoản" nhập tên người dùng bất kì, nó sẽ được thêm @<Tên Miền Fake> ở
phía sau
- Ô "Mật khẩu" nhập mật khẩu cho Email này, phải nhập mật khẩu mạnh mới tạo được +
Click "Tạo Email" để tạo Email
Khối "Liên kết với cPanel"
- "Email Accounts", Click để vào trang C Panel, Tab "Tools", khối "Email", mục "Email
Accounts"
- "File Manager", Click để vào trang File Host
Về trang con đăng ký dịch vụ
Về Tab "Hosting"
- Phần bên dưới liệt kê các bộ gói Hosting, trong mỗi bộ sẽ có nhiều gói khác nhau, Click
vào 1 bộ để tiếp tục, phần bên dưới sẽ liệt kê các gói thuộc bộ đó, với mỗi gói có các
thông tin sau
a) Tên gói
b) Số Core của CPU
c) Dung lượng RAM
d) Dung lượng đĩa
e) Số tên miền, nói cách khác, số trang Web có thể được Host trên máy
f) Thanh chọn chu kỳ thanh toán
g) Nút "Đăng ký", Click vào + nhập tên miền đầu tiên muốn chõ vào cái Host này, tên miền
phải đã đăng ký + Click "Kiểm tra" + Click "Thêm vào giỏ hàng" để thêm vào trang giỏ
hàng + Click "Thanh toán" rồi thanh toán bằng Momo bằng quét mã QR
Về Tab "Tên miền"
- Tab con "Đăng ký tên miền mới", nhập tên miền muốn đăng ký, phải không trùng với tên
miền nào + Click "Kiểm tra" + Click "Thêm vào giỏ" để thêm vào trang giỏ hàng + xem và
chỉnh sửa các Authoritative Name Server nếu muốn + Click "Thêm vào giỏ hàng" + Click
"Thanh toán" để trả tiền bằng Momo quét QR
- Sau khi đăng ký tên miền mới với đuôi ".com", ".net", ".info", ".org", thì phải lập tức vào
Link https://thongbaotenmien.vn/thongbaomoi.xhtml + nhập tên miền vừa đăng ký +
Click "Tra cứu" + Click "Thông báo sử dụng tên miền" + mục "Nhà đăng ký quản lí" chọn
cái nào có "VIETNIX" + nhập mật khẩu bất kì + điền phần thông tin còn lại + Click "Thực
hiện"
Về trang Web Mail, Link của nó sẽ độc nhất cho mỗi Host, bạn có thể chia sẽ Link này
cho mọi người, trang này như Gmail, nhưng chỉ cho phép các Email với tên miền Fake
được đăng nhập vào, ban đầu khi đăng nhập vào sẽ ở trang con thông tin chung, ở phần
con chính
Trang con thông tin chung
- Thanh trên cùng không đổi với các phần con khác nhau
a) Biểu tượng "Webmail" bên trái Click để về phần con chính
b) Nút "LOGOUT" Click để đăng xuất ngay
c) Nút hình biểu đồ tròn, có ghi dung lượng đã dùng để lưu trữ thư của tài khoản Email này
/ dung lượng tối đa cho phép của Email này, Click vào để vào phần con dung lượng
d) Nút hình người, có ghi Email hiện tại, Click để ẩn hiện Panel cá nhân, gồm mục
"Roundcube", Click để vào trang con thư nhận gửi, mục "Spam Filters" Click để vào phần
con lọc rác, mục "Password & Security", Click để vào phần con bảo mật, mục "Manage
Disk Usage", Click để vào phần con dung lượng
- Về phần con chính
a) Tick "Open my inbox when I log in" góc trái trên để thay vì mỗi lần đăng nhập là vào
trang con thông tin chung, thì nó sẽ vào luôn trang con thư nhận gửi
b) Click nút "Open" góc trái trên để vào trang con thư nhận gửi
Trang con thư nhận gửi
- Thanh công cụ lề bên trái là cố định
a) Nút tròn đỏ dưới cùng, Click để đăng xuất ngay
b) Nút mặt trăng gần dưới cùng, Click để đổi màu chủ đạo từ trắng thành đen, nó sẽ thành
nút mặt trời, Click lại để đen thành trắng
c) Nút hình vô cực màu đỏ cam ở giữa, Click để về trang con thông tin chung
d) Nút hình phong bì, Click để vào phần con thư nhận gửi
e) Nút bút chì, Click để tiến hành soạn thư và gửi thư, chỉ gửi được cho các Email có cùng
tên miền Fake
2. Trang C Panel?
Vietnix sẽ cấp cho bạn tài khoản mật khẩu để bạn đăng nhập vào C Panel, trang đăng
nhập của C Panel có Link là độc nhất với mỗi Host, nên bạn có thể chia sẻ nó, tuy nhiên
cũng sẽ chỉ có duy nhất 1 tài khoản có thể đăng nhập được là tài khoản được cung cấp
như đã nói
Giao diện gồm 3 phần
Thanh trên cùng là thanh tài khoản
- Nút Avatar bên phải, Click để ẩn hiện Panel cá nhân
a) "Password & Security", Click để vào phần con bảo mật
b) "Contact Information", Click để vào phần con thông tin liên hệ
c) "Log Out", đăng xuất ngay
Panel bên trái là Panel điều hướng, gồm các Tab
Phần bên phải khác nhau với mỗi Tab và phần con
- Về Tab "Tools"
a) Khối "General Information" bên phải, mục "Current User" hiện tên tài khoản C Panel,
mục "Primary Domain" là tên miền Fake, mục "Shared IP Address" là địa chỉ IP của máy
chủ Host, mục "Last Login IP Address" là địa chỉ IP của máy đăng nhập vào tài khoản C
Panel này gần đây nhất, mục "Server Information", Click đê vào phần con thông tin
Server, mục "Home Directory", là đường dẫn tới thư mục chứa trang Web, thông
thường do Server là Linux nên đường dẫn sẽ là /home/<Tên Tài Khoản C Panel>, tạm gọi
đây là đường dẫn gốc
b) Khối "Email" ở đầu tiên, mục "Email Accounts", Click để vào phần con tài khoản Email
c) Khối "Files" ở giữa, mục "File Manager", Click để vào trang File Host
d) Khối "Software" ở gần cuối, mục "Setup Node.js App", Click để vào phần con Node JS
- Về phần con bảo mật, dùng để đổi mật khẩu tài khoản C Panel, nhập mật khẩu hiện tại
và mật khẩu mới + Click "Change your password now!"
- Về phần con thông tin liên hệ, điền Email sẽ nhận được thông báo khi mật khẩu C Panel
thay đổi + Click "Save"
- Về phần con thông tin Server
a) "Server Name", tên Server, tức tên máy chủ Host
b) "Hosting Package", tên viết tắt của gói Hosting đăng ký
c) "Operating System", tên hệ điều hành của Server, thông thường là linux
d) "Shared IP Address", địa chỉ IP của Server, tức địa chỉ IP của máy chủ Host
- Về phần con tài khoản Email, ở đây sẽ liệt kê các Email thuộc Host, có phần sau @ là tên
miền Fake, tuy nhiên trong các Email này sẽ có 1 Email hệ thống được tạo mặc định, địa
chỉ Email của nó có cú pháp <Tên Tài Khoản C Panel>@<Tên Server>.vietnix.vn, không
thể thay đổi hay xóa Email này, nó vẫn có thể đăng nhập được vào trang Web Mail
a) Nút "Create" để thêm 1 Email mới, gồm địa chỉ Email, mật khẩu, dung lượng tối đa +
Click "Create"
b) Phần "Filter", chọn "All" để liệt kê tất cả Email, "System Account" để liệt kê mỗi Email hệ
thống
c) Có thể Tick vào ô vuông trước mỗi Email được liệt kê rồi Click "Delete" để xóa các Email
này
d) Nút "Check Email" bên phải mỗi Email, Click để đăng nhập vào trang Web Mail
e) Nút "Manage" để vào phần chỉnh sửa Email như đổi mật khẩu mới, giới hạn lại dung
lượng tối đa, xóa Email
- Về phần con Node JS, 1 tên miền sẽ có nhiều Web Application trên nó, mỗi Web
Application sẽ trú ngụ tại 1 Path khác nhau, Path của Web Application này có thể nằm
trong Path của Web Application kia, mỗi Web Application cũng sẽ định cư trong 1 thư
mục con cháu trong đường dẫn gốc
a) Tab "WEB APPLICATIONS" liệt kê tất cả các Web Application hiện tại trên tên miền Fake,
nghĩa là bạn nên chỉnh tên miền Fake trùng với tên miền thật để có thể hoạt động, cột
"App URI" có cú pháp <Tên Miền><Path Tương Ứng>, cột "App Root Directory" là đường
dẫn tuyệt đối tới thư mục mà Web Application định cư, cột "Mode" là chế độ phát triển
= "development" hoặc đã thành phẩm = "production", cột "Status" là trạng thái Web
Application, "started" tức đã chạy, "stopped" tức đã dừng, nó còn kèm theo phiên bản
Node JS để chạy Web Application, cột "Actions", nút ô vuông đầu tiên để dừng Web
Application, thành nút tam giác để chạy, nút mũi tên tròn để chạy lại, nút thùng rác để
xóa Web Application, nút bút chì để vào phần Tab chỉnh sửa Web Application
b) Tab chỉnh sửa Web Application, nút "DESTROY" để xóa Web Application, "CANCLE" để
quay về, "SAVE" để lưu chỉnh sửa, mục "Node.js", nút "STOP APP" để dừng, "RESTART"
để chạy lại, mục "Node.js version", chọn phiên bản Node JS để chạy, mục "Application
Mode", chọn chế độ phát triển hoặc đã thành phẩm, mục "Application root", ghi đường
dẫn tới thư mục mà Web Application định cư, bắt đầu từ trong đường dẫn gốc, ví dụ
foo/bar, mục "Application URL", kế tên miền bạn sẽ điền Path mà Web Application trú
ngụ, cách khi như "Application root", mục "Application startup file" điền đường dẫn tới
File JS có phần mở rộng, bắt đầu từ trong thư mục định cư, cách viết tương tự như vừa
nói, File JS này được gọi là File Entry, mục "Detected configuration files", nếu trong thư
mục định cư chứa File "package.json", thì nút "Run NPM Install" có thể nhấn được để cài
đặt các thư viện được nêu trong File này, y chang lệnh npm install, mục "package.json"
sẽ hiển thị nếu File này tồn tại, nút "Edit" Click vào để chỉnh sửa File "package.json" +
Click "SAVE" để lưu
c) Nút "CREATE APPLICATION" góc phải trên Click để tạo Web Application, điền thông tin
như khi chỉnh sửa + Click "CREATE", khi tạo Web Application, nếu các đường dẫn bạn
điền chưa tồn tại thì sẽ tự động tạo trong dự án, chính là tạo các thư mục và File trong
đường dẫn gốc, riêng Path trú ngụ bạn điền, ví dụ bạn điền foo/bar, thì trong thư mục
"public_html" của đường dẫn gốc sẽ xuất hiện thư mục "foo" và trong "foo" có thư mục
"bar", thư mục "bar" rỗng
d) Khi chạy lần đầu hoặc chạy lại 1 Web Application, thì tương đương việc bạn vào thư mục
định cư của Web Application đó, rồi chạy lệnh node <Đường Dẫn Tới File Entry>, nhưng
trong Code JS, bạn sẽ không thể chỉ định cụ thể Port mà bạn sẽ lắng nghe, ví dụ với
Express JS, nếu bạn ghi app.listen(3000) thì nó tương đương app.listen(), nghĩa là bạn
không được phép chỉ định Port, khi bạn viết app.listen(), thì tự động nó lắng nghe trên
Port 80 và 443, chính là Port mặc định của giao thức HTTP và HTTPS, các phương thức
get thì vẫn lấy Path truyệt đối trên URL, đéo quan tâm Path trú ngụ của Web Application,
ví dụ app.get("/concac/foo", () => {}) thì vẫn bắt gg.com/concac/foo, cho dù Web
Application trú ngụ ở gg.com/concac, nghĩa là nếu bạn viết app.get("/foo", () => {}), thì
không bắt gg.com/concac/foo mà bắt gg.com/foo, nhưng gg.com/foo lại không thuộc
gg.com/concac nên không bắt được, nghĩa là chỉ bắt được những Path nằm trong Path
trú ngụ
Về trang File Host, thư mục to nhất là đường dẫn gốc, ở đây bạn có thể chỉnh sửa thêm
xóa các File và thư mục tùy thích
Về cơ chế URL, xét phần Path của nó, đối chiếu xem có Path nào tương tự trong thư mục
"public_html" trong đường dẫn gốc không, ví dụ Path của URL là /foo/bar, thì nếu trong
thư mục "public_html" có thư mục "foo", và trong "foo" có "bar", thì sẽ xét trong "bar"
xem, nếu trong đây có File "index.html" thì ngay lập tức phản hồi về File này, tức phần
Response Body sẽ là File "index.html", nếu tất cả điều kiện trên không xảy ra, thì sẽ tiến
hành phân tích Path của URL, lần lượt đi ngược lại, ví dụ Path là /foo/bar/alice thì đi
ngược lại sẽ là /foo/bar/alice, rồi /foo/bar, rồi /foo, rồi cuối cùng là /, cho tới khi có 1
Web Application đang chạy trú ngụ tại Path đó, ví dụ sẽ dùng lại tại /foo nếu có 1 Web
Application đang trú ngụ tại /foo, sau đó tiếp tục kiểm tra xem Path trú ngụ của Web
Application này có tồn tại trong "public_html" không, tiếp tục ví dụ trên thì thư mục
"foo" phải ở trong thư mục "public_html" thì điều kiện mới thỏa mãn, sau đó sẽ xử lí
URL theo Web Application này, ví dụ theo Web Application này, thì với Path
/foo/bar/alice của URL sẽ trả về chuỗi "ggnore", thì Response Body sẽ là "ggnore", nếu
điều kiện không thỏa mãn, thì sẽ gửi về lỗi 404
Các File ảnh, văn bản hay gì đó trong thư mục "public_html" đều có thể truy cập bằng
URL
3. Về Máy Chủ Của Vietnix?
Nó đã được cài đặt python3, tức là bạn có thể kết nối SSH rồi chạy lệnh như python3.py,
…, và nhiều lệnh khác nữa, tuy nhiên khi bạn đóng Shell ở máy bạn thì các Process này
cũng bị giết, tuy nhiên để khắc phục điều này, tức Process vẫn chạy cho dù bạn đóng
Shell, thì dùng lệnh Linux sau
nohup <Lệnh> &
Ví dụ
nohup python3 foo.py &
4. WHOIS?
Vào Link https://www.whois.com/
Về giao diện, gồm 2 phần
Thanh trên cùng là thanh điều hướng
- Ô Input nhập 1 tên miền + Click "WHOIS" để vào phần tra cứu tất cả thông tin về tên
miền này
Phần dưới khác nhau với mỗi Tab ở thanh điều hướng
5. ICANN (Internet Corporation For Assigned Names And Numbers)?
Là 1 tổ chức phi lợi nhuận có nhiệm vụ đánh địa chỉ IP cho các thiết bị kết nối với
Internet
6. Cloudflare?
Vào Link https://dash.cloudflare.com/, đăng nhập = tài khoản Cloudflare
Giao diện gồm 3 phần
Thanh trên cùng là thanh công cụ
- Biểu tượng "CLOUDFLARE" bên trái, Click vào để tải lại trang, Tab "Account Home"
- Nút Avatar bên phải cùng
a) "My Profile", Click vào để vào phần con Profile
b) "Account Home", để vào Tab "Account Home"
c) "Billing", để vào Tab "Billing"
d) "Appearance", để vào phần con Profile, cuộn xuống 1 chút
e) "Log Out", đăng xuất
Panel bên trái là Panel điều hướng
- Phần trên cùng là địa chỉ Email tài khoản
Phần bên phải khác nhau với mỗi Tab ở Panel điều hướng
- Về Tab "Websites", vào Tab này để thêm tên miền của bạn vào, khi này, nó sẽ cấp cho
bạn địa chỉ của 2 ANS của Cloudflare, bạn phải thêm 2 NS Record vào danh sách các DNS
Record trong trang Web của nhà cung cấp tên miền của bạn, và xóa tất cả NS Record
khác, với Vietnix thì bạn còn phải vào Tab "Nameservers" của phần chỉnh sửa tên miền
để đặt lại các tên miền của Cloudflare, sau đó chờ 1 ngày để nó cập nhật lại, 2 ANS này
có 1 cơ chế đặc biệt, khi 1 DNS Resolver gửi yêu cầu tới, nó sẽ gửi thêm địa chỉ IP của
CDN (Content Delivery Network) Server gần nhất với người gửi yêu cầu tới trang Web,
nhờ đó mà DNS Resolver thay vì gửi yêu cầu trực tiếp lên Server lưu trang Web ở tút xa,
thì nó chỉ gửi tới CDN Server gần đó, CDN Server nhận được yêu cầu, nếu nó thấy trong
bộ nhớ đệm của nó đã có trang Web đó rồi thì gửi thẳng về cho người dùng luôn, còn
không thì vẫn gửi yêu cầu lên Server lưu trang Web, và 1 khi Server này gửi về trang
Web, thì CDN Server cũng lưu nó vào bộ đệm, đồng thời lan truyền cho tất cả CDN
Server khác trên thế giới trang Web này, nhờ đó mà bất cứ ai cũng có thể truy cập nhanh
được trang Web
- Về Tab "DNS", liệt kê các DNS Record của 2 ANS của Cloudflare cấp cho bạn, cần có 1 A
Record chĩa tên miền của bạn vào địa chỉ IP của Host