Home Blog Page 205

67 công cụ hữu ích, thư viện và tài nguyên để tiết kiệm thời gian với các nhà phát triển web

67-cong-cu-huu-ich-thu-vien-va-tai-nguyen-de-tiet-kiem-thoi-gian-voi-cac-nha-phat-trien-web

Thư viện Javascript

Particles.js —  Thư viện giúp tạo các floating particle cho trang web

Three.js —  Thư viện giúp tạo các đối tượng và không gian 3D trên trang web

Fullpage.js—  Giúp dễ dàng thực hiện tính năng cuộn trang

Typed.js — Hiệu ứng đánh máy

Waypoints.js — Kích hoạt một function khi bạn di chuyển đến một element của web

Highlight.js—  Làm nổi bật các cú pháp cho website

Chart.js —  Tạo các biểu đồ trực quan bằng cách dùng javascript

Instantclick —  Đẩy nhanh thời gian tải trang, tải trước tài nguyên trên di chuột

Chartist —  Một thư viện về biểu đồ khác

Motio —  Một thư viện cho các hình động và hoạt họa dựa trên nền sprite

Animstion —  Plugin Jquery cho chuyển đổi trang bằng css animaton

Barba.js — Chuyển trang bằng fluid

TwentyTwenty — Một công cụ khác biệt trực quan để tìm những khác biệt

Vivus.js — Thư viện để tạo các ảnh vẽ trên SVG

Wow.js— Cung cấp các animation khi bạn cuộn trang

Scrolline.js —  Theo dõi việc bạn đã cuộn từ đầu cho đến khi kết thúc trang

Velocity.js —  Tạo hình động với javascript cực nhanh và đẹp

Animate on scroll —  Tạo sự đơn giản cho webite

Handlebars.js — Cung cấp các mẫu  Javascript

jInvertScroll — Cuộn trang với Parallax

One page scroll —  Một trang cuộn thư viện

Parallax.js —  Công cụ Parallax phản ứng với một thiết bị thông minh

Typeahead.js —  Hoàn thành tìm kiếm

Dragdealer.js —  Thư viện cung cấp việc minh họa drag

Bounce.js —  Tạo các hình động CSS3 cool

Pagepiling.js —  Cuộn một trang

Multiscroll.js —  Cuộn một trang web thành hai thanh cuộn dọc

Favico.js — Tạo các  favicon đa dạng

Midnight.js — Chuyển tiêu đề thành cố định

Anime.js — Thư viện animation

Keycode — Tạo  keycode javascript chỉ với một nút

Sortable — Kéo và thả

Flexdatalist —  Tự động điền

Slideout.js —  Trình điều hướng trình chiếu cho các ứng dụng di động

Jquerymy —  Liên kết dữ liệu bằng cách sử dụng jquery

Cleave.js — Định dạng nội dung nhập

Page — Định tuyến phía client cho các ứng dụng trang đơn

Selectize.js — Selected box ghép nối để thêm tag

Nice select — Thư viện JQuery để tạo các hộp chọn

Tether —  Sử dụng các yếu tố định vị một cách hiệu quả

Shepherd.js —  Hướng dẫn người dùng thông qua ứng dụng

Tooltip — Tên speak cho chính nó

Select2 — Thay thế Jquery cho các selected box

IziToast —Dễ dàng thực hiện các js notification

IziModal — Dễ dàng thực hiện các js modal

 

Thư viện CSS / Công cụ thiết kế

Animate.css — Thư viện animation

Flat UI Colors — Danh sách các màu chính đơn giản và hiệu quả

Material design lite— Framework dựa trên material design của Google

Materialui.co —  Nhiều tài nguyên cho material design framework

Colorrrs —Generator màu ngẫu nhiên

Section separators — Phân chia css

Topcoat —  Framework

Create ken burns effect — Ken hiệu ứng bằng cách sử dụng các css3 animation

DynCSS —  Thêm các hàm vào css, làm cho nó trở nên thân thiện

CSSpin —  Bộ sưu tập của css spinners

Feather icons — Đưa ra  Icon

Ion icons — Các icon

Font awesome — Icon và phông chữ

Font generator —  Kết hợp các phông chữ và tạo ra mixture

On/Off switch — Tạo chuyển đổi on/off với css

UI Kit —  Framework

Bootstrap — Framework

Foundation — Framework

Các sản phẩm/liên kết hữu ích

<cheat> cheatsheet – một danh sách tất cả mọi thứ có thể đi vào <head> tag

Ghost —  nền tảng blog đơn giản dựa trên node.js

What runs —  Plugin của Chrome để khám phá công nghệ nào được sử dụng để xây dựng trang web

Learn anything — Cung cấp các Mindmap để minh họa một các chủ đề khác nhau.

TopDev via Hackernoon

  Tìm kiếm số liệu cho các dự án JavaScript hàng đầu

Kinh nghiệm xương máu từ 9 tháng làm kỹ sư phần mềm ( P2 )

TopDev via 

  Kinh nghiệm xương máu từ 9 tháng làm kỹ sư phần mềm (P1)

Không có gì là quá khó hiểu ở đây cả

Thường có một lý do chính đáng cho việc tại sao code được LGTM’ed ( tức là được chấp nhận trong code base). Nếu bạn không hiểu cách nó hoạt động, hãy dành một chút thời gian tìm hiểu về nó. Vọc thử chỗ này chỗ kia, và đồng thời đọc document của các functions và pattern thật kỹ.  

Nhìn con vịt nhựa trên bàn tôi nè, nhiều khi tôi bế tắc đến nổi phải nói chuyện với nó, ê mày có hiểu code tao không. Bạn cũng nên có con vịt tương tự? Nếu bạn vẫn không chắc chắn, hãy thử check lại những lỗ hổng kiến thức của mình.

Debug nữa, Debug mãi, Debug mãi mãi

Debug thể hiện việc bạn rất hiểu sản phẩm cũng như các tính năng code của mình. Bạn cần phải hiểu cách mọi thứ hoạt động để như thế nào để có thể nhanh chỏng tìm ra lý do tại sao nó không chạy. Tips: Có thể sử dụng các công cụ debug của trình duyệt sẽ giúp cho cuộc sống và công việc của bạn dễ dàng hơn. Luôn nhớ rằng các công cụ debugg sẽ luôn là trợ thủ đắc lực của bạn.

Một số tài nguyên hữu ích mà tôi tìm thấy:

Pro-tip: console.log output có thể được tinh chỉnh bằng CSS. Điều này giúp log của bạn dễ identify hơn.

console.log('%c I want this to be big and red', 'font-size: 30px; color: red;');

Theo dấu dữ liệu

Vấn đề tiếp theo sẽ là một vấn đề mà bạn sẽ thường xuyên gặp phải, vì ngay cả chính tôi cũng thường gặp những sai lầm này.

Phần lớn việc phát triển phần mềm liên quan đến việc biến dữ liệu thành một format mà người dùng có thể hiểu được.

Các ứng dụng với luồng dữ liệu đơn hướng và ở tầm cỡ toàn cầu cần có một dòng dữ liệu trực tiếp để follow. Nguồn dữ liệu đến từ mọi nơi rất phức tạp, nột khi bạn tìm ra nguồn gốc của nó, bạn sẽ gỡ lỗi dễ dàng hơn.

Bẻ đũa phải bẻ từng chiếc

Codepen.io là trợ thủ đắc lực nhất của tôi, và nó cũng nên là bạn của bạn. Khi tôi không thể tìm ra nguyên nhân gây ra sự cố, tôi tạo một phiên bản đơn giản của sản phẩm. Sau đó chạy thử xem nó hoạt động có hoạt động hay không, rồi tích hợp nó vào môi trường (environment) mà mình đang làm. Bạn sẽ dễ dàng hơn để tìm ra những gì có thể phá vỡ UI của bạn trong một môi trường như vậy.

Hãy suy nghĩ về việc function sẽ hoạt động như thế nào

Nói đơn giản là tôi sẽ viết ra một kế hoạch để tính năng có thể chạy trơn tru từ trên xuống dưới. Nó giúp tôi nhìn rõ được cục diện của toàn bộ những gì mà mình sẽ bắt tay vào làm một cách có hệ thống nhất.

Ngoài ra, tôi có thể tham khảo lại những gì tôi đã viết hoặc cho mọi người biết những gì tôi đang nghĩ giúp giảm thiểu những sai sót không đáng có.

Vạn sự khởi đầu nan, gian nan đừng có nản

Theo như thuyết của tác giả Malcom Gladwell, sau 10.000 giờ đấu tranh trong công việc, bạn sẽ giải quyết các vấn đề tốt hơn. Bạn sẽ phải có thể làm bất kể điều gì, vì vậy tận hưởng những trải nghiệm sẽ giúp cho ngày làm việc của bạn tốt hơn nhiều. Cười với bản thân một chút và cố gắng giải quyết vấn đề. Bạn sẽ làm được, ngay cả khi bạn cần một chút trợ giúp.

Hãy phê bình có tính xây dựng và làm thường xuyên

Đồng đội của bạn muốn bạn làm tốt hơn. Các nhà phát triển cao cấp muốn bạn trở thành một developer giỏi hơn. Thực hiện theo lời khuyên của họ ngay cả khi bạn không hiểu tại sao họ lại nói bạn làm điều đó. Một người không thể biết mọi thứ.

Cứ từ từ, cháo sẽ nhừ

Làm công việc của bạn gấp gáp dẫn đến những sản phẩm không ổn định, có nhiều nhầm lẫn, và vô tình tăng thêm sự thất vọng. Thà sếp thấy sản phẩm ra trễ hơn là sản phẩm tệ hại với đống code được làm trong bế tắc.

Học phải đi đôi với hành

Bên cạnh học hỏi  từ công việc, tôi vẫn muốn tiếp tục học những điều mới ngoài việc xử lý cơ sở code. Điều này hoàn toàn khả thi nếu tôi dùng python, và xây dựng một con bot, làm việc thông qua video, hoặc làm việc trên một dự án cá nhân. Tôi đã làm một bảng với Zenhub + Github để theo dõi tình trạng của tôi, kpi và các task cần làm trong tháng. Việc giữ mục tiêu tháng đã buộc tôi phải tiếp tục học tập, xây dựng và vâng, viết blog trong thời gian của tôi.

Source: Medium – Freecodecamp

Các nền tảng tuyển dụng tốt nhất dành cho Software Engineer l Cập nhật năm 2022

Công ty của bạn có cần thuê một kỹ sư phần mềm không? Khả năng cao câu trả lời là có. Theo dữ liệu Monster Intelligence công bố vào tháng 10, các chuyên gia IT ( nhất là các kỹ sư phần mềm) là những người được tìm kiếm nhiều nhất. 12% của tất cả các công việc đang tuyển ở Mỹ thuộc lĩnh vực công nghệ.

Các doanh nghiệp lớn và nhỏ đang cạnh tranh trên thị trường để tạo ra những công nghệ tiên tiến tốt nhất, và nhu cầu tuyển dụng các vị trí IT ngày càng tăng đồng nghĩa với việc xu hướng tuyển dụng IT đang dần thay đổi. Khi các bài đăng tuyển dụng vị trí công nghệ dần bão hoà, bạn sẽ rất có lợi nếu biết được các điểm mạnh và yếu của các nền tảng tuyển dụng công nghệ. Ý tưởng là trên các trang tin tuyển dụng có lưu lượng truy cập cao, listing của bạn có nhiều hiển thị tin cậy hơn và nhiều hơn. Đó là việc cơ bản nhất mà một công ty hoặc agency tuyển dụng phải làm được để tiếp cận đúng ứng viên.

Chúng tôi tại Recruitee cũng đã thuê các nhà phát triển phần mềm để tinh chỉnh quá trình tuyển dụng để chiêu mộ được các tài năng công nghệ hàng đầu. Tại thời điểm này, chúng tôi đã thấy nhiều và muốn khuyến nghị một danh sách các trang tuyển dụng hàng đầu cho bạn. Các trang web sau không theo một thứ tự cụ thể nào, và giá cả được liệt kê có thể sẽ thay đổi theo thời gian.

1 – Stack Overflow 

Stack Overflow là một trang đăng tuyển các vị trí công nghệ rất dễ sử dụng. Họ tuyên bố có một cơ sở dữ liệu với 1000 CVs mới từ nhà phát triển mỗi ngày. Bạn có thể mua ” Featured Listings” hoặc ” Top Spots ” cho các bài đăng công việc của bạn. Featured Listings sắp xếp các công việc cần tuyển của bạn lên trang chủ và làm nổi bật chúng ở gần đầu kết quả tìm kiếm. Top Spots sắp xếp công việc của bạn trên các quảng cáo banner trên Stack Overflow.

Stack Overflow 

2 – Dice

Dice là một bảng tin đăng tuyển các vị trí tech tự hào với lượng truy cập khủng ( khoảng hai triệu ứng viên!). Bạn trả tiền cho mỗi vị trí đăng tuyển và tiết kiệm hơn với mỗi danh sách công việc bổ sung. Nếu bạn muốn chiêu mộ các ứng viên kĩ thuật có nhiều kinh nghiệm, đây là nền tảng dành cho bạn. Hãy nghĩ trang web này như con xúc xắc may mắn của bạn, và sẵn sàng đặt cược để có tất cả.

Dice

3 – Crunchboard

Trang tin tuyển dụng chính thức của TechCrunch, Crunchboard là một giao diện sành điệu được sử dụng để tìm kiếm các ứng viên IT có trình độ cao. Giá cả minh bạch, bao gồm số lượng bài đăng tuyển dụng, cũng như khoảng thời gian bài đăng tồn tại. Hãy mua một gói để tiết kiệm! Nó giống như việc mua bia. Thực ra thì không hẳn, nhưng bạn hiểu ý của tôi mà!

Crunchboard

4 – GitHub 

GitHub là một nền tảng để các developers cộng tác với nhau. Có điều gì cool hơn không? Nó cũng cung cấp một nơi để đăng tuyển, ngay những vị trí các developers hay nhìn. Giá cho mỗi danh sách là $450 hoạt động trong 30 ngày. Các vị trí tech đặc biệt nhạy cảm về thời gian, vì vậy những danh sách ngắn hơn sẽ là lợi thế của bạn ở trang web này.

5 – Masha

Mọi người đều đã nghe về Mashable, nhưng nếu chưa, bạn đã nghe rồi đấy. Giá dao động từ $ 259 đến $ 399, phụ thuộc vào mức độ hiển thị bạn mong muốn. Mashable là trung tâm tin tức công nghệ, do đó, bạn sẽ dễ dàng tìm thấy những kiến thức chuyên sâu và đặc trưng về công nghệ.

Masha

6 – Icrunchdata

Bên cạnh cái tên gây cười của nó, icrunchdata là một trang tin tức công nghệ cập nhật hàng tuần cho hơn một triệu người đọc. Vậy nó có gì đặc biệt hơn so với các web khác? Bạn cũng có thể đăng một danh sách tuyển dụng trên đó, với rất nhiều lựa chọn về độ dài và mức độ hiển thị.

7 – ITJobPro

Bạn muốn một công việc IT chuyên nghiệp? Hãy đăng danh sách của bạn lên ITJobPro. Với hơn hai triệu ứng viên IT, trang này tự tin cho rằng luôn có sẵn những công việc IT tốt nhất cho người xem của họ. Việc làm được đăng bởi các công ty hàng đầu, như IBM và Best Buy. Chi phí của ITJobPro được đánh giá là một trong những web phải chăng nhất ở mức $120 cho một danh sách 30 ngày.

8 –  Authentic Jobs 

Được sử dụng bởi Apple và The New York Times, Authentic Jobs có giao diện web đẹp nhất. ” Trang tuyển dụng hàng đầu dành cho các nhà thiết kế, hackers và các chuyên gia sáng tạo” – Đó là trang web hàng đầu để đăng các vị trí cần tuyển dụng của bạn. Một lợi ích khác của Authentic Jobs là giá phụ thuộc vào loại hình công việc đăng tuyển. Bằng phương thức này, bạn không phải trả nhiều hơn cho các vị trí thực tập hoặc ngắn hạn. Giá cho mỗi danh sách việc làm chỉ bắt đầu ở mức $100!

9 – WeWorkRemotely 

Nếu bạn đang thuê một chuyên gia công nghệ từ xa, WeWorkRemotely là một sự lựa chọn hoàn hảo. Nó có một vài phân loại công việc, nhưng hai mảng chính là developers và programmers. Danh sách công việc của bạn nằm trên trang web này trong khoảng thời gian 30 ngày mà sẽ mất $200. Để danh sách của bạn nổi bật, bạn có thể phải trả thêm $50.

10 – Indeed Prime 

Indeed Prime là một sự bổ sung cho Indeed.com phục vụ việc đăng tuyển kĩ thuật. Bạn có thể truy cập vào danh sách tài năng công nghệ hàng tuần khi bạn đăng ký với danh nghĩa ” Employer “. Về vấn đề giá cả, tất cả đều nằm trong fineprint, vì vậy hãy đọc kĩ nó trước khi bạn đăng ký! Indeed Prime hoạt động theo mô hình thuê bao. Bạn sẽ phải trả một khoản phí cố định trước khi đăng tuyển công việc.

11 – F6S

F6S là nơi mà các tài năng công nghệ tìm kiếm những startups để tham gia, và các startups đăng danh sách việc cần tuyển miễn phí! Các vị trí cần tuyển sẽ phù hợp với những tài năng giỏi nhất theo nhu cầu của bạn. Điểm đặc biệt của F6S là ý thức cộng đồng. Một đại diện từ team tuyển dụng của bạn có thể làm một profile, và các ứng viên có thể thấy một hình ảnh để tự đánh giá có phù hợp với công ty đó hay không! Điều này khác biệt rất nhiều so với bảng tin tuyển dụng bình thường chỉ hiển thị tên danh sách các công ty. Nó gần giống như một nền tảng social media cho danh sách việc làm và người tìm việc. Những kết nối cá nhân với các ứng cử viên tạo ra trải nghiệm tốt hơn.

12 – Smashing Jobs 

Smashing Jobs có mối quan hệ với Tạp chí Smashing, với khoảng 4 triệu người xem hàng tháng. Nó có một nguồn khổng lồ các chuyên gia sáng tạo và công nghệ có thể thấy danh sách công việc của bạn! Độc đáo hơn, trang web này liệt kê danh sách việc làm thành hai loại: toàn thời gian ($225) và freelance ($75). Điều này cho thấy họ nhận ra tính linh hoạt của lĩnh vực này. Ngoài ra, Smashing Jobs cung cấp các gói credits nếu sắp tới bạn dự đoán cần phải đăng nhiều việc hơn. Ví dụ: bạn có thể mua 5 credits với $ 300 hoặc 10 credits với mức 525 đô la, mỗi gói tiết kiệm 30%.

Niche Job Boards

13 – AndroidDev

AndroidDev Digest là bản tin hàng tuần cho tất cả mọi thứ trong bản tin Android Development. Các danh sách việc làm dành riêng cho Nhà phát triển Android, cụ thể, được xuất bản trong bản tin, cũng như phần công việc của trang web. Bạn có thể đăng đến 4 tuần, và mỗi tuần tốn $ 25. Nếu bạn cần tuyển một Android Developer, AndroidDev là một nơi tuyệt vời để bắt đầu, đạt khoảng 16.500 độc giả mục tiêu.

Android Developer Jobs in Topdev

14 – Angular Jobs

Angular Jobs không chỉ cho phép tự do đăng, mà còn phục vụ cho các chuyên gia IT. Đây là cộng đồng AngularJS số 1. Nếu bạn muốn các bài đăng của bạn hiển thị trong 30 ngày, bạn chỉ cần trả $280.

Tham khảo thêm các vị trí Angular Jobs in Topdev

15 – Python Job Board

Nếu bạn đang tìm kiếm một Python engineer, không nơi nào có thể tìm kiếm việc làm tốt hơn trang web chính thức của phần mềm đó. Nó cho phép tự do đăng tuyển dụng, nhưng họ muốn đó là một nơi uy tín để tìm các công việc phần mềm, do đó, các bài đăng phải được kiểm duyệt trước. Lưu ý rằng có thể sẽ mất nhiều thời gian hơn để đăng, nhưng khả năng bài đăng trên web này tiếp cận đúng đối tượng cao hơn.

43 Python Jobs in Topdev

16 – Python Jobs HQ 

Python Jobs HQ là một nền tảng tuyển dụng đặc thù dành cho các nhà phát triển Python. Sự khác biệt ở đây là trang web được tích hợp với Pycoder’s Weekly, một tạp chí trực tuyến nhằm vào các Python coders, nên phạm vi tiếp cận của danh sách việc làm đang ngày càng mở rộng rất nhiều! Ngoài ra, danh sách công việc của bạn được “đẩy” đến các tài khoản Twitter liên quan, với những người theo dõi tuyển dụng, cũng như “đẩy” một bản tin email, khi có ai đăng mới lên web! Một bài đăng việc sẽ có giá $199 trong 45 ngày, 3 bài đăng việc làm có giá $597,60, và gói 5 bài đăng giá $796.

17 – DataJobs 

Nếu bạn đang chiêu mộ các vị trí Big data hoặc phân tích dữ liệu, DataJobs là trang web dành cho bạn. Xếp hạng các doanh nghiệp tuyển dụng nổi bật bao gồm những cái tên lớn như Công ty Walt Disney và Đại học Princeton! Ngoài ra, nó có giá khá linh hoạt và giảm giá cho các công ty khởi nghiệp. Đối với Basic Recruiting (một bài đăng tuyển dụng), chi phí là $150 trong suốt một tháng. Tùy chọn Unlimited Recruiting cho phép đăng tải các bài viết không giới hạn chỉ với $250 mỗi tháng.

18 – RubyNow

Với khởi đầu của Ruby là nền tảng tuyển dụng Rails, Ruby Now có ( như bạn đoán ) nguồn các nhà phát triển từ Ruby on Rails. Đã hoạt động trong khoảng 10 năm, nó có một nguồn tài năng lớn, thích hợp cho bạn tìm kiếm. Giá ở mức $99 cho một bài đăng Tiêu chuẩn, bao gồm gửi email và Twitter, gửi bài ngay lập tức, và thời gian đăng trong 45 ngày. Các bài đăng Premium chỉ khác khi chúng hiên thị trên bảng tin tuyển dụng. Họ có một biểu tượng nhiều màu ở góc trên bên trái với $149 mỗi 45 ngày. Các bài đăng tuyển dụng Chuyên gia có một biểu tượng riêng, nhưng chúng có một notch với highlight trong phần nội dung văn bản. Ngoài ra, RubyNow cũng cung cấp mã giảm giá ngay trên trang web trong một khoảng thời gian giới hạn, vì vậy hãy theo dõi chúng!

19 – Ruby on Rails Jobs

Ruby on Rails Jobs tự hào là một bảng tin tuyển dụng đặc thù. Nó chỉ tập trung vào các nhà phát triển Rails, giúp các ứng viên đủ điều kiện dễ dàng tìm được công việc phù hợp hơn. Các công ty như Sony và eHarmony đã đăng trên trang này, và danh sách công việc của bạn sẽ được tweet đến hơn 3.000 người theo dõi, cũng như gửi trong email của bản tin hàng tuần.

Xem thêm các vị trí Ruby on Rails Jobs in Topdev

20 – BigDataJobs

Được thành lập bởi và phục vụ cho các chuyên gia Big Data, BigDataJobs có ba gói đăng việc khác nhau. Thời gian hiển thị là 30 ngày, và bạn có thể tiết kiệm tiền bằng cách mua gói ba hoặc năm công việc một lúc. Công ty cũng tweet và email danh sách việc làm của bạn đến những người theo dõi và subcribers.

Tham khảo các vị trí tuyển dụng Big Data lương cao tại Topdev.

21 – Core Intuition Jobs

Core Intuition là bảng tin tuyển dụng đặc biệt dành cho các nhà phát triển iOS và Mac Cocoa. Chi phí là $200 để đăng một danh sách trong vòng 30 ngày. Core Intuition nhận được những nhận xét tốt từ các công ty lớn như Salesforce, và có một phần mềm đi kèm Intuition Podcast mang lại lưu lượng truy cập cho trang web.

22 – Upload VR

Upload là trang web chuyên dành các công việc VR và AR. Hiện tại có rất nhiều startups thực tế ảo, và họ cũng là một trong số những công ty sáng tạo nhất. Nếu công ty bạn là một trong số đó, hãy tìm tài năng ở đây! Thời gian đăng tuyển dài hơn hầu hết ở những trang khác ( 90 ngày ), và chúng đều được miễn phí! Bạn có thể tự do để trả nếu bạn muốn, nhưng các bài viết đều miễn phí!

23 – Ember

Ember là trang tin tuyển dụng cho phép bạn đăng tin hơn 30 ngày cho mỗi đăng, tối đa trong 45 ngày. Giá không miễn phí, nhưng Ember có giá tốt so với các trang web tương tự. Ember là một khuôn mẫu JavaScript mã nguồn mở cho phép các nhà phát triển tạo ra các ứng dụng web một trang có thể mở rộng được một cách nhanh chóng và dễ dàng. Với sự phổ biến của nó, ngày càng nhiều vị trí đòi hỏi kĩ năng Ember. Nếu bạn đang chiêu mộ một vị trí như vậy, đây là trang web tốt nhất để đăng tuyển. Các công ty hàng đầu, như Netflix, sử dụng trang web này để đăng các danh sách công việc tương tự.

24 – WP hired

Nếu bạn đang tìm kiếm một nhà phát triển WordPress, WP Hired là một nơi hoàn hảo để đăng tuyển các vị trí ấy. Bạn có thể chiêu mộ toàn cầu, và với sự tập trung của trang web này, bạn sẽ có được tài năng mà bạn cần.

Main Job Boards

25 – Indeed

Indeed là ” tên ở nhà ” trong thế giới săn việc làm. Các bài đăng tuyển dụng có thể miễn phí, xuất hiện trong các tìm kiếm thông thường trên trang web, hoặc được tài trợ, xuất hiện ở một điểm dễ nhìn phụ thuộc ngân sách được thiết lập (bắt đầu từ 5$ một ngày). Mặc dù Indeed không chỉ chuyên đăng tuyển các công việc về công nghệ, rất nhiều người tìm việc thường xuyên truy cập vào trang web, nên bạn cũng nên thử một bài đăng miễn phí trên đây.

26 – Glassdoor 

Glassdoor được biết đến chủ yếu nhờ các đánh giá công ty của những nhân viên cũ và hiện tại, cũng như những ứng viên bị từ chối. Nếu công ty của bạn ở vị trí tốt trên trang web, bạn nên xem xét cách đăng việc trên Glassdoor! Glassdoor tự hào về việc tiết kiệm 30% chi phí cho mỗi trường hợp tuyển dụng so với các bảng tin tuyển dụng truyền thống với khoảng 30 triệu người dùng duy nhất mỗi tháng. Bạn có thể đăng tuyển lên đến 10 công việc miễn phí trong 7 ngày. Sau đó, sau khi chương trình thử nghiệm kết thúc, bạn có thể đăng một công việc (hoặc”gói” ba hoặc bảy ) trong vòng 30 ngày. Bạn phải liên hệ với đại diện của Glassdoor để có được một gói tùy chỉnh cho việc này.

27 – JustTechJobs 

Giao diện đơn giản của JustTechJobs là một lợi thế khi có thể đăng và xem dễ dàng hơn. JustTechJobs cũng có một số nhà tuyển dụng hàng đầu, như Johnson & Johnson trên đó. Quy trình đăng tuyển đang được sửa đổi, nhưng giá khởi điểm là 279 USD cho một danh sách 30 ngày

28 – ITJobCafe

Có một sự thật ai cũng biết là các chuyên gia CNTT thích môi trường làm việc của quán cà phê. ITJobCafe không phải là ngoại lệ. Đó là một bảng tin tuyển dụng cho phép bạn đăng đơn lẻ hoặc hàng loạt các công việc và nhận ngay 25 hồ sơ phù hợp. Một công việc đơn lẻ đang triển khai ở mức $149 mỗi 30 ngày, và một gói công việc (10 công việc) đang triển khai ở mức $ 1000 trong 30 ngày.

29 – TopTechJobs 

TopTechJobs không chỉ có nhiều lựa chọn đăng tuyển mà còn cung cấp các tìm kiếm resume với mức giá cố định theo tháng tùy thuộc vào số lần xem bạn mong muốn sử dụng. TopTechJobs định vị nó như một mạng lưới phân phối công việc với một cơ sở dữ liệu đang tiếp tục mở rộng. Sẽ rất có lợi nếu bạn biết tận dụng lợi thế của gói kết hợp!

30 – Trovit 

Trovit là một công cụ tìm kiếm việc làm tổng hợp kết quả tìm kiếm từ hàng ngàn trang web chỉ trong một tìm kiếm. Với bản cập nhật gần nhất, bạn không còn có thể đăng tuyển việc làm ở đây miễn phí.

31 – Jooble 

Jooble cũng tương tự như Trovit ở điểm nó là một công cụ tìm kiếm việc làm có nguồn từ internet. Để hiển thị trên Jooble, bạn phải là một đối tác. Hoặc, bạn có thể đăng trực tiếp từ Recruitee. Chúng tôi sẽ quay trở lại vấn đề này vào cuối bài viết này.

32 – Adzuna 

Adzuna cũng là một công cụ tìm kiếm việc làm, nhưng bây giờ cung cấp thêm dịch vụ đăng tuyển việc. Một danh sách premium miễn phí được cung cấp cho các nhà tuyển dụng, nhưng chỉ trong một thời gian giới hạn, vì vậy hãy hành động thật nhanh! Với giao diện đẹp và hiện đại, trang web này dần phổ biến trên toàn thế giới.

33 – Eurojobs 

Eurojobs là trang web việc làm lớn nhất của Châu Âu và cho phép các ứng viên lọc theo quốc gia, thành phố hoặc loại hình việc làm. Đăng tin tuyển dụng trên Eurojobs là miễn phí.

34 – Careerjet 

Careerjet là một công cụ tìm kiếm việc làm khác, lấy nguồn từ 30.000 trang web khác nhau trên toàn thế giới. Tương tự như các công cụ tìm kiếm khác, bạn có thể quảng cáo trên trang web hoặc trở thành đối tác để hiển thị trong tìm kiếm.

35 – JobInventory 

JobInventory là một công cụ tìm kiếm việc làm và cho phép các nhà tuyển dụng đăng tuyển miễn phí. Tuy nhiên, nếu bạn muốn xếp hạng cao hơn trong tìm kiếm, bạn có thể tham gia vào dịch vụ được gọi là “Contributor Badges and Links”, có nghĩa là bạn quảng cáo JobInventory trên trang web của riêng bạn. Việc này sẽ ngay lập tức cho phép danh sách công việc của bạn dễ dàng tìm kiếm hơn trong các tìm kiếm có liên quan.

36 – Monster

Monster là một trang tìm kiếm việc làm rất phổ biến. Nếu bạn đăng một công việc, bạn có thể nhận được tối đa 20 hồ sơ của ứng viên đủ tiêu chuẩn ngay lập tức. Giá cho việc đăng tin tuyển dụng phụ thuộc vào ba điều: số lượng danh sách, loại công việc, và vị trí của công việc. Ví dụ: một danh sách việc làm tìm kiếm Android Developer chỉ ở Philadelphia, PA chạy với giá $499 trong 60 ngày.

37 – CareerBuilder

Với CareerBuilder, bạn có thể đăng lên đến 35 danh sách việc làm, với giá lần đầu bắt đầu từ $ 419. CareerBuilder tự hào có trung bình 30 ứng viên cho mỗi danh sách việc làm, do đó mức giá có vẻ cao ấy có thể đáng đầu tư.

38 – LinkedIn

Bên cạnh được biết đến như Facebook dành cho các chuyên gia, LinkedIn cũng cung cấp một nơi để đăng tuyển công việc. Nó thông qua LinkedIn Recruiter và có hướng dẫn từng bước rất cụ thể. Giá $ 195 cho một bài đăng 30 ngày, và giá của mỗi bài đăng sẽ giảm khi nhà tuyển dụng đăng với số lượng lớn.

39 – StartUpHire

Nếu công ty của bạn là một Startup đang chiêu mộ nhân tài, StartUpHire là một trang web không thể bỏ qua. Các bài đăng cơ bản với giá khởi điểm từ $79 và các bài đăng nổi bật với giá $149. Trong một khoảng thời gian giới hạn, khi một chương trình quảng cáo diễn ra, các bài đăng nổi bật chỉ còn $99.

40 – StartupJobs 

Trang web này có những lựa chọn cơ bản dành cho bạn, và nó hoàn toàn miễn phí! StartupJobs chủ yếu tập trung vào các công ty startups được thành lập ở Mỹ và Canada, và các vị trí đăng tuyển trong ngành đó. Nếu bạn muốn công việc bạn đăng tuyển được nổi bật trên trang web, xuất hiện trước tất cả những trang khác, hãy nâng cấp chỉ với $100. Họ cũng có những gói dịch vụ khác nhau, nếu công ty của bạn không phải là startups và muốn tuyển dụng.

41 – Jobsdb

Nếu công ty của bạn ở Hồng Kông, Indonesia, Singapore hoặc Thái Lan, JobsDB là trang web nên cân nhắc. Đây là công cụ tìm kiếm mà bạn phải xây dựng mối quan hệ đối tác để xếp hạng cao trong kết quả tìm kiếm.

42 – Craigslist 

Craigslist miễn phí đăng bài ở hầu hết các địa điểm và đăng các quảng cáo mới trên mặt báo. Nếu bạn đang tìm kiếm nhân sự tại địa phương, trang web này là một bắt đầu tuyệt vời. Chỉ cần theo dõi cho Craigslist cổ điển.

43 – AngelList 

AngelList có một logo khá dễ thương và hoạt động như một bảng tin tuyển dụng kết nối các chuyên gia với startups cần họ. Đăng một công việc miễn phí trên trang này.

AngelList 

44 – TalentZoo

TalentZoo là một bảng tin tuyển dụng đặc thù nhưng hoạt động ở khá nhiều mảng. Nó cung cấp các công việc liên quan đến quảng cáo, marketing, tech và thiết kế. Danh sách việc làm được đăng trong 45 ngày và giá bắt đầu từ $249. TalentZoo cũng cung cấp một cơ sở dữ liệu resume và portfolios, cũng như giá tùy chỉnh khi bạn liên hệ với đại diện của họ.

TalentZoo

45 – GeekWork

Là một phần của GeekWire, một trang tin nóng về các chủ đề công nghệ và kinh doanh, GeekWork là một nền tảng tuyển dụng nhằm phục vụ mảng công nghệ, cho phép các đối tượng đúng tiếp cận các danh sách của bạn. Đăng tuyển một danh sách tiêu chuẩn miễn phí, nhưng bạn cũng có các lựa chọn!

GeekWork

46 – Remotive

Như tên cho thấy, Remotive là một hội đồng quản trị để đăng các vị trí tuyển dụng từ xa của bạn. Các công việc về kỹ thuật là một trong những lĩnh vực phát triển nhất trong lĩnh vực này, vì thế, nếu bạn đang tìm kiếm nguồn hàng trên toàn cầu, đây là một điều không hề dễ dàng để đăng ở đây. Các công ty hàng đầu đã sử dụng trang web, do đó, giá 149 $ giá trị là nó có giá trị để tham gia vào gói.

47 – Digital NYC

Nếu bạn ở khu vực thành phố New York và thuê, bạn đang may mắn! Digital NYC là “trung tâm của NYC dành cho công nghệ và công ty mới thành lập”. Dường như cũng miễn phí và dựa trên bài trình bày. Các hồ sơ xin việc được xem xét và đưa vào một danh sách đặc biệt sau đó được phân phát cho độc giả của ấn bản trực tuyến. Các công ty có trụ sở tại NYC có thể hưởng lợi rất nhiều từ việc tiếp xúc với các ứng cử viên đúng mục tiêu!

Digital NYC 

48 – Computer Jobs 

Giống như tên của nó, Việc làm máy tính là một bảng việc làm đơn giản và dễ hiểu. Các công việc CNTT có thể được đăng ở đây trong một tuần, rất hữu ích cho lĩnh vực đang di chuyển nhanh. Đó có thể là tất cả những gì bạn cần! Họ có các gói khác có sẵn, cũng như, trong dòng sản phẩm đầy đủ của họ. Công việc máy tính sẽ rất có thể có cái gì đó phù hợp với nhu cầu của bạn và nhận được danh sách của bạn ở phía trước của người tìm việc có liên quan.

Computer Jobs 

Bonus: Free Job Boards 

49 – PostJobFree

Tên trang web nói tất cả. Trang web rất đơn giản và có các video hướng dẫn để thuận tiện cho bạn.

50 – JobSpider

Ngay cả khi bạn sợ nhện, đừng sợ JobSpider. Đăng việc miễn phí và tìm kiếm cơ sở dữ liệu miễn phí có sẵn.

51 – eBay Classifieds

eBay không chỉ là một nơi để thử và bán Beanie Babies của bạn với giá 2000 đô la. Các phân loại phần tương tự như Craigslist trong đó nó được mô tả theo vị trí.

52 – JobisJob

Tên lạ, mát mẻ khái niệm. Với các quảng cáo việc làm miễn phí và một giao diện tuyệt vời cho phép tìm kiếm theo vị trí và thể loại, thật là xấu hổ nếu không sử dụng JobisJob.

53 – Doostang

Doostang có toàn bộ phần công việc về công nghệ và có một cộng đồng với hơn một triệu chuyên gia.

54 – Backpage

Backpage là một trang đăng rao vặt công việc Craigslist-esque, với các bản phân phối vị trí cụ thể miễn phí.

55 – FlexJobs

FlexJobs là trang web hàng đầu cho các công việc tự do và ngắn hạn. Nếu danh sách việc làm của bạn là không điển hình, đây là nơi để đăng! Không có một lượng lớn việc làm trên trang web này thường xuyên, vì vậy nó là một cơ hội để được những con cá lớn trong ao nhỏ, cũng.

56 – AllStarJobs

AllStarJobs nâng cấp hệ thống của mình và đặt một cơ sở dữ liệu đa dạng về sự nghiệp và cơ hội giáo dục. Bạn có thể đăng công việc không giới hạn miễn phí!

57 – Slack At Work 

Slack là một công cụ truyền thông cho các công ty thông minh, và nếu công ty của bạn sử dụng phần mềm kiểu dáng đẹp của nó, bạn có thể đăng một công việc lên bảng quản lý công việc. Nếu công ty của bạn đã có trong kế hoạch trả tiền của Slack, bạn có thể liệt kê một việc làm miễn phí!

Nguồn: Recruitee

TopDev via 

  Khan hiếm lập trình viên làm việc tại Nhật, nhà tuyển dụng chấp nhận tuyển cả IT không biết tiếng Nhật

Kinh nghiệm xương máu từ 9 tháng làm kỹ sư phần mềm (P1)

Tác giả: Benjamin Schachter

Sau 9 tháng làm việc tại Dexter với tư cách là một lập trình viên, tôi đã học được rất nhiều điều.  Cũng vì vậy, tôi đã quyết định viết một bài đăng blog chia sẽ về những trải nghiệm, cũng như một bài đăng một bài kĩ thuật về Self Positioning React Component mà tôi đã thực hiện trong vài tháng làm việc tại đây. Nhận được công việc mới chỉ là bước khởi đầu, làm thật tốt công việc được giao lại là một câu chuyện hoàn toàn khác, là một lập trình viên tôi hoàn toàn hiểu điều đó.

Những suy nghĩ của tôi về vai trò của mình đã thay đổi đáng kể kể từ khi tôi bắt đầu. Tôi đã nghĩ rằng trở thành một nhà phát triển phần mềm thì phải “xử lý” đám code càng nhanh càng tốt. Tuy nhiên, điều đó có vẻ không đúng thực tế lắm, như chuyện bạn viết code nhanh nhưng không chất lượng, buộc phải thay đổi liên tục sẽ không phải là cách giúp cho doanh nghiệp của bản có thể bị trì trệ hơn. May mắn thay, tôi đã gặp một người sếp có suy nghĩ tương tự, anh ấy cũng là dân phần mềm như tôi.

Mục tiêu của bạn sẽ là: Viết code chất lượng tốt và giao tiếp tốt với đồng nghiệp. Bạn không phải được trả tiền chỉ để code, bạn được trả tiền để suy nghĩ và tìm ra vấn đề. Sản phẩm đi kèm là tư duy tinh tể và chỉ dẫn máy làm theo dưới dạng code. Tôi muốn giải quyết vấn đề trong một dòng code dễ đọc hơn 10 dòng code khó hiểu. Tôi muốn giải quyết vấn đề trong 5 dòng code có thể đọc được so với một dòng code phức tạp, nested code kèm theo nhiều loại toán tử phức tạp. Tôi nghĩ bạn sẽ hiểu ý tôi muốn nói gì.

Muốn biết phải hỏi muốn giỏi phải học.

Những ngày đầu, tôi đã được sếp gửi cho một đường link để tham khảo, sau khi đọc tôi thật sự lo lắng về khả năng của mình. Tôi vẫn luôn rất ý thức trước khi đặt bất kỳ câu hỏi nào.

Tôi có hẳn riêng mình một check list trước khi nhờ người khác hỗ trợ điều gì:

  • Đây có phải là một câu hỏi mà tôi đã hỏi trước đó, và nếu có, tôi đã ghi lại câu trả lời ở đâu?
  • Đây có phải là điều tôi có thể Google không?
  • Điều này đã được ghi chép lại ở đâu đó trong nội bộ?
  • Chuyện gì đang xảy ra ở đây? Nguyên nhân sâu xa của lỗi hoặc các phản ứng bất ngờ mà tôi đang gặp phải là gì?
  • Tôi có thực sự hiểu câu hỏi tôi đang cố gắng để trả lời? Bạn có thể dành thời gian để đọc lại vấn đề một lần nữa thay vì đưa ra câu trả lời nửa vời hoặc câu trả lời hấp tấp.

Sau khi làm theo các bước này, tôi sẽ thử giải quyết vấn đề một mình, tìm một giải pháp đã được từng được document lại, hoặc hỏi một câu hỏi với ngữ cảnh tốt hơn và chi tiết hơn để giúp người khác dễ dàng trả lời hơn. Thậm chí, tốt hơn nữa, nếu tôi có thể đặt một câu hỏi hay và được trả lời qua đoạn chat, đồng đội của tôi không cần phải bỏ mọi thứ để giúp tôi.

Nếu tôi đã đi hết 90% con đường để giải quyết vấn đề thì thật ra chỉ cần 10% sự trợ giúp nữa thôi, một nhà phát triển cấp cao sẽ rất vui khi giúp bạn vì biết rằng bạn đã cố gắng hết mức có thể. Tìm kiếm người khác để giải quyết vấn đề của bạn không phải là một cách tuyệt vời để xây dựng lòng tin trong nhóm của bạn.

Những người thông minh thích những câu hỏi hay – vì vậy đừng ngại khi hỏi họ.

Tránh những sai lầm cũ và hỏi những câu hỏi mà ai cũng đã biết câu trả lời.

Điều này nói dễ hơn là thực hiện, bạn có thể ứng dụng nó vào bất cứ ngành nào, không chỉ lập trình. Rất nhiều khái niệm và thông tin mới sẽ khiến mắc phải những sai lầm không đáng có, và là không thể tránh khỏi. Để hạn chế việc này, hãy nghiên cứu nhiều hơn, Google có đầy đủ thông tin. Xem kĩ các tài liệu, chúng là bạn của bạn. Hãy hỏi nếu như sau khi tìm hiểu bạn vẫn không có trả lời. Sau đó hãy viết chúng ra thành tài liệu, và đặt cho mình những mục tiêu để cải thiện nó.

Hãy đảm bảo rằng lần tiếp theo bạn gặp vấn đề tương tự, bạn biết phải làm gì. Tất cả chúng ta đều mắc sai lầm, nhưng việc tự ý thức và nỗ lực thay đổi là cách để mọi người trở nên tốt hơn.

Luôn xem lại những gì mình đã làm

Không ai thích đi qua PR và bảo bạn gỡ bỏ console.logs,  debuggers hoặc bảo bạn sửa lỗi linting. Tôi sẽ không xuất bản bài đăng này mà không đọc qua một vài lần và nhờ một người bạn xem qua nó trước.

Nhìn kĩ vào code của bạn và tự hỏi những câu hỏi sau:

  • Tôi đã viết một đoạn logic phức tạp. Có chức năng tương tự nào trong ứng dụng có thể giải quyết vấn đề này theo cách dễ đọc hơn, linh hoạt hơn hay chung chung không?
  • Nếu không, tôi có nhớ lý do tại sao tôi đã viết code này trong một tuần hay không? Nếu câu trả lời là không, tôi muốn đổi code hoặc bình luận nó. Người duyệt PR nên có một số lí do giải thích tại sao tôi lại đưa ra quyết định đó.
  • Hãy chắc chắn rằng code của bạn đang đi qua linting và được kiểm tra trước khi đưa nó cho bất kì ai khác.
  • Tôi có đang lặp lại hay không? Tôi có thể làm gọn logic bị lặp bằng một hàm hay không ?
  • Nếu đây là code của người khác mà tôi đang xem, tôi sẽ đưa ra những bình luận nào? Tôi muốn thay đổi gì để nó rõ ràng hơn?

Hãy thử nhìn vào code của bạn vào ngày hôm sau, bạn sẽ nhìn thấy rất nhiều sự khác biệt. Liệu có gì không ổn trong logic của các đoạn code? Liệu các component của bạn có xử lý logic đúng hay không?

Ngoài ra, việc tự đánh giá code tốt tiết kiệm thời gian và tiền bạc cho công ty. Đó là cách tốt nhất để bạn tìm ra bug của bạn và tự khắc phục chúng thay vì phải nhờ người khác tìm ra chúng sau hai ngày.

Điều cuối cùng nói về việc xem lại code của bạn. Test tất cả vào MỌI THỨ bạn đã làm. Tôi muốn code của tôi gửi cho bất cứ ai cũng phải tốt đến mức không thể chỉnh sửa. Nếu họ bấm vào một trang mới và thấy được một lỗi lớn hoặc màn hình trắng, điều đó chứng minh tôi đã không thực sự xem xét lại công việc của mình. Grep cho code bạn đã chỉnh sửa và đảm bảo rằng bạn không làm hỏng bất cứ thứ gì bằng việc bổ sung thêm vào component.

Nghe có vẻ ngớ ngẩn, nhưng những sản phẩm có quá nhiều dòng code lớn phức tạp và bạn có thể không nhận ra cho đến khi bạn đã làm hỏng một cái gì đó.

Tôi chắc rằng, bạn sẽ không muốn xem bản draft đầu tiên của bài blog này 🙂

  Kinh nghiệm xương máu từ 9 tháng làm kỹ sư phần mềm ( P2 )

Bài viết gốc được đăng tải tại Medium – Freecodecamp

Bài học của CEO Na Uy giúp các lập trình viên đột phá hơn trong từng dòng code

Với sự phát triển mạnh mẽ của công nghệ, đặc biệt sau trào lưu IoT là sự bùng nổ của một thời kỳ ” nhà nhà, người người làm phần mềm”. Tuy nhiên, thực trạng thiếu hụt về nhân lực công nghệ, nhiều công ty công nghệ đã chuyển sang thuê ngoài dịch vụ thay vì tự phát triển sản phẩm của riêng mình, nhằm tiết kiệm chi phí, giải phóng bớt sự phụ thuộc vào nguồn nhân lực nội bộ. Chưa bao giờ thị trường Outsourcing lại trở nên nhộn nhịp như hiện nay, đặc biệt là tại các quốc gia đang phát triển khu vực Đông Nam Á, trong đó có Việt Nam.

Outsourceit- Facilitated Work Hub là một trong những công ty chuyên về cung cấp các dịch vụ outsourcing cho lĩnh vực IT. Hãng đã hoạt động được tại Việt Nam 11 năm với rất nhiều projects khác nhau cả thị trường trong và ngoài nước. Qua đó thể hiện chất lượng mà các dịch vụ và sản phẩm của Outsourceit- Facilitated Work Hub luôn được các đối tác tin tưởng. Trong đó, có sự đóng góp vô cùng to lớn từ đội ngũ các developers Việt Nam đầy tài năng cũng như táo báo trong suy nghĩ.

Hôm nay, TopDev đã có buổi phỏng vấn trao đổi với ØYSTEIN BAEKO, CEO của Outsourceit- Facilitated Work Hub về tầm nhìn của ông về developer Việt Nam nói riêng cũng như làm thể nào để đột phá tư duy và sáng tạo trong IT.

Anh có thể giới thiệu đôi chút về công ty của mình không?

Thời điểm 2001, tôi vẫn còn đang đảm nhiệm vai trò là developer cho một khách hàng cần outsourcing. Công việc thì luôn quá nhiều và thường xuyên phải làm thêm giờ. Lúc đấy, tôi chợt nghĩ là sao lại không nhờ một người quen, cũng có kĩ năng và sử dụng công nghệ giống nhau, phụ giúp làm công việc của tôi. Anh ta có thể ngồi ở bất cứ nơi đâu, từ bất cứ quốc gia nào trên thế giới và vẫn có thể làm được 90% khối lượng công việc của project. Điều quan trọng là 10% còn lại sẽ bắt buộc phải làm onsite, bởi chính các thành viên chủ chốt.

Với sự phối hợp từ hai bên, giữa làm onsite và outsourcing tại các nước như Việt Nam, sẽ cho phép nhận được lợi ích từ cả hai và tạo ra các sản phẩm tốt nhất. Như vậy, Outsourceit- Facilitated Work Hub đã ra đời tại Oslo, thủ đô của Na Uy.

Năm 2003, công ty đã từng làm nhiều project với các nước khác nhau như Ấn độ, Việt Nam, Thái Lan. Ngay lập tức, tôi đã bị thu hút bởi sự thẳng thắn, rõ ràng cũng như là sự thân thiện của con người nơi đây. Do đó mà công ty quyết định mở văn phòng tại Việt Nam vào năm 2007.

Là một chuyên gia trong lĩnh vực outsourcing, anh nghĩ như thế nào về sự phát triển trong tương lai 10 năm nữa? Cũng như ảnh hưởng của nó với các nước có chi phí lao động rẻ như Việt Nam?

Tôi nghĩ câu trả lời cũng như 10 năm trước. Vào năm 2007, thị trường Việt Nam nổi bật bởi hiệu năng cao cũng như chi phí lao động rẻ. Kể từ đó đến nay, mức lương của developer Việt Nam đã tăng ít nhất gấp 2 tới 3 lần. Nhưng điều đó cũng có nghĩa Việt Nam đang mất dẫn ưu thế nếu họ chỉ tập trung thế mạnh vào chi phí rẻ. Thay vào đó, Việt Nam cần phải tìm kiếm những giá trị khác. Singapore là một ví dụ điển hình khi từ một đất nước nghèo đã nhảy vọt và gắn liền với hình ảnh các sản phẩm cao cấp, chất lượng.

Tôi tin rằng Việt Nam cũng đang trong quá trình tương tự, các bạn sẽ cần tìm kiếm được một thế mạnh mới.

Theo anh, Việt Nam có phải là một điểm đến của những đổi mới công nghệ trong thời gian tới không?

Tôi không nghĩ là Việt Nam được biết nhiều tới bởi sự đổi mới sáng tạo vượt bậc về công nghệ trên mặt trận toàn cầu, mà được biết đến với hiệu quả năng suất rất cao đồng thời chi phí lại thấp. Ở Việt Nam, chúng ta có lợi thế là phải luôn nghĩ ra nhiều giải pháp để giải quyết 1 vấn đề phức tạp. Tuy nhiên, Việt Nam cần phải hướng mình tới đổi mới sáng tạo công nghệ nhiều hơn trong tương lai để có thể duy trì sự phát triển trong kinh tế dài lâu.

Anh nghĩ mindset như thế nào là cần thiết cho các developers Việt Nam cho sự thay đổi cũng như các xu hướng mới trong tương lai để hướng đến việc phát triển làm product nhiều hơn thay vì chỉ tập trung vào outsourcing?

Việt Nam hiện tại đa phần vẫn còn tập trung làm về outsourcing mà như vậy thì không thể gọi là đổi mới sáng tạo, bởi chỉ đơn giản là làm những thứ mà người khác đã nghĩ ra. Và tôi nghĩ để đạt được những cột mốc mới, điều quan trọng nhất chúng ta cần phải tìm hiểu và học hỏi thêm rất nhiều.

Hãy tự hỏi bản thân vì sao phải làm cách này? Tại sao không phải là cách khác? Sao mọi người lại nghĩ theo hướng như vậy? Cũng như có đủ sự tự tin để có thể làm điều mới lạ. Có thể tranh luận lại với sếp cũng như là việc người lớn tuổi hơn cho phép giới trẻ tự do hơn. Vì vậy mà tôi nghĩ nó sẽ là một quá trình lâu dài để tạo ra sự tự tin đấy.

Vậy để có được sự tự tin cũng như khả năng đưa ra quyết định thì developer cần có những kĩ năng mềm hay kinh nghiệm gì?

Bạn cần phải dám chấp nhận mạo hiểm. Bởi vì việc nghe và làm theo người khác hàng ngày vốn rất là dễ nhưng nó sẽ không làm cho ta phát triển thêm được. Vì vậy hãy nắm bắt cơ hội, dám làm dám mạo hiểm và thử nghiệm điều mới lạ.

Hẳn đây cũng là những điều mà anh đã áp dụng cho công ty của mình?

Chính xác là vậy! Chúng tôi luôn khuyến khích và tạo cơ hội nhân viên của mình cũng như tạo cơ hội và cho họ sự tự tin để dám mạo hiểm và thử thách bản thân. Nhưng tôi cũng nghĩ rằng việc tạo động lực không hề đơn giản cũng như vô cùng quan trọng. Bởi cơ hội xuất hiện thì cần phải có động lực để nắm bắt nó. Đó cũng là phẩm chất mà công ty luôn nhắm tới trong tuyển dụng. Đặc biệt là với những bạn muốn phát triển và đạt tới tầm cao mới.

Nhưng như vậy cũng sẽ gặp nhiều khó khăn khi có nhiều ý tưởng khác nhau được đưa ra. Không biết là anh cũng như công ty đã có giải pháp gì không?

Tất nhiên đây cũng là một vấn đề mà chúng tôi thường xuyên phải đối mặt (cười). Đầu tiên thường là tôi sẽ tập trung vào mục tiêu của những sản phẩm đó đối với khách hàng. Vì vậy, mà miễn là ý tưởng của bạn đáp ứng được những tiêu chí trên thì nó đáng để áp dụng. Ngoài ra, khi có nhiều ý tưởng tốt và nhóm cần phải đưa ra quyết định thì bên tôi sẽ bỏ vào một cái hộp và chọn ngẫu nhiên từ chúng.

Điều quan trọng ở đây là việc mọi người cố gắng bàn luận và trao đổi với nhau để tìm ra giải pháp tốt nhất.

Vậy công ty có những chương trình hay workshop để giúp developer phát triển sự nghiệp của họ không?

Hiện tại chúng tôi vẫn chưa thật sự có workshop đúng nghĩa. Nhưng Outsourceit- Facilitated Work Hub cũng đang có gắng khuyến khích các bạn ấy tự đưa ra quyết định và giải quyết vấn đề cũng như là tìm hiểu về xu hướng công nghệ mới. Bản thân tôi cũng là người thường đưa ra các ý tưởng bởi bản thân khá thích tìm hiểu và trao đổi với mọi người nên khi có gì mới là tôi luôn cố gắng đưa nó vào cuộc bàn luận với nhóm.

 

Tôi tin rằng không có ai là có quyền áp đặt bắt buộc bạn cái gì đúng hay sai. Cũng như việc phải luôn cầm tay chỉ việc cho họ sẽ chỉ khiến các developer không thể phát triển tốt nhất được. Chúng ta cần những người có khả năng tự đưa ra quyết định của riêng tôi.

Anh có thể nêu ra những thách thức mà các developer Việt Nam phải vượt qua khi làm việc trong một công ty có văn hóa nước ngoài?

Tôi nghĩ là việc đầu tiên là phải giải thích và giúp họ hiểu rõ hơn về văn hóa của nhau cũng như môi trường làm việc. Công ty cũng muốn tạo động lực cho họ để làm việc cũng như giao tiếp với nhau.

Quan trọng nhất là kinh nghiệm làm việc nhóm. Với tôi thì nó rất khác biệt so với việc các thành viên chỉ đơn giản làm những task được giao sẵn. Thay vào đó, các thành viên được giao cho những task lớn và họ phải làm việc với nhau để tìm ra giải pháp. Bởi vì ai cũng có điểm mạnh và yếu nên một team tốt thì các thành viên sẽ luôn gắn kết và trợ giúp lẫn nhau trong việc giải quyết vấn đề thay vì chỉ nhận lệnh từ leader một cách máy móc. Bạn sẽ cần một team có sự hợp tác như vậy để giải quyết những vấn đề hóc búa.

Theo anh thì đâu là những ưu điểm của developer Việt Nam khi làm việc với các đồng nghiệp nước ngoài?

Đầu tiên là việc được mở rộng tầm nhìn cũng như hiểu rõ hơn về sự khác biệt trong văn hóa làm việc khi được làm trong một môi trường mới.

Ngoài ra, developer Việt Nam cũng sẽ có cơ hội học và rèn luyện tiếng anh. Theo tôi đó cũng là một ưu thế nổi bật.

Hơn nữa, mặc dù cả hai nước đều có sự khác biệt rất lớn về địa lí nhưng khoảng cách ấy lại trở nên rất nhỏ đối với việc hợp tác với nhau. Như hai mảnh ghép của cùng một bức tranh lớn. Chính sự khác nhau ấy đã tạo ra sự hòa hợp giữa 2 team.

Anh có thể nói rõ thêm về sự khác biệt văn hóa trong công ty của mình so với những nơi khác?

Tôi nghĩ là công ty khá khác biệt so với những môi trường làm việc tại Việt Nam cũng như Mỹ. Sự khác biệt nằm ở việc có rất nhiều tự do. Đi kèm với đó là tinh thần trách nhiệm. Mọi người có thể nói là ngang bằng nhau, không có nhiều khoảng cách giữa sếp và nhân viên. Chỉ có ý tưởng và kĩ năng của bạn là quan trọng. Tuổi tác và cấp bật không quan trọng, đặc biệt là với công ty của tôi. Và hai nhóm làm rất tốt điều này.

Tuy nhiên, tôi nghĩ là các bạn Việt Nam vẫn chưa thật sự quen như vậy khi làm với đồng nghiệp cùng quốc tịch với họ.

Vậy công ty có gặp phải những vấn đề khó khăn gì khi họ mới tham gia vào môi trường là việc mới mẻ này không?

Vấn đề khó nhất nằm ở việc họ phải tự biết để làm gì. Tôi thấy rất nhiều người gặp khó khăn và không biết làm gì vì không được nhận task từ client. Điều này là hoàn toàn bình thường và tại công ty tôi thì mọi người  thường sẽ tự tìm ra những task mới để làm trước khi đạt được mục tiêu. Bởi tôi hiểu rõ sự quan trọng của việc luôn có mục tiêu và không bị lạc hướng.

Một phần khác thì các bạn sẽ cần phải muốn thay đổi cũng như kiên trì trong việc đó. Cái này thì tôi cũng không biết chỉ sao bởi bạn cần phải tự có động lực thì mới thay đổi được.

Vì sao những công ty lớn ở thị trường Nhật hay Na Uy lại thích dùng những công nghệ cũ để xây dựng sản phẩm thay vì những công nghệ mới?

Đây là một câu hỏi khó! Điều cần lưu ý là các công nghệ không kể mới hay cũ đều rất thú vị trong mắt các developer cũng như công ty. Vấn đề nằm ở việc khi bạn phát triển một sản phẩm cho công ty, bạn sẽ muốn nó sống được khoảng 10~20 năm. Tuy vậy, công nghệ mới cũng đồng nghĩa với nguy hiểm cao. Ví dụ như Angular 1, vốn được nhiều người yêu thích và sử dụng vài năm trước. Tuy nhiên, Google nhận ra nó có nhiều hạn chế nên đã làm ra Angular 2. Sự giống nhau giữa chúng chỉ là cái tên, mọi thứ khác đều đã bị thay đổi. Nói cách khác, công nghệ mới đến và đi với tần suất đến chóng mặt cũng như tuổi đời càng ngày ngắn. Do đó mà các công nghệ đã ổn định sẽ càng ngày trở nên quan trọng hơn như Java, .Net, PHP. Chúng đã có tồn tại từ lâu và sẽ tiếp tục như thế. Đó là một giải pháp đầu tư an toàn cho các công ty lớn.

Ngoài ra, các công nghệ mobile như Android cũng như các công nghệ mới như AI, Big Data, IoT sẽ ngày càng trở nên quan trọng hơn. Nhưng cách thức sử dụng chúng chắc cũng sẽ thay đổi nhiều lần trong tương lai trước khi có thể trở nên ổn định hơn.

Do đó mà khả năng thích nghi cũng như học hỏi nhanh sẽ rất quan trọng. Ngoài ra trong quá trình phát triển, chúng ta cũng cần phải có khả năng đưa ra quyết định cũng như biết rõ rằng các cấu trúc sẽ thay đổi chỉ trong vòng 2 năm. Hãy luôn có sự chuẩn bị. Mặt khác đừng quá sa lầy vào quá trình manual testing bởi nó mất rất nhiều thời gian cũng như phức tạp.

Sau tất cả những lời khuyên của anh dành cho developer tại Việt Nam, theo anh thì các bạn cần phải làm gì để có thể có những đột phá trong sự nghiệp của mình?

Theo tôi, đổi mới sáng tạo cũng như sự đột phá nằm nhiều ở tư duy. Như đã nói ở trên, trước nhất, bạn phải “DÁM” (dare) thực hiện những ý tưởng của mình. Nó còn là việc bạn tự tin làm ra được một thứ hoàn toàn mới chưa từng xuất hiện ở bất cứ đâu. Gọi vui là bạn không thể Google Search được nó. Nói một cách khác, ý tưởng của bạn phải lạ và chưa hề có ai nghĩ ra.

Những ý tưởng đó không đến từ việc bạn làm việc nhiều ở công ty A,B,C hay D mà là đến từ việc bạn dám đặt mình ra khỏi vùng an toàn, tìm cho mình những thách thức mới về mindset, về công nghệ hay về tư duy làm sản phẩm. Đó thật sự là một điều mà không phải lập trình viên nào cũng dám thử thách bản thân mình. Chúng ta cần rất nhiều sự tự tin và lòng can đảm để đem đến những đổi mới có sức ảnh hưởng toàn diện.

TopDev

Tìm việc IT lương cao, đãi ngộ tốt trên TopDev ngay!

3 Tip để tìm ra chiến lược giữ chân nhân viên hiệu quả

Ngay cả đối với các leader mảng HR dày dạn, việc giữ chân nhân viên là một trong những việc khó khăn nhất, đặc biệt là tuyển dụng nhân viên ngành công nghệ. Bất cứ khi nào bạn thuê các developer chất lượng, áp lực luôn luôn là giữ họ cảm thấy hạnh phúc. Cuối cùng, cuộc cạnh tranh đang tìm cách để tương tác với các ứng viên ngành công nghệ thụ động và các lập trình viên của bạn cũng không là ngoại lệ.

Đồng thời, đây là một thống kê thể hiện cho nhiều hơn kết quả của câu trả lời “Bao nhiêu nhà phát triển đã rời khỏi công ty bạn trong năm nay?” Nhưng làm thế nào bạn có thể tìm ra một chiến lược giữ chân nhân viên hiệu quả cho các developer ngày hôm nay? Dưới đây là một vài mẹo đáng để xem xét.

Đánh giá việc duy trì như là một phần trong sự cam kết của nhân viên

Khi đánh giá chiến lược duy trì nhân viên, nhiều nhà quản lý bắt đầu bằng cách xác định tỷ lệ doanh thu của công ty. Thông thường, bạn phải tự tính toán điều này bằng cách chia số nhân viên còn lại trong một khoảng thời gian nhất định cho tổng số nhân viên vào cuối thời điểm đó. Nếu tỷ lệ doanh thu của bạn trong bất kỳ quý nào thấp hơn phần còn lại, có lẽ bạn sẽ nghĩ rằng chiến thắng. Nhưng khi bạn tập trung quá nhiều vào con số này, bạn sẽ gặp nguy cơ bị mất đi những thứ lớn hơn.

Amy Hirsch Robinson thuộc Học viện Human Capital cho biết sự cam kết của nhân viên là một thước đo có giá trị hơn nhiều so với thu nhập của nhân viên. Cô nói thêm, “Các tổ chức thu hút sự chú ý như một thước đo chính yếu thường gặp khó khăn với những người có thành tích tầm thường và có tham vọng tối thiểu. Những nhân viên muốn thử thách, hấp dẫn công việc để lại một cách nhanh chóng khi họ nhìn thấy hiệu suất trung bình được khen thưởng. ”

Hãy nói về tỷ lệ doanh thu. Bạn có biết lý do tại sao các developer hoặc là ở lại hay rời khỏi? Để tìm hiểu điều này, hãy hỏi ít nhất ba developer hiện tại của bạn cảm thấy thế nào về công việc của họ. Nếu họ hài lòng với những gì được yêu cầu, hãy coi đó như một dấu hiệu cho thấy team sẽ không chọn cách rời khỏi công ty.

Tạo thêm cơ hội thăng tiến và phát triển

Nói về cơ hội thăng tiến và phát triển, các developer thẳng thắn về tầm quan trọng của họ trong công việc. Trên thực tế, họ đã đứng đầu danh sách các tiêu chuẩn đánh giá việc làm năm 2017. Việc phát triển chuyên môn là yếu tố quan trọng để đánh giá developer nào phù hợp các công việc mới, họ là một phần quan trọng trong chiến lược giữ chân nhân viên hiệu quả.

Viết ra các sáng kiến hiện tại mà bạn có sẵn để giúp các developer phát triển kỹ năng. Nếu bạn không thể xác định được ít nhất ba, hãy gặp các engineering manager để thảo luận và tìm cách. Nếu team gần đây đã tập trung vào một số dự án quan trọng, hãy tạo ra một kế hoạch để team có thêm cơ hội phát triển nghề nghiệp sau khi hoàn thành nhiệm vụ. Quan trọng hơn, truyền đạt ý tưởng của bạn cho team ngay khi bạn hoàn tất chúng. Nếu bạn đã làm việc chăm chỉ để giúp họ xây dựng sự nghiệp, và những nỗ lực của bạn có thể sẽ có ảnh hưởng tích cực đến số lưu giữ chung của bạn.

Tập trung vào việc tuyển chọn người phù hợp

Với flipside, dữ liệu lưu giữ có thể gây hiểu nhầm nếu bạn đang lấp đầy vai trò của developer một cách nhanh chóng. Nếu bạn liên tục thay thế thành viên của nhóm công nghệ cao của mình, đó rõ ràng là điều bạn cần phải giải quyết. Nhưng vấn đề lớn hơn là chiến lược tuyển dụng chứ không phải chiến lược giữ chân nhân viên của công ty.

Một lần nữa, hãy nhìn xa hơn tỷ lệ mà bạn đang mất đi các developer. Bắt đầu bằng cách phân tích mẫu tuyển dụng trong sáu tháng qua, và tự hỏi tại sao bạn phải lấp đầy nhiều vị trí. Có những nhà phát triển trước đây của bạn chuyển sang các cơ hội việc làm khác, hoặc là nó là kết quả của một vài thuê tồi? Nếu đó là lần thứ hai, gặp gỡ với các engineering manager để xác định các phần của quá trình tuyển dụng của bạn mà có làm.

TopDev via Stackoverflowbusiness

  5 tố chất để thành công khi làm nghề tuyển dụng

Xây dựng Vue SPA (Single Page App) với Laravel – Phần 1

Xây dựng Vue SPA (Single Page App) với Laravel - Phần 1

Xây dựng một Vue SPA bằng Laravel là một sự kết hợp tuyệt vời để xây dựng các ứng dụng sử dụng API. Trong bài viết này, tôi sẽ chỉ cho bạn cách bắt đầu và sử dụng Vue router kết hợp back-end là Laravel để xây dựng một SPA. Ta sẽ tập trung vào việc kết nối các thành phần cần thiết.

Các flow quan trọng cần để Vue SPA hoạt động với Laravel như là backend như sau:

  • Đầu tiên là request đều truy cập đến router của Laravel
  • Laravel render bố cục SPA
  • Request tiếp theo là sử dụng history.pushState API để điều hướng URL mà không cần tải lại trang

Vue router có thể được cấu hình để sử dụng history mode hoặc hash-mode mặc định, nó sử dụng URL hash để mô phỏng URL đầy đủ để trang sẽ không tải lại khi URL thay đổi.

Việc sử dụng history mode, có nghĩa là chúng ta cần phải cấu hình route của Laravel sẽ khớp với tất cả các URL mà tùy theo người dùng nhập vào Vue SPA. Ví dụ: nếu người dùng  refresh /hello route, chúng ta sẽ cần phải match route đó và return lại kết quả cho Vue SPA template. Router của Vue sau đó sẽ xác định route và render các component thích hợp.

Tham khảo việc làm Laravel lương cao cho bạn

Cài đặt

Để bắt đầu, chúng ta sẽ tạo một project Laravel mới và sau đó cài đặt Vue router NPM package:

laravel new vue-router
cd vue-router

# Link the project if you use Valet
valet link

# Install NPM dependencies and add vue-router
yarn install
yarn add vue-router # or npm install vue-router

Chúng ta đã cài đặt Laravel và vue-router NPM package. Tiếp theo, chúng ta sẽ cấu hình router và define một vài route và các component.

Cấu hình Vue router

Cách Vue Router hoạt động là nó maps một route đến component và sau đó render trong ứng dụng với tag:

<router-view></router-view>

Đầu tiên, chúng ta sẽ cập nhật các các file JavaScript chính resources/assets/js/app.js và cài đặt cấu hình cho Vue router. Thay thế nội dung của tệp app.js bằng đoạn code sau:

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

import App from './views/App'
import Hello from './views/Hello'
import Home from './views/Home'

const router = new VueRouter({
    mode: 'history',
    routes: [
        {
            path: '/',
            name: 'home',
            component: Home
        },
        {
            path: '/hello',
            name: 'hello',
            component: Hello,
        },
    ],
});

const app = new Vue({
    el: '#app',
    components: { App },
    router,
});

Chúng ta có một vài file cần tạo, nhưng trước tiên chúng ta hãy đề cập đến nội dung của app.js:

  • Import và cài đặt plugin VueRouter với Vue.use()
  • Import 3 Vue Component:

+ App là component nằm ngoài cùng

+ Hello component map với route /hello
+ Home component map với route 

  • Chúng ta xây dựng một VueRouter instance mới để config object
  • Làm cho Vue nhận ra được component App bằng cách đẩy nó vào khu vực components trong cấu trúc của Vue
  • Truyền route constant router vào ứng dụng Vue mới để có thể access đến this.$routerthis.$route

VueRouter lấy một mảng các route, nơi mà chúng ta define path, tên và component mà nó có thể map với đường dẫn.

Để kết hợp Laravel, chúng ta cần xác định ba component:

mkdir resources/assets/js/views
touch resources/assets/js/views/App.vue
touch resources/assets/js/views/Home.vue
touch resources/assets/js/views/Hello.vue

Đầu tiên, file App.vue  là element container ngoài cùng của ứng dụng. Ở trong component này, chúng ta sẽ định nghĩa một nhóm ứng dụng và một số điều hướng sử dụng tag <router-link/> của Vue Router:

<template>
    <div>
        <h1>Vue Router Demo App</h1>

        <p>
            <router-link :to="{ name: 'home' }">Home</router-link> |
            <router-link :to="{ name: 'hello' }">Hello World</router-link>
        </p>

        <div class="container">
            <router-view></router-view>
        </div>
    </div>
</template>
<script>
    export default {}
</script>

Tag quan trọng nhất trong component App là tag <router-view></router-view> , nơi mà router sẽ render thành phần đã cho mà nó phù hợp với route (VD: Home hoặc Hello).

Component tiếp theo chúng ta cần xác định nằm ở resources/assets/js/views/Home.vue:

<template>
  <p>This is the homepage</p>
</template>

Cuối cùng, chúng ta xác định component Hello nằm ở resources/assets/js/views/Hello.vue:

<template>
  <p>Hello World!</p>
</template>

Tôi thích tách các component có thể tái sử dụng và các component ít đụng tới bằng cách sắp xếp tất cả các view vào thư mục resources/assets/js/views và các component cần sử dụng lại nhiều vào resources/assets/js/components

Chúng ta có mọi thứ cần để chạy Vue application. Tiếp theo, chúng ta cần definr route ở backend và server-side template.

Server-Side

Chúng ta có thể tận dụng framework như Laravel với một Vue SPA để chúng ta có thể xây dựng một API để làm việc. Nhưng trong hướng dẫn này, chúng ta sẽ không build 1 API mà là kết nối trên Vue router

Đầu tiên chúng ta sẽ define route. Mở tệp routes/web.php và thay thế welcome route bằng:

<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/{any}', 'SpaController@index')->where('any', '.*');

Chúng ta define bắt tất cả route đến SpaController và điều này có nghĩa là bất kỳ route web sẽ map với SPA. Nếu không làm điều này, và người sử dụng tạo 1 request đến /hello, Laravel sẽ bị lỗi 404.

Tiếp theo, chúng ta cần phải tạo ra SpaController và define view:

php artisan make:controller SpaController

Mở SpaController và nhập như sau:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class SpaController extends Controller
{
    public function index()
    {
        return view('spa');
    }
}

Cuối cùng, nhập các thông tin sau vào resources/views/spa.blade.php:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Vue SPA Demo</title>
</head>
<body>
    <div id="app">
        <app></app>
    </div>

    <script src="{{ mix('js/app.js') }}"></script>
</body>
</html>

Chúng ta đã khai báo required #app element mà nó chứa App component để cho Vue render, cùng với việc hiển thị thành phần thích hợp dựa trên URL.

Chúng tôi đã define các phần tử bắt buộc #app mà chứa App component mà Vue sẽ render cùng với việc hiển thị thành phần thích hợp dựa trên URL.

Chạy ứng dụng

Chúng ta cần build trước khi chạy ứng dụng, gõ lệnh:

yarn watch # or npm run watch

Mở trình duyệt và chạy:

Xây dựng Vue SPA (Single Page App) với Laravel - Phần 1

Tiếp theo

Chúng ta đã có bộ khung cho Vue SPA sử dụng Laravel để làm API. Ứng dụng này vẫn còn nhiều điều thú vị ta sẽ được tìm hiểu trong bài viết tiếp theo:

  • Bắt tất cả điều hướng 404 trên frontend
  • Sử dụng các route parameters
  • Child route
  • Thực hiện một API request từ một component đến Laravel
  • Và còn nhiều điều thú vị khác

Phần 2: Xây dựng Vue SPA (Single Page App) với Laravel

Nguồn: laravel-news

Laravel 5.6 đã lên sóng, và đây là những điểm mới nổi bật nhất!

Laravel 5.6 đã chính thức ra mắt phiên bản mới nhất! Phiên bản này có rất nhiều feature mới, và dưới đây chúng tôi đã đưa ra những feature nổi bật hơn hẳn các bản trước. Để xem được danh sách đầy đủ tất cả các thay đổi, hãy truy cập vào changelog (GitHub).

Những cải thiện về logging

Tính năng nổi bật nhất trong Laravel 5.6 đó là những cải thiện về logging. Với những người mới,cấu hình logging v5.6 chuyển từ file config/app.php sang file mới config/logging.php.

Bạn sẽ thiết lập “stacks” để gửi message log đến nhiều công cụ quản lý và theo dõi. Ví dụ, bạn có thể gửi đi tất cả các message debug đến log hệ thống và gửi các log lỗi đến slack.

Bạn có thể đọc thêm thiết lập và tùy chỉnh log bằng cách truy cập vào tư liệu logging.

Single Server Task Scheduling

Nếu bạn có một task scheduler chạy trên nhiều server, task sẽ chạy riêng rẽ trên mỗi server. Bạn có thể cấu hình task chỉ nên chạy trên một server bằng method onOneServer() , về phần này chưa được dùng nhiều nên anh em nào đã có kinh nghiệm xin vui lòng chỉ giáo thêm ở comment:

$schedule->command('report:generate')
    ->fridays()
    ->at('17:00')
    ->onOneServer();

Lưu ý: bạn phải sử dụng cache driver memcached hoặc redis như một cache driver mặc định để tận dụng lợi thế của task mỗi single server task scheduling trong phiên bản Laravel 5.6.

Dynamic Rate Limiting

Laravel 5.6 công bố dynamic rate limiting giúp bạn linh hoạt hơn và dễ dàng giới hạn những chức năng cơ bản của một user:

Route::middleware('auth:api', 'throttle:rate_limit,1')
    ->group(function () {
        Route::get('/user', function () {
            //
        });
    });

Trong ví dụ trên, rate_limit là một thuộc tính của model App\User để xác định số lượng request được cho phép trong một khoảng giới hạn thời gian.

Broadcast Channel Classes

Giờ đây bạn có thể sử dụng các class channel trên file routes/channels.php của mình thay vì sử dụng closure.

Để tạo nên một class channel mới, Laravel 5.6 cung cấp một lệnh make:channel mới:

php artisan make:channel OrderChannel

Bạn có thể khai báo channel trên file routes/channels.php như sau:

use App\Broadcasting\OrderChannel;

Broadcast::channel('order.{order}', OrderChannel::class);

API Controller

Giờ đây bạn có thể tạo ra một resource controller cho các API mà không bao gồm những thao tác create và edit không cần thiết, những cái mà chỉ apply vào các resource controller trả về HTML. Để tạo ra một resource controller, sử dụng flag --api:

php artisan make:controller API/PhotoController --api

Eloquent Date

Bạn có thể chủ động tự tùy chỉnh format của ngày và ngày giờ Eloquent:

protected $casts = [
    'birthday' => 'date:Y-m-d',
    'joined_at' => 'datetime:Y-m-d H:00',
];

Format này được dùng trên phần chuyển đổi model thành một array hoặc JSON data.

Blade Component Aliases

Giờ đây bạn có thể đặt bí danh cho các blade components giúp việc truy cập tiện lợi hơn. Ví dụ, nếu bạn lưu component vào resources/views/components/alert.blade.php bạn có thể sử dụng method component() để đặt một tên ngắn hơn:

Blade::component('components.alert', 'alert');

Sau đó bạn có thể render nó bằng tên được đặt:

@component('alert')
    <p>This is an alert component</p>
@endcomponent

Argon2 Password Hashing

Laravel 5.6 hỗ trợ thuật toán mã hóa mật khẩu cho PHP 7.2+ (chỉ có ver php này hỗ trợ thuật toán trên). Bạn có thể kiểm soát mã hóa driver nào được sử dụng mặc định trong file config/hashing.php mới.

Bạn có thể đọc thêm về hỗ trợ thuật toán Argon2i hashing của Laravel 5.6 trong bài báo của chúng tôi.

Các method UUID 

Hai method mới đã có mặt trên class Illuminate\Support\Str để tạo ra Universal Unique Identifiers (UUID):

// The methods return a Ramsey\Uuid\Uuid object

return (string) Str::uuid();

return (string) Str::orderedUuid();

Method orderedUuid() sẽ tạo timestamp cho UUID đầu tiên giúp cho việc database indexing dễ dàng hơn và hiệu quả hơn.

Collision

Chúng tôi mới viết về Collision coming to Laravel 5.6 là một dev dependency, cung cấp  báo cáo lỗi trực quan trong bảng điều khiển:

Collision Package in Laravel 5.6

Bootstrap 4

Tất cả các frontend scaffolding và example Vue component giờ đây đều sử dụng Bootstrap 4. Chúng ta đã dùng Bootstrap 4 trong bản beta, và thậm chí còn tạo một Bootstrap 4 Laravel preset. Thật tốt khi thấy Bootstrap 4 ổn định đi kèm với Laravel 5.6!

Tìm hiểu thêm về Laravel 5.6

Để nâng cấp Laravel lên v5.6, bạn có thể tham khảo hướng dẫn nâng cấp. Việc nâng cấp từ 5.5 lên 5.6 ước tính tốn khoảng từ 10 đến 30 phút. Hiện tại các việc làm IT lương cao liên quan đến Laravel cũng được các doanh nghiệp tuyển dụng rất nhiều.

Tham khảo thêm các vị trí ứng tuyển lập trình Laravel lương cao tại đây

TopDev via Laravel News

  Tính năng Frontend Presets của Laravel 5.5
  Laravel, bạn đã viết đúng?

Laravel 5.6 thêm Collision Package cho CLI Error Report

Được cung cấp bời Nuno Maduro, Collision là 1 gói thiết kế cho phép bạn xem một báo cáo error đẹp mắt và trực quan khi bạn check log thông qua command line. Gói này hiện tại chỉ được hỗ trợ trên bản Laravel 5.6, Collision sẽ cho phép cài đặt trước dưới dạng là dev composer dependency.

Như bạn thấy, xem error log trực quan vậy thì dễ tìm ra lỗi, đỡ nhức mắt và giúp anh em dev nhanh chóng fix bug.

  Hướng dẫn Laravel Model Caching

Tham khảo thêm các việc làm cho it laravel

Hướng dẫn Laravel Model Caching

Có thể trước đây bạn đã từng cache một số data model trên controller, nhưng giờ tôi sẽ chỉ cho bạn một kỹ thuật cache Laravel model sử dụng model Active Record phức tạp hơn một chút. Đây là kỹ thuật tôi học được từ RailsCasts.

Bằng việc sử dụng cache key riêng biệt lên model, bạn có thể cache các properties và associations tự động update lên model của mình (và cache hết hiệu lực) khi model (hoặc model liên quan) được update. Một lợi ích khác đó là việc truy cập vào data được cache trên model tiện lợi hơn việc cache data trên controller.

Dưới đây là phần lý giải của kỹ thuật này:

Xem như bạn có một model Article mà có chứa nhiều model Comment. Khi được cho template Laravel blade như dưới đây, bạn có thể nhận về số comment như thế trên route /article/:id:

<h3>$article->comments->count() {{ str_plural('Comment', $article->comments->count())</h3>

Bạn có thể cache phần comment count trong controller, nhưng controller có thể trở nên khá tệ khi bạn có nhiều query và data cần phải cache. Việc sử dụng controller, truy cập vào data được cache cũng không được thuận tiện cho lắm.

Chúng ta có thể xây dựng một template mà chỉ thực hiện việc truy cập database khi article được update, và bất kì code nào có access vào model đều có thể lấy giá trị được cache:

<h3>$article->cached_comments_count {{ str_plural('Comment', $article->cached_comments_count)</h3>

Chúng ta sẽ cache lượng comment count dựa theo lần cuối mà article được update.

Vậy bằng cách nào mà chúng ta update cột updated_at của article khi một comment mới được thêm vào hoặc xóa đi?

Sử dụng phương thức touch.

>>> Xem thêm: Laravel, bạn đã viết đúng?

Touching Models

Việc sử dụng method touch() của model, chúng ta có thể update cột updated_at của article:

$ php artisan tinker

>>> $article = \App\Article::first();
=> App\Article {#746
     id: 1,
     title: "Hello World",
     body: "The Body",
     created_at: "2018-01-11 05:16:51",
     updated_at: "2018-01-11 05:51:07",
   }
>>> $article->updated_at->timestamp
=> 1515649867
>>> $article->touch();
=> true
>>> $article->updated_at->timestamp
=> 1515650910

Chúng ta có thể sử dụng timestamp đã update để invalidate cache, nhưng làm sao để đụng tới trường updated_at của article khi chúng ta thêm hoặc bỏ đi comment?

Việc này cũng xảy ra tương tự khi model Eloquent có một thành phần gọi là $touches. Comment model của chúng tôi được diễn giải như sau:

<?php

namespace App;

use App\Article;
use Illuminate\Database\Eloquent\Model;

class Comment extends Model
{
    protected $guarded = [];

    protected $touches = ['article'];

    public function article()
    {
        return $this->belongsTo(Article::class);
    }
}

$touches là một mảng chứa một liên kết sẽ được “touch” khi một comment được tạo ra, lưu về hoặc xóa đi.

Thuộc tính Cached (cached attribute)

Quay lại phần $article->cached_comments_count. Phần thực hiện có thể trông như thế này trên model App\Article:

public function getCachedCommentsCountAttribute()
{
    return Cache::remember($this->cacheKey() . ':comments_count', 15, function () {
        return $this->comments->count();
    });
}

Chúng ta đang cache model trong khoảng 15 phút bằng method cacheKey() riêng biệt và quay lại phần đếm comment trong phần closure.

Lưu ý rằng chúng ta có thể sử dụng method  Cache::rememberForever() và dựa vào thùng rác tạm trên bộ nhớ đệm để loại bỏ key cũ. Tôi đã cài đếm giờ để cache sẽ được truy cập mọi lúc, với một cache mới mỗi 15 phút.

method cacheKey() cần phải làm trên model riêng biệt, và vô hiệu cache khi model được update. Dưới đây là phần ứng dụng cacheKey của tôi:

public function cacheKey()
{
    return sprintf(
        "%s/%s-%s",
        $this->getTable(),
        $this->getKey(),
        $this->updated_at->timestamp
    );
}

Một ouput mẫu của method cacheKey() có thể cho ra kết quả như sau:

articles/1-1515650910

Mấu chốt là tên bảng, model id, và updated_at. Một khi đụng tới model, timestamp sẽ được update, và cache model sẽ được vô hiệu hóa ngay.

Dưới đây là model Article đầy đủ:

<?php

namespace App;

use App\Comment;
use Illuminate\Support\Facades\Cache;
use Illuminate\Database\Eloquent\Model;

class Article extends Model
{
    public function cacheKey()
    {
        return sprintf(
            "%s/%s-%s",
            $this->getTable(),
            $this->getKey(),
            $this->updated_at->timestamp
        );
    }

    public function comments()
    {
        return $this->hasMany(Comment::class);
    }

    public function getCachedCommentsCountAttribute()
    {
        return Cache::remember($this->cacheKey() . ':comments_count', 15, function () {
            return $this->comments->count();
        });
    }
}

Và model Comment liên quan:

<?php

namespace App;

use App\Article;
use Illuminate\Database\Eloquent\Model;

class Comment extends Model
{
    protected $guarded = [];

    protected $touches = ['article'];

    public function article()
    {
        return $this->belongsTo(Article::class);
    }
}

Tiếp đến là gì?

Tôi đã chỉ ra cách cache một hàm đếm comment đơn giản, nhưng làm thế nào để cache tất cả comment?

public function getCachedCommentsAttribute()
{
    return Cache::remember($this->cacheKey() . ':comments', 15, function () {
        return $this->comments;
    });
}

Bạn cũng có thể chọn chuyển đổi comment thành array:

public function getCachedCommentsAttribute()
{
    return Cache::remember($this->cacheKey() . ':comments', 15, function () {
        return $this->comments->toArray();
    });
}

Cuối cùng, tôi define method cacheKey() vào Article model, nhưng bạn nên define method này qua ProvidesModelCacheKey để có thể dùng trên nhiều model hoặc define method trên model gốc mà tất cả các model khác kế thừa. Thậm chí bạn còn muốn dùng contract (interface) cho các model để áp dụng method cacheKey().

Tham khảo thêm các vị trí tuyển dụng lập trình Laravel lương cao cho bạn.

TopDev via Laravel News

10 PHP Instagram Scripts & Widgets tốt nhất

Dù bạn có dùng Instagram cho công việc hay giải trí thì nó vẫn là một công cụ tuyệt vời để kết nối bạn bè, khách hàng và cả người hâm mộ. Tuy vậy, quá trình tạo ra một tài khoảng với hàng trăm kết nối trở lên có thể sẽ rất tốn thời gian. Vì vậy mà bất kì tool nào có thể rút ngắn thời gian cũng đều trở nên vô cùng giá trị trong mắt người dùng.

Hôm nay, tôi sẽ liệt kê ra 10 PHP Instagram scripts và widgets tốt nhất trên CodeCanyon, với những tính năng như tự động hóa function, giúp download hình ảnh và nhiều task khác nữa.

Nextpost Instagram

Automation tools sẽ là những trợ thủ vô cùng đắc lực giúp tiết kiệm rất nhiều thời gian cho người dùng. Trong đó, phải kể đến Nextpost Instagram.

Trước hết, nó cho phép bạn quản lí một hoặc nhiều tài khoản khác nhau trong cùng một trang. Hơn nữa, Nextpost Instagram còn có thể xếp lịch đăng bài vô cùng tiện lợi. Phần mềm rất dễ cài đặt với thiết kế tập trung cho người dùng mobile.

VTGram

VTGram cũng là một tool cực kì tuyệt vời khác với nhiều tính năng hơn Nextpost. Với VTGram, người dùng có thể tự động đăng và chia sẻ photos, videos, status cũng như là câu truyện của mình lên tài khoản Instagram nhờ vào tính năng xếp lịch. Bạn cũng có thể dùng hashtags, vị trí và cả tên người dùng để tìm những bài mà bạn thích cũng như auto-like hoặc auto bình luận chỉ với một nút click.

Đồng thời, VTGram cũng cho phép bạn tự động follow các người dùng dựa trên hashtag mà họ dùng, vị trí họ ở hoặc đơn giản là tên người dùng. Mặt khác, việc tự động follow lại những ai follow cũng là một tính năng nổi bật trong VTGram. Càng đơn giản hơn khi phần mềm cho phép người dùng lọc và set-up một hệ thống tự động với những tiêu chí riêng biệt.

Ứng tuyển ngay các vị trí PHP tuyển dụng mới nhất trên TopDev

Gram Post

Tương tự như hai tool ở trên, Gram Post cho phép người dùng quản lí một hoặc nhiều tài khoản Instagram và tự động đăng photos, videos và status lên nhiều profiles khác nhau. Đồng thời, nó cũng sẽ báo cáo liệu các bài đã được đăng thành công hay không.

Warbler

Nếu bạn có xài cả Facebook, Twitter và Instagram thì việc nhầm lẫn sẽ xảy ra như cơm bữa cũng như rất tốn thời gian chỉnh qua lại. Do đó, Warbler có thể là automation tool phù hợp nhất cho bạn với khả năng quản lí các tài khoản mạng xã hội.

Instagram Downloader Script

Dù bạn đã có được quyền chia sẻ thì việc tải hình ảnh từ Instagram vẫn không hề đơn giản tí nào. Thật may mắn là mọi chuyện đã thay đổi với sự hiện diện của Instagram Downloader Script.

Chỉ với một click, script đơn giản này sẽ cho phép bạn tải về các photos và videos về hard drive để sử dụng cho nhiều mục đích khác nhau.

Instagram Multiple Photo and Video Downloader

Nếu bạn cần phải tải về nhiều photos hay videos từ Instagram cùng một lúc, thì Instagram Multiple Photo and Video Downloader là một tool vô cùng hữu dụng khi cho thực hiện những điều ấy với một chỉ thao tác bấm nút.

Chỉ việc dán Instagram post links vào downloader, và bấm nút tải về. Phần mềm sẽ tự động thêm các hình vào trong một ZIP file. Đây là một cách rất tốt để back up cho tất cả các hình và video trên tài khoảng Instagram của bạn.

Instagram Video/Image Downloader with Ajax

Instagram Video/Image Downloader with Ajax cũng là một tool khác hỗ trợ việc tải một hoặc nhiều hình ảnh và video từ một bài đăng Instagram thông qua URLs của nó.

Phần mềm này sử dụng Bootstrap Framework và có tài liệu hướng dẫn khá chi tiết.

Instapostcards

Mọi thứ trên Instagram đều về hình ảnh và còn có cách nào tốt hơn để chia sẻ chúng cho bạn bè cũng như thế giới bằng cách biến chúng thành thẻ email postcards.

Instapostcards cho phép bạn làm chính xác những điều đó. Phần mềm cũng không cần nào API bên ngoài để kết nối tới Instagram mà sử dụng Minibots PHP class, vốn đã được tích hợp sẵn trong gói.

Instagram Connect và API Integration

Đa phần mọi người sử dụng đề sử dụng một Facebook hoặc Google+ để đăng nhập vào nhiều tài khoản khác nhau, nhưng giờ đây với Instagram Connect and API Integration script, người dùng có thể sử dụng tài khoản Instagram của họ để đăng nhập vào website của bạn.

BioLink

Instagram chỉ cho phép một link từ tài khoản của người dùng, điều nay có thể khiến bạn vô cùng khó chịu bởi không thể chia sẻ nhiều nội dung trên các website khác nhau.

BioLink cung cấp giải pháp cho vấn đề này. Người dùng sẽ phải đăng kí và tạo một tài khoản trên BioLink’s website, nơi mà họ có thể thêm bao nhiêu link của website liên quan cũng được. Sau đó, người dùng sẽ lấy profile URL từ Biolink tới Instagram bio. Nhờ đó bảo đảm được rằng khi có người bấm vào link, họ sẽ dẫn đến trang web chứa nhiều đường dẫn khác nhau mà bạn muốn.

Lời kết

10 PHP Instagram scripts và widgets tốt nhất này chỉ mới là bề nổi của Envato Market, do đó nếu bạn chưa vừa ý thì có thể kiếm thêm tại đây.

Techtalk via tutplus

Xem ngay những tin đăng tuyển dụng IT mới nhất trên TopDev

Laravel 5.5 và Reactjs: Xây dựng CRUD (Create, Read, Update, Delete) từ đầu

Laravel 5.5 và Reactjs: Xây dựng CRUD (Create, Read, Update, Delete) từ đầu

Trước khi vào bài này bạn cần biết về tính năng Front end preset của Laravel. Laravel 5.5 đem đến một preset mới là Reactjs, bài hướng dẫn này sẽ giúp anh em tiết kiệm thời gian.

1.Cài đặt Laravel 5.5 và cấu hình DB

Chạy lệnh:

composer create-project --prefer-dist laravel/laravel LaravelReactJSTuts

Sau khi cài đặt xong, chúng ta cần cài đặt Javascript dependencies cho project. Chạy lệnh:

npm install

Bây giờ mình tạo 1 database trong phpMyAdmin hay MySQL work bench (Mac thì cài Sequel pro mà quản lý DB).

Cấu hình thông số DB trong file .env:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=LaravelReactjstuts
DB_USERNAME=root
DB_PASSWORD=mysql

Bước tiếp theo chúng ta cd vào root folder bằng terminal rồi chạy lệnh migrate

php artisan migrate

Lệnh này tạo 2 bảng mặc định là users và password_resets. Xong phần cài Laravel, tiếp đến cài React nhé.

  Laravel, bạn đã viết đúng?

2.React Preset

Bạn có thể sử dụng lệnh preset với tùy chọn là react:

php artisan preset react

Lệnh này sẽ tạo cho bạn một khung sườn cơ bản (scaffold). Bạn có thể compile assets bằng cách sử dụng command

npm install && npm run dev

Tiếp theo chúng ta vào LaravelReactJSTuts  >> resources  >>  assets  >>   js , tại đó có 1 folder và 2 file js. Folder có tên là components, đây là react component với 2 file là app.js và boostrap.js

Đi đến resources  >>  views  >>  welcome.blade.php và xóa code đang có trong file, sau đó chèn đoạn code bên dưới:

<!doctype html>
<html lang="{{ app()->getLocale() }}">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Laravel</title>
        <link href="{{asset('css/app.css')}}" rel="stylesheet" type="text/css">
    </head>
    <body>
        <div id="example"></div>
        <script src="{{asset('js/app.js')}}" ></script>
    </body>
</html>

Mở terminal và chạy lệnh:

npm run dev

Lệnh này nó sẽ compile tất cả assets và để bundled js vào trong public >> js  >>  app.js

Để run project chúng ta chạy lệnh

php artisan serve

Visit http://localhost:8000

Laravel 5.5 và Reactjs: Xây dựng CRUD (Create, Read, Update, Delete) từ đầu

3.Chúng ta cần cài đặt vài dependencies liên quan đến reactjs

Đầu tiên chúng ta cần cài gói react-router cho phần điều hướng.

npm install react-router@2.8.1

Theo kinh nghiệm thì mình cài version cũ hơn 1 xíu để ổn định. Mở terminal và chạy lệnh:

npm run watch

Nó sẽ xem những thay đổi trong thư mục assets và và tự động compile lại. Bây giờ mình sẽ chỉnh sửa lại cái ReactJS scaffold theo ý mình bằng cách paste đoạn code bên dưới vào App.js:

// app.js

require('./bootstrap');
import React from 'react';
import { render } from 'react-dom';
import { Router, Route, browserHistory } from 'react-router';

import Example from './components/Example';

render(<Example />, document.getElementById('example'));

Thay đổi tiếp theo là modify Example.js component:

// Example.js

import React, { Component } from 'react';

export default class Example extends Component {
    render() {
        return (
            <div className="container">
                <div className="row">
                    <div className="col-md-8 col-md-offset-2">
                        <div className="panel panel-default">
                            <div className="panel-heading">Example Component</div>

                            <div className="panel-body">
                                I am an example component!
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        );
    }
}

Sau khi save, Laravel Mix sẽ compile lại tất cả các assets và build 1 bundled app.js file. Mở trình duyệt và refresh lại page thì bạn sẽ không thấy sự thay đổi gì cả, nhưng bên trong nó vẫn chạy theo flow quy định của chúng ta.

Bây giờ chúng ta cần tạo một component khác gọi là Master.js bên trong components folder.

/ Master.js

import React, {Component} from 'react';
import { Router, Route, Link } from 'react-router';

class Master extends Component {
  render(){
    return (
      <div className="container">
        <nav className="navbar navbar-default">
          <div className="container-fluid">
            <div className="navbar-header">
              <a className="navbar-brand" href="#">AppDividend</a>
            </div>
            <ul className="nav navbar-nav">
              <li className="active"><a href="#">Home</a></li>
              <li><a href="#">Page 1</a></li>
              <li><a href="#">Page 2</a></li>
              <li><a href="#">Page 3</a></li>
            </ul>
          </div>
      </nav>
          <div>
              {this.props.children}
          </div>
      </div>
    )
  }
}
export default Master;

Tiếp tục lại modify app.js một lần nữa và để component này như là root component.

// app.js

require('./bootstrap');
import React from 'react';
import { render } from 'react-dom';
import { Router, Route, browserHistory } from 'react-router';

import Master from './components/Master';

render(<Master />, document.getElementById('example'));

4.Cấu hình ReactJS routes

Tạo thêm 3 components trong component folder bao gồm:

  1. CreateItem.js
  2. DisplayItem.js
  3. EditItem.js

Rồi ta tạo form trong CreateItem.js để save item data

// CreateItem.js

import React, {Component} from 'react';

class CreateItem extends Component {
    render() {
      return (
      <div>
        <h1>Create An Item</h1>
        <form>
          <div className="row">
            <div className="col-md-6">
              <div className="form-group">
                <label>Item Name:</label>
                <input type="text" className="form-control" />
              </div>
            </div>
            </div>
            <div className="row">
              <div className="col-md-6">
                <div className="form-group">
                  <label>Item Price:</label>
                  <input type="text" className="form-control col-md-6" />
                </div>
              </div>
            </div><br />
            <div className="form-group">
              <button className="btn btn-primary">Add Item</button>
            </div>
        </form>
  </div>
      )
    }
}
export default CreateItem;

Chúng ta cần cấu hình route trong app.js

// app.js

require('./bootstrap');
import React from 'react';
import { render } from 'react-dom';
import { Router, Route, browserHistory } from 'react-router';

import Master from './components/Master';
import CreateItem from './components/CreateItem';

render(
  <Router history={browserHistory}>
      <Route path="/" component={Master} >
        <Route path="/add-item" component={CreateItem} />
      </Route>
    </Router>,
        document.getElementById('example'));

Nếu mọi thứ ổn thì thằng Laravel Mix sẽ recompile và chạy lệnh php artisan serve, mở trình duyệt chạy URL http://localhost:8000/

Thử nhấp vào Create Item xem sao:

Laravel 5.5 và Reactjs: Xây dựng CRUD (Create, Read, Update, Delete) từ đầu

5.Sử dụng axios để làm AJAX Post request

Thêm một số event để lấy input data từ form và gửi đến server bằng AJAX post request.

// CreateItem.js

import React, {Component} from 'react';

class CreateItem extends Component {
  constructor(props){
    super(props);
    this.state = {productName: '', productPrice: ''};

    this.handleChange1 = this.handleChange1.bind(this);
    this.handleChange2 = this.handleChange2.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }
  handleChange1(e){
    this.setState({
      productName: e.target.value
    })
  }
  handleChange2(e){
    this.setState({
      productPrice: e.target.value
    })
  }
  handleSubmit(e){
    e.preventDefault();
    const products = {
      name: this.state.productName,
      price: this.state.productPrice
    }
    let uri = 'http://localhost:8000/items';
    axios.post(uri, products).then((response) => {
      // browserHistory.push('/display-item');
    });
  }

    render() {
      return (
      <div>
        <h1>Create An Item</h1>
        <form onSubmit={this.handleSubmit}>
          <div className="row">
            <div className="col-md-6">
              <div className="form-group">
                <label>Item Name:</label>
                <input type="text" className="form-control" onChange={this.handleChange1}/>
              </div>
            </div>
            </div>
            <div className="row">
              <div className="col-md-6">
                <div className="form-group">
                  <label>Item Price:</label>
                  <input type="text" className="form-control col-md-6" onChange={this.handleChange2}/>
                </div>
              </div>
            </div><br />
            <div className="form-group">
              <button className="btn btn-primary">Add Item</button>
            </div>
        </form>
  </div>
      )
    }
}
export default CreateItem;

6.Backend dùng Laravel (tất nhiên)

Chúng ta sẽ quản lý các hoạt động CRUD (Create, Read, Update, Delete) của item data. Trước mắt cần tạo controller và routes. Chạy lệnh:

php artisan make:model Item -m

Nó tạo ra 2 file là Model và Migration. Mở file migration trong database  >>  migrations  >>  create_items_table và paste đoạn code này

<?php

// create_items_table

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateItemsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('items', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->integer('price');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('items');
    }
}

Rồi chạy lệnh

php artisan migrate

Lệnh này tạo bảng items trong DB. Ngoài ra, 1 file model được tạo trong folder app tên là Item.php

Cần phải tạo một controller là ItemController

php artisan make:controller ItemController --resource

ItemController chứa đựng tất cả các hàm về quản lý CRUD. Mình thử thêm code vào xem sao:

<?php

// ItemController.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Item;

class ItemController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $items = Item::all();
        return response()->json($items);
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $item = new Item([
          'name' => $request->get('name'),
          'price' => $request->get('price')
        ]);
        $item->save();
        return response()->json('Successfully added');
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        $item = Item::find($id);
        return response()->json($item);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        $item = Item::find($id);
        $item->name = $request->get('name');
        $item->price = $request->get('price');
        $item->save();

        return response()->json('Successfully Updated');
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
      $item = Item::find($id);
      $item->delete();

      return response()->json('Successfully Deleted');
    }
}

Chúng ta cũng cần tạo 1 protected field $fillable trong Item.php nếu không thì nó sẽ báo ‘mass assignment exception

<?php

// Item.php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Item extends Model
{
    protected $fillable = ['name', 'price'];
}

Update file routes >> web.php

<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});
Route::resource('items', 'ItemController');

Nếu bạn insert giá trị vào DB, sẽ có thể bạn gặp vấn đề này:

Laravel 5.5 và Reactjs: Xây dựng CRUD (Create, Read, Update, Delete) từ đầu

Error này là do vấn đề bảo mật CORS. Giải pháp là ta cần allow origin cho Laravel server side. Tạo 1 middleware tại backend và dùng nó cho tất cả các API request.

Tải package CORS dưới đây

composer require barryvdh/laravel-cors

Add Cors\ServiceProvider cho config/app.php

Barryvdh\Cors\ServiceProvider::class,

Để allow CORS cho tất cả route, add HandleCors trong        $middleware của app/Http/Kernel.php

protected $middleware = [
    // ...
    \Barryvdh\Cors\HandleCors::class,
];

Rồi chạy lệnh:

php artisan vendor:publish --provider="Barryvdh\Cors\ServiceProvider"

Xong, bây giờ bạn thử save data vào DB thử xem.

7.Hiển thị data ra ReactJS Frontend

Mở DiplayItem.js component trong folder components, nếu chưa tạo thì bạn tạo đi nhé

// DisplayItem.js

import React, {Component} from 'react';
import axios from 'axios';
import { Link } from 'react-router';
import TableRow from './TableRow';

class DisplayItem extends Component {
  constructor(props) {
       super(props);
       this.state = {value: '', items: ''};
     }
     componentDidMount(){
       axios.get('http://localhost:8000/items')
       .then(response => {
         this.setState({ items: response.data });
       })
       .catch(function (error) {
         console.log(error);
       })
     }
     tabRow(){
       if(this.state.items instanceof Array){
         return this.state.items.map(function(object, i){
             return <TableRow obj={object} key={i} />;
         })
       }
     }

  render(){
    return (
      <div>
        <h1>Items</h1>

        <div className="row">
          <div className="col-md-10"></div>
          <div className="col-md-2">
            <Link to="/add-item">Create Item</Link>
          </div>
        </div><br />

        <table className="table table-hover">
            <thead>
            <tr>
                <td>ID</td>
                <td>Item Name</td>
                <td>Item Price</td>
                <td>Actions</td>
            </tr>
            </thead>
            <tbody>
              {this.tabRow()}
            </tbody>
        </table>
    </div>
    )
  }
}
export default DisplayItem;

Tạo thêm TableRow.js component.

// TableRow.js

import React, { Component } from 'react';

class TableRow extends Component {
  render() {
    return (
        <tr>
          <td>
            {this.props.obj.id}
          </td>
          <td>
            {this.props.obj.name}
          </td>
          <td>
            {this.props.obj.price}
          </td>
          <td>
            <button className="btn btn-primary">Edit</button>
          </td>
          <td>
            <button className="btn btn-danger">Delete</button>
          </td>
        </tr>
    );
  }
}

export default TableRow;

Register route này nhé

// app.js

import DisplayItem from './components/DisplayItem';

render(
  <Router history={browserHistory}>
      <Route path="/" component={Master} >
        <Route path="/add-item" component={CreateItem} />
        <Route path="/display-item" component={DisplayItem} />
      </Route>
    </Router>,
        document.getElementById('example'));

Chúng ta cần thay đổi 1 thứ nữa là cần phải redirect đến component này sau khi save data. Vì vậy trong tập tin CreateItem.js, sửa code như sau:

// CreateItem.js

import {browserHistory} from 'react-router';

axios.post(uri, products).then((response) => {
      browserHistory.push('/display-item');
    });

8. Edit và update data

Mở EditItem.js :

// EditItem.js

import React, {Component} from 'react';
import axios from 'axios';
import { Link } from 'react-router';

class EditItem extends Component {
  constructor(props) {
      super(props);
      this.state = {name: '', price: ''};
      this.handleChange1 = this.handleChange1.bind(this);
      this.handleChange2 = this.handleChange2.bind(this);
      this.handleSubmit = this.handleSubmit.bind(this);
  }

  componentDidMount(){
    axios.get('http://localhost:8000/items/${this.props.params.id}/edit')
    .then(response => {
      this.setState({ name: response.data.name, price: response.data.price });
    })
    .catch(function (error) {
      console.log(error);
    })
  }
  handleChange1(e){
    this.setState({
      name: e.target.value
    })
  }
  handleChange2(e){
    this.setState({
      price: e.target.value
    })
  }

  handleSubmit(event) {
    event.preventDefault();
    const products = {
      name: this.state.name,
      price: this.state.price
    }
    let uri = 'http://localhost:8000/items/'+this.props.params.id;
    axios.patch(uri, products).then((response) => {
          this.props.history.push('/display-item');
    });
  }
  render(){
    return (
      <div>
        <h1>Update Item</h1>
        <div className="row">
          <div className="col-md-10"></div>
          <div className="col-md-2">
            <Link to="/display-item" className="btn btn-success">Return to Items</Link>
          </div>
        </div>
        <form onSubmit={this.handleSubmit}>
            <div className="form-group">
                <label>Item Name</label>
                <input type="text"
                  className="form-control"
                  value={this.state.name}
                  onChange={this.handleChange1} />
            </div>

            <div className="form-group">
                <label name="product_price">Item Price</label>
                <input type="text" className="form-control"
                  value={this.state.price}
                  onChange={this.handleChange2} />
            </div>

            <div className="form-group">
                <button className="btn btn-primary">Update</button>
            </div>
        </form>
    </div>
    )
  }
}
export default EditItem;

và register route trong app.js:

// app.js

import EditItem from './components/EditItem';

render(
  <Router history={browserHistory}>
      <Route path="/" component={Master} >
        <Route path="/add-item" component={CreateItem} />
        <Route path="/display-item" component={DisplayItem} />
        <Route path="/edit/:id" component={EditItem} />
      </Route>
    </Router>,
        document.getElementById('example'));

Update thêm cho TableRow.js

<Link to={"edit/"+this.props.obj.id} className="btn btn-primary">Edit</Link>

9. Xóa data

Để xóa data, chúng ta cần define hàm delete trong TableRow.js

// TableRow.js

import React, { Component } from 'react';
import { Link, browserHistory } from 'react-router';

class TableRow extends Component {
  constructor(props) {
      super(props);
      this.handleSubmit = this.handleSubmit.bind(this);
  }
  handleSubmit(event) {
    event.preventDefault();
    let uri = 'http://localhost:8000/items/${this.props.obj.id}';
    axios.delete(uri);
      browserHistory.push('/display-item');
  }
  render() {
    return (
        <tr>
          <td>
            {this.props.obj.id}
          </td>
          <td>
            {this.props.obj.name}
          </td>
          <td>
            {this.props.obj.price}
          </td>
          <td>
            <Link to={"edit/"+this.props.obj.id} className="btn btn-primary">Edit</Link>
          </td>
          <td>
          <form onSubmit={this.handleSubmit}>
           <input type="submit" value="Delete" className="btn btn-danger"/>
         </form>
          </td>
        </tr>
    );
  }
}

export default TableRow;

Chúc mọi người làm thành công nhé.

Tham khảo thêm tìm việc làm ReactJS , việc làm Laravel hấp dẫn lương cao tại Topdev

  Sử dụng Laravel Mix với Webpack cho tất cả các assets

Tính năng Frontend Presets của Laravel 5.5

front end presets

Sau đây, Topdev xin giới thiệu đến các bạn một số thông tin về Laravel 5.5

Từ Laravel 5.3 trở đi thì framework này đã cập nhật thêm 1 khung sườn (scaffold) cho frontend dùng Bootstrap và Vue.js tùy chọn để bạn có thể nhanh chóng bắt đầu một ý tưởng nhanh nhất có thể.

Các tính năng này luôn luôn dễ dàng remove nếu bạn không thích sử dụng, vì nhiều người lại thích dùng Reactjs chẳng hạn, do đó trong Laravel 5.5 đã thêm một Artisan preset command, cho phép bạn thay thế khung sườn mặc định bằng các tools khác như React, Bootstrap thuần và thậm chí gỡ bỏ tất cả.

React Preset

Câu lệnh React preset được khai báo như sau:

php artisan preset react

Sau khi chạy lệnh, nó sẽ replace Vue.js scaffolding (đại loại là khung sườn) bằng React. Nó bao gồm có cấu hình, components và một số files liên quan mặc định.

Nhiều công ty tuyển dụng Frontend Developer đãi ngộ tốt, ứng tuyển ngay!

Bootstrap Preset

Boostrap preset rất hữu dụng khi bạn muốn ưu tiên không muốn dùng bất kỳ một khung sườn sử dụng Javascript nào:

php artisan preset bootstrap

Điều này được thiết kế cho những người muốn thiết lập JavaScript riêng của mình, hoặc chỉ dùng ứng dụng PHP thuần cho nhanh và nhẹ nhàng.

Gỡ bỏ toàn bộ khung sườn Laravel Vue và Boostrap

Chỉ cần đơn giản chạy lệnh:

php artisan preset none

Phần tiếp theo mình sẽ bắt đầu series tuts Laravel và React.

Truy cập ngay việc làm IT đãi ngộ tốt trên TopDev

9 mã nguồn mở cho file upload field

Bạn có thể dễ dàng tìm được các công cụ hữu ích giúp cải thiện web forms, từ các bộ UI kits đến các plugins jQuery nâng cao.

Tuy nhiên, một trong những trường input khó chỉnh sửa nhất là trường upload. Nó là một phần input mặc định của HTML và cho phép người dùng upload tệp lên từ máy tính cá nhân. Việc thiết kế lại trường upload là một thử thách “nặng đô” so với việc thay đổi các yếu tố khác.

Nếu bạn đang mong muốn điều chỉnh các trường upload của mình, thì các thư viện dưới đây có thể giúp bạn. Tôi đã tổng hợp 9 trường upload code tay từ CodePen để chứng minh rằng bạn có thể tái thiết kế trường này theo các bạn muốn.

1. Flat File Upload

Wallace Erick đã tạo nên trường upload này bằng CSS và JavaScript. Nó được thiết kế dựa theo xu hướng thiết kế phẳng (flat design), tránh sử dụng các màu gradient bằng cách chỉ tập trung vào một màu – thường thông qua một cơ chế tông màu đơn sắc.

Bạn có thể thêm upload file này vào bất cứ trang nào và vẫn trông rất phù hợp. Tất cả những gì bạn cần làm đó là thay đổi cơ chế màu và vị trí của nó cho phù hợp với form của mình.

Nó sẽ hoạt động đúng như những gì bạn mong đợi và vì nó chạy trên input HTML chuẩn nên nó còn có thể chạy trên các trình duyệt cũ hơn và hoạt động trên mobile nữa.

2. Custom File Upload

Đây là một thiết kế phức tạp hơn đối với trường upload. Aaron Vanston đã tạo nên tính năng upload file này như một bản sao mà bạn thường thấy trên các website lớn.

Hãy nghĩ về các website công nghệ lớn như Dropbox, Google+ và Facebook. Thường có một vùng kéo & thả file đi kèm với dòng chữ “click here” lớn để mở cửa sổ upload. Đó chính xác là những gì Aaron làm với đoạn snippet này.

Nó dựa trên jQuery và một chút JS/CSS để hoạt động. Và dù cho nó có sử dụng trường input chuẩn HTML, nó vẫn còn có thể xử lý quá trình upload bằng các chức năng tự chọn của JS.

Nếu bạn thông thạo JavaScript, nó có thể hoạt động như một template hữu ích giúp bạn xây dựng UI cho trường file upload của riêng mình.

3. Responsive Animated Uploader

Nếu bạn đang dành thời gian phát triển bất kì thiết kế web nào, bạn sẽ biết rõ rằng bạn phải làm theo xu hướng responsive (có tính tương thích cao). Người dùng mobile có thể upload tệp lên web thông qua các form như thế, vì vậy việc tận dụng responsive trường input là một ý rất hay.

Bạn có thể tham khảo thiết kế này như một mẫu trường upload chất lượng có tương thích với mobile. Nó trông rất căn bản, bao gồm một ô upload nhỏ kèm tính năng kéo – thả.

Lưu ý rằng thiết kế này không sử dụng yếu tố input – vì thế việc nhấn chọn upload là không thể. Tôi cho rằng đây là một cơn ác mộng về tính năng – nhưng nó chỉ là một bản mẫu giúp cho việc kiểm thử – vì thế nó không thể đáp ứng nhu cầu khả dụng hoàn hảo được.

Nếu bạn đem dòng lệnh này vào trang của mình, bạn nên thêm một trường upload thông thường vào bên cạnh vùng kéo & thả.

4. Custom Uploader

Lập trình các project mỗi ngày là một phương pháp phát triển kĩ năng tuyệt vời cho bạn. Drew Vosburg đã áp dụng phương pháp này để dựng nên một upload form đơn giản và miễn phí trên CodePen.

Nó được tùy chỉnh chủ yếu dựa trên các tính năng của JavaScript mà được sử dụng để xử lý hiệu ứng kéo – thả. Nhưng thực chất trường input này được xây dựng để hỗ trợ cả hai tính năng chạm & nhấn, bên cạnh chức năng kéo & thả.

Vùng chọn được là vùng được dán label HTML và style với CSS. Thành phần label này đính kèm vào trường input, cái được dấu đi khỏi trang. Nó hoạt động như một trường có thể click chọn được. Đây là một ý tưởng rất thông minh và hợp lí để áp dụng.

5. Stock Photo Upload Interface 

Đây là một trong những snippet phức tạp nhất, và cũng ấn tượng nhất mà tôi thấy được trên CodePen. Nó cho phép bạn upload ảnh vào thư viện trực tiếp từ máy tính của bạn. Với mỗi bức ảnh mà bạn upload lên, nó sẽ hiển thị bản preview ngay trên trang.

Nó hoạt động bằng cách lấy ảnh bằng JavaScript, sau đó chuyển nó thành base64 để nhúng vào CSS.

Bất cứ khi nào bạn upload ảnh lên server, chúng sẽ tự động tạo nên một file tạm thời. Trên máy chủ của riêng bạn, bạn có thể sử dụng tệp này để hiển thị hình ảnh. Nhưng giờ đây khi CSS hỗ trợ base64, đây chỉ còn là một phương pháp thay thế.

Giao diện này vô cùng gọn gàng và có tính năng upload xen giữa trong đó.

6. Simple Blue Upload UI

Nếu bạn đang tìm kiếm một trường upload không theo JS thì có thể tham khảo mẫu sau, được xây dựng bởi Stephen Baker.

Nó sử dụng CSS3 thuần để đổi cách thức input gói gọn trong một nút lớn. Nó hoạt động bởi một icon upload của Font Awesome và được bọc tròn lại quanh trường upload.

Bạn có thể thay đổi style, màu, icon hay bất cứ yếu tố nào khác để làm nó phù hợp với site của mình. Về căn bản, đây là một phương án cực gọn nhẹ cho thiết kế input mặc định và nó chạy được trên CSS3 thuần.

7. jQuery Custom File Upload Input

Nhà phát triển Terry Young đã dùng một ít jQuery để nâng cấp một số trường upload có sẵn. Dưới đây là kết quả (và tôi có thể nói, đó là một kết quả hết sức đột phá).

Qua các style này bạn có thể thay đổi chữ, kích cỡ, màu của nút hoặc bỏ chữ trong trường upload để chỉ dùng một nút.

Hãy lưu ý rằng cách này đòi hỏi một lượng jQuery đủ tốt vì hầu hết các tính năng không thể chỉnh sửa bằng CSS. Nếu bạn không phiền làm việc với jQuery, thì lựa chọn này sẽ đem đến kết quả phi thường.

8. Flat UI Input File

Đây là một trường upload khá khác biệt được xây dựng bởi Geoffrey Crofte. Nó cũng dựa trên JavaScript, nhưng thiết kế toàn bộ phần input bằng CSS3.

Vì đây chỉ là một bản snippet mẫu, sẽ không có chỗ để bạn upload tệp. Tuy nhiên, nó đủ đơn giản để chỉnh sửa nếu bạn thêm nó vào site của mình. Phần thiết kế và cài đặt chính sẽ mang sức sống đến cho đoạn snippet này.

Chức năng return chạy trên JavaScript, nên đó cũng là nơi bạn xử lý các tệp được upload, những thay đổi hiển thị hay bất cứ cái gì khác.

Điểm tuyệt vời nhất là, các đoạn mã này có thể hoạt động trên các trình duyệt từ thời của IE 8! Vì thế đây là một sự lựa chọn hoàn hảo nếu bạn trăn trở về khả năng truy cập.

9. Multi-trường uploads

Đây là trường tùy chỉnh cuối cùng với một điểm khác biệt: về mặt thẩm mỹ nó có thể trông khá đơn giản – nhưng điểm sáng thực sự nằm ở phần tính năng.

Trường upload này được thiết kế để hỗ trợ nhiều tệp một lúc. Bạn sẽ không hay thấy field này đi với trường input – hoặc ít nhất là không phải mặc định. Người dùng phải chọn nhiều tệp trong cùng một cửa sổ và phần backend phải hỗ trợ việc đó.

Với snippet này, bạn có thể liệt kê tất cả các tên tệp vào một trường upload. Thậm chí bạn có thể dùng JavaScript để chèn thêm các tên tệp đó đâu đó trên trang chính.

Và dù cho trên đây là một số những snippet ưa thích của tôi, chúng chắc chắn không phải là duy nhất. Bạn có thể dạo một vòng tại CodePen để xem bạn có thể tìm thấy những gì khác nữa nhé.

Nguồn: Speckyboy.com

  CSS trong JavaScript: Công cụ không thể thiếu cho component-based styling

Mẹo với Javascript (ES6) và thủ thuật để làm cho code sạch hơn, ngắn hơn, và dễ đọc hơn ( Phần 2)

Tái cấu trúc

Tái cấu trúc là quá trình tách array hoặc object bên trái của dấu bằng. Array hoặc object có thể đến từ một biến, chức năng, hoặc phương trình.

let [ a, b, c ] = [ 6, 2, 9];
console.log(`a=${a}, b=${b}, c=${c}`); //a=6, b=2, c=9
function foo() { return ['car', 'dog', 6 ]; } 
let [ x, y, z ] = foo();
console.log(`x=${x}, y=${y}, z=${z}`);  // x=car, y=dog, z=6

Với việc tái cấu trúc object, các key của object có thể được liệt kê bên trong dấu ngoặc nhọn để lấy ra cặp key-value đó. Xem ví dụ để hiểu rõ hơn:

function bar() { return {a: 1, b: 2, c: 3}; }
let { a, c } = bar();
console.log(a); // 1
console.log(c); // 3
console.log(b); // undefined

Đôi khi, bạn muốn lấy ra các giá trị nhưng gán chúng cho một biến mới. Điều này được thực hiện bằng cách sử dụng kết hợp cặp ‘key: variable’ ở bên trái dấu bằng.

function baz() { 
    return {
        x: 'car',
        y: 'London',
        z: { name: 'John', age: 21}
    }; 
}
let { x: vehicle, y: city, z: { name: driver } } = baz();
console.log(
    `I'm going to ${city} with ${driver} in their ${vehicle}.`
); // I'm going to London with John in their car.

Một điều khác là tái cấu trúc các object cho phép gán một giá trị cho nhiều biến.

let { x: first, x: second } = { x: 4 };
console.log( first, second ); // 4, 4

Tìm việc làm Javascript lương cao

Object Literals và thu gọn Parameters

Khi bạn đang tạo một object literal từ các biến, ES6 cho phép bạn bỏ qua key nếu nó cùng tên với biến.

let a = 4, b = 7;
let c = { a: a, b: b };
let concise = { a, b };
console.log(c, concise) // {a: 4, b: 7}, {a: 4, b: 7}

Điều này cũng có thể được sử dụng kết hợp với việc tái cấu trúc để làm cho code của bạn đơn giản hơn và sạch hơn.

function foo() {
    return {
        name: 'Anna', 
        age: 56,
       job: { company: 'Tesco', title: 'Manager' }
    };
} 
// pre ES6
let a = foo(), name = a.name, age = a.age, company = a.job.company;
// ES6 destructuring and concise parameters 
let { name, age, job: {company} = foo();

Nó cũng có thể được sử dụng để tái cấu trúc các object được truyền vào các function. Phương pháp 1 và 2 là cách bạn đã làm trước ES6, phương pháp 3 sử dụng tái cấu trúc và thu gọn params.

let person = {
    name: 'Anna', 
    age: 56,
    job: { company: 'Tesco', title: 'Manager' }
};
// method 1
function old1( person) {
    var yearOfBirth = 2018 - person.age;
    console.log( `${ person.name } works at ${ person.job.company } and was born in ${ yearOfBirth }.`);
}
// method 2
function old1( person) {
    var age = person.age,
        yearOfBirth = 2018 - age, 
        name = person.name,
        company = person.job.company;
    console.log( `${ name } works at ${ company } and was born in ${ yearOfBirth }.`);
} 
// method 3
function es6({ age, name, job: {company}) {
    var yearOfBirth = 2018 - age,
    console.log( `${ name } works at ${ company } and was born in ${ yearOfBirth }.`);
}

Sử dụng ES6, chúng ta có thể lấy ra giá trị của agename và company  mà không cần khai báo thêm biến.

Dynamic Property Names

ES6 thêm khả năng tạo hoặc thêm thuộc tính với các key được gán một cách linh động.

let  city= 'sheffield_';
let a = {
    [ city + 'population' ]: 350000
};
a[ city + 'county' ] = 'South Yorkshire';
console.log(a); // {sheffield_population: 350000, sheffield_county: 'South Yorkshire' }

Arrow Functions =>

Arrow functions có hai lợi điểm: cấu trúc và thuộc tính this.

Chúng ta có thể có một cấu trúc đơn giản hơn nhiều so với các function truyền thống bởi vì chúng ta không cần từ khai báo từ khóa function, và tự động return kết quả sau dấu mũi tên (=>).

var foo = function( a, b ) {
    return a * b;
} 
let bar = ( a, b ) => a * b;

Nếu chức năng đòi hỏi nhiều hơn một tính toán đơn giản, dấu ngoặc nhọn có thể được sử dụng và function trả về kết quả bất kỳ từ block scope.

If the function requires more than a simple calculation, curly braces can be used and the function returns whatever is returned from the block scope.let baz = ( c, d ) => {
    let length = c.length + d.toString().length;
    let e = c.join(', ');
    Return `${e} and there is a total length of  ${length}`;
}

Một trong những khu vực hữu ích nhất của arrow function là nằm trong các hàm array như .map.forEach hay .sort.

let arr = [ 5, 6, 7, 8, 'a' ];
let b = arr.map( item => item + 3 );
console.log(b); // [ 8, 9, 10, 11, 'a3' ]

 

Vòng lặp for … of

ES6 thêm một cách để lặp lại mỗi giá trị trong một array. Điều này khác hoàn toàn với vòng lặp for ... in đó là nó lặp trên key/index.

(Vòng lặp For..in tương tự như vòng lặp For cơ bản, nhưng có 1 điểm quan trọng là For..in có thể được dùng cho 1 biến kiểu đối tượng)

let a = ['a', 'b', 'c', 'd' ];
// ES6 
for ( var val of a ) {
    console.log( val );
} // "a" "b" "c" "d"
// pre-ES6 
for ( var idx in a ) {
    console.log( idx );
}  // 1 2 3 4

Sử dụng for … of sẽ đỡ phải thêm let val = a[idx] vào bên trong mỗi vòng lặp.

Các array, string, generator and collection đều có thể lặp trong JavaScript. Các đối tượng thường không thể lặp lại được, trừ khi bạn đã define lặp cho nó.

Number Literals

Code ES5 xử lý các định dạng số thập phân và số thập lục phân khá tốt, nhưng nó không hiểu được định dạng bát phân. Bình thường, nếu một số được bắt đầu bằng 0, thì javascript sẽ hiểu đó là hệ cơ số 8. Ví dụ 010 === 8 sẽ trả về giá trị là true. Tuy nhiên, không phải ai cũng biết đến điều đó, và cách viết 010 có thể sẽ khiến nhiều người vẫn hiểu đó là 10. Chính vì thế ở Strict Mode, nó đã bị coi là một lỗi cú pháp.

ES6 đã thêm một định dạng mới, bạn lại có thể dùng cách viết trên, với tiền tố là 0o. Tức dù là trong Strict Mode, nhưng var foo = 0o10 vẫn là một cách viết hợp lệ, và 0o10 === 8 sẽ trả ra kết quả là true.

Number( 29 )  // 29
Number( 035 ) // 35 in old octal form 
Number( 0o35 ) // 29 in new octal form 
Number( 0x1d ) // 29 in hexadecimal 
Number( 0b11101 ) // 29 in binary form

TopDev via Freecodecamp

>>> Xem thêm: Phần 1 : Mẹo với ES6 và thủ thuật để làm cho code sạch hơn, ngắn hơn, và dễ đọc hơn.

Tìm việc làm IT mới nhất trên TopDev

Dù là nhân viên hay ông chủ, bạn cũng cần phải nắm 4 nguyên tắc này để nâng cao chất lượng công việc

Nếu bạn làm việc không ngừng nghỉ từ sáng đến tối trong quá nhiều ngày hoặc bỏ bê việc sử dụng tất cả thời gian nghỉ, có lẽ bạn nên xem lại cách làm việc của bản thân.

 Những người thành công luôn có cách làm việc hiệu quả của riêng họ nhưng họ luôn có một điểm chung là không làm việc trong ngày nghỉ và không lấn giờ làm việc sang giờ ăn. Vậy, họ làm gì để giảm mức căng thẳng và cải thiện sự cân bằng giữa công việc và cuộc sống?

1. Đặt giới hạn

Nếu bạn là ông chủ, bạn phải làm gương bằng cách rời khỏi văn phòng vào một giờ hợp lý, lý tưởng là từ 5 đến 6 giờ chiều. Để không bị công việc cám dỗ mà ở lại lâu hơn, bạn nên sắp xếp lịch thật sát nhau: sắp xếp cuộc họp với bạn bè, đặt chỗ tại lớp tập thể dục hoặc mua vé cho một chuyến tàu sớm hơn.

2. Hãy nghỉ phép

Tại Thụy Điển, người lao động được nghỉ phép năm tuần trong một năm và họ luôn sử dụng chúng. Người Mỹ thường được nghỉ 2 tuần mỗi năm nhưng hầu hết họ thậm chí không sử dụng tất cả số ngày nghỉ. Một công ty, InspireHUB Inc., ở Dallas, đang cố gắng thay đổi văn hoá đó ở Mỹ.

Đồng sáng lập viên công ty, ông Karolyn Hart cho biết: “Chúng tôi cho phép nhân viên kỳ nghỉ không giới hạn, thậm chí nhân viên Canada của chúng tôi còn được hưởng một năm nghỉ thai sản. Người sử dụng lao động cần phải hiểu được lợi thế cạnh tranh họ nhận được từ việc nhân viên nghỉ ngơi tốt: họ sẽ nhận được chất lượng công việc tốt hơn”.

3. Làm việc ít hơn để đạt hiệu quả nhiều hơn

Vào năm 2015, 9 trong số 10 nước nằm ở châu Âu có năng suất hiệu quả nhất trong Tổ chức Hợp tác và Phát triển Kinh tế (OECD), một tổ chức kinh tế liên chính phủ với 35 quốc gia thành viên. Hoa Kỳ – một quốc gia có tần suất làm việc chóng mặt nhưng chỉ đứng thứ sáu. Dữ liệu được xuất bản bởi tờ CNBC xác nhận rằng, thời gian nghỉ không có nghĩa là năng suất lao động thấp hơn.

Cuộc khảo sát Time Off của hơn 7.000 người Mỹ cho thấy 43% công nhân không nghỉ vì họ sợ cảm giác bắt đầu trở lại làm việc. Tuy nhiên, các chuyên gia y tế khuyến cáo nhân viên nên nghỉ ít nhất hai lần một năm để giảm mức căng thẳng và cải thiện sức khoẻ tổng thể.

Học thêm các kiến thức, tìm hiểu các lĩnh vực cùng ngành nghề của mình:

4. Rời khỏi văn phòng

Theo Travel & Leisure, ở Pháp, Tây Ban Nha, Hy Lạp và các nước khác, nghỉ trưa có thể kéo dài một giờ hoặc lâu hơn và hiếm khi diễn ra trước màn hình máy tính. Gần đây, công ty CBRE của Canada thậm chí đã thành lập một chính sách mới của công ty: cấm ăn ở bàn làm việc. Kết quả là nhân viên đã được hiệu quả cao hơn trong suốt ngày làm việc của họ.

Nếu bạn không có thời gian để đi dạo hoặc nghỉ ngơi khác trong ngày, ít nhất hãy tránh ăn trưa ở bàn làm việc của bạn. Theo PayScale.com, con người không nên ngồi cả ngày, vì vậy hãy ăn thức ăn từ dưới phố hoặc ăn trưa bên ngoài và thưởng thức thiên nhiên. Hơn nữa, đó là một trong những cách thông minh để ngăn chặn sự tăng cân của dân văn phòng.

Tìm việc IT lương cao mới nhất trong tháng tại đây

API Authentication trong Laravel-Vue SPA sử dụng Jwt-auth

API Authentication trong Laravel-Vue SPA sử dụng Jwt-auth

Đây là tutorial hướng dẫn bạn các bước thực hiện cung cấp 1 authentication cho Vue Single Page Application (SPA) cần xác thực để access API trong Laravel.

Resources cần chuẩn bị:

  • NodeJS 8.9.1
  • Laravel 5.5
  • jwt-auth 0.5.12
  • NPM 5.6.0
  • VueJS 2.5.7
  • Vue-router
  • Vue-axios
  • @websanova/vue-auth

Cài đặt

Tạo một project laravel bằng cách thực hiện command trong terminal

composer create-project laravel/laravel lara-vue-auth –prefer-dist

Di chuyển vào thư mục project

cd lara-vue-auth

Tiếp theo bạn cần cài đặt javascript dependencies bằng cách sử dụng command

npm install

Bước tiếp theo cung cấp các config để kết nối database trong file .env và tạo db để sử dụng nếu bạn chưa có. Để tạo 1 db trong Laravel thì dùng lệnh sau:

php artisan migrate

Lệnh này sẽ tạo cho bạn 1 db với bản userspassword_resets

  Laravel, bạn đã viết đúng?

Tiếp tục là cài đặt một số thư viện Vue mà chúng ta cần.

npm install --save-dev vue-axios vue-router vue-loader vue-template-compiler

Tạo một file với tên là App.vue trong resources/assets/js và bỏ vào file nội dung sau:

<template>
    <div class="panel panel-default">
        <div class="panel-heading">
            <nav>
                <ul class="list-inline">
                    <li>
                        <router-link :to="{ name: 'home' }">Home</router-link>
                    </li>
                    <li class="pull-right">
                        <router-link :to="{ name: 'login' }">Login</router-link>
                    </li>                    <li class="pull-right">
                        <router-link :to="{ name: 'register' }">Register</router-link>
                    </li>
                </ul>
            </nav>
        </div>
        <div class="panel-body">
            <router-view></router-view>
        </div>
    </div>
</template>

Tạo 1 file khác với tên Home.vue trong resources/assets/js/components và thêm:

<template>
    <h1>Laravel - Vue SPA Authentication</h1>
</template>

Sau đó replace nội dung resouces/assets/js/app.js với nội dung sau:

import Vue from 'vue';
import VueRouter from 'vue-router';
import App from './App.vue';
import Home from './components/Home.vue';

Vue.use(VueRouter);

const router = new VueRouter({
    routes: [
        {
            path: '/',
            name: 'home',
            component: Home
        },
    ]
});

new Vue({
    el: '#app',
    router: router,
    render: app => app(App)
});

Kế tiếp thay đổi content của template resources/views/welcome.blade.php như sau:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <title>Laravel</title>

    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">

</head>
<body>
    <div class="container">
        <div id="app"></div>
    </div>
    <script src="/js/app.js"></script>
</body>
</html>

Bây giờ chạy thử command

npm run watch

php artisan serve

Mở browser và gõ http://localhost:8000. Nếu mọi chuyện ổn thì bạn sẽ thấy homepage nghen. Xong phần cơ bản!

Tạo Vue Components

Tạo file với tên Register.vue trong thư mục resources/assets/js/components với nội dung sau:

<template>
    <div>
        <div class="alert alert-danger" v-if="error && !success">
            <p>Có lỗi đâu đó, đăng ký không thành công.</p>
        </div>
        <div class="alert alert-success" v-if="success">
            <p>Đăng ký thành công. Bạn có thể <router-link :to="{name:'login'}">sign in.</router-link></p>
        </div>
        <form autocomplete="off" @submit.prevent="register" v-if="!success">
            <div class="form-group" v-bind:class="{ 'has-error': error && errors.name }">
                <label for="name">Name</label>
                <input type="text" id="name" class="form-control" v-model="name" required>
                <span class="help-block" v-if="error && errors.name">{{ errors.name }}</span>
            </div>
            <div class="form-group" v-bind:class="{ 'has-error': error && errors.email }">
                <label for="email">E-mail</label>
                <input type="email" id="email" class="form-control" placeholder="user@example.com" v-model="email" required>
                <span class="help-block" v-if="error && errors.email">{{ errors.email }}</span>
            </div>
            <div class="form-group" v-bind:class="{ 'has-error': error && errors.password }">
                <label for="password">Password</label>
                <input type="password" id="password" class="form-control" v-model="password" required>
                <span class="help-block" v-if="error && errors.password">{{ errors.password }}</span>
            </div>
            <button type="submit" class="btn btn-default">Submit</button>
        </form>
    </div>
</template>

Tạo file khác với tên Login.vue trong cùng một thư mục với nội dung sau:

<template>
    <div>
        <div class="alert alert-danger" v-if="error">
            <p>Có lỗi đâu đó, không thể login!</p>
        </div>
        <form autocomplete="off" @submit.prevent="login">
            <div class="form-group">
                <label for="email">E-mail</label>
                <input type="email" id="email" class="form-control" placeholder="user@example.com" v-model="email" required>
            </div>
            <div class="form-group">
                <label for="password">Password</label>
                <input type="password" id="password" class="form-control" v-model="password" required>
            </div>
            <button type="submit" class="btn btn-default">Sign in</button>
        </form>
    </div>
</template>

Lại tiếp tục tạo thêm file Dashboard.vue cùng thư mục và thêm:

<template>
    <h1>Laravel – Dashboard</h1>
</template>

Sau đó replace content của file resources/assets/js/app.js :

import Vue from 'vue';
import VueRouter from 'vue-router';
import axios from 'axios';
import VueAxios from 'vue-axios';
import App from './App.vue';
import Dashboard from './components/Dashboard.vue';
import Home from './components/Home.vue';
import Register from './components/Register.vue';
import Login from './components/Login.vue';
Vue.use(VueRouter);
Vue.use(VueAxios, axios);
axios.defaults.baseURL = 'http://localhost:8000/api';
const router = new VueRouter({
    routes: [{
        path: '/',
        name: 'home',
        component: Home
    },{
        path: '/register',
        name: 'register',
        component: Register
    },{
        path: '/login',
        name: 'login',
        component: Login
    }]
});

@websanova/vue-auth

Đây là thư viện chịu trách nhiệm xử lý các chứng thực tại client side. Nhiệm vụ của nó là thêm 1 object $auth  với cung cấp một số chức năng trợ giúp như register() xử lý đăng ký người dùng, login() xử lý đăng nhập, user() cho phép truy cập vào dữ liệu người dùng hiện tại, rồi logout() và một vài chức năng khác.

Cài đặt @websanova/vue-auth

npm install @websanova/vue-auth

Sau đó modify là app.js như thế này:

import Vue from 'vue';
import VueRouter from 'vue-router';
import axios from 'axios';
import VueAxios from 'vue-axios';
import App from './App.vue';
import Dashboard from './components/Dashboard.vue';
import Home from './components/Home.vue';
import Register from './components/Register.vue';
import Login from './components/Login.vue';
Vue.use(VueRouter);
Vue.use(VueAxios, axios);
axios.defaults.baseURL = 'http://localhost:8000/api';
const router = new VueRouter({
    routes: [{
        path: '/',
        name: 'home',
        component: Home
    },{
        path: '/register',
        name: 'register',
        component: Register,
        meta: {
            auth: false
        }
    },{
        path: '/login',
        name: 'login',
        component: Login,
        meta: {
            auth: false
        }
    },{
        path: '/dashboard',
        name: 'dashboard',
        component: Dashboard,
        meta: {
            auth: true
        }
    }]
});
Vue.router = router
Vue.use(require('@websanova/vue-auth'), {
   auth: require('@websanova/vue-auth/drivers/auth/bearer.js'),
   http: require('@websanova/vue-auth/drivers/http/axios.1.x.js'),
   router: require('@websanova/vue-auth/drivers/router/vue-router.2.x.js'),
});
App.router = Vue.router
new Vue(App).$mount('#app');

Đoạn code trên chúng ta đã included thêm thư viện vừa cài và thêm 1 số config cần để hoạt động với nó.

Cấu hình vue-auth để sử dụng trình điều khiển bearer, nó thêm những authen token cho những request header trong quá trình requests, đọc và parse token từ phản hồi của server:

auth: require('@websanova/vue-auth/drivers/auth/bearer.js')

Tùy chọn config vue-auth để sử dụng axios http driver, vì chúng ta đang sử dụng axios cho các http request:

http: require('@websanova/vue-auth/drivers/http/axios.1.x.js')

Cấu hình vue-auth để sử dụng driver cho vue-router

router: require(‘@websanova/vue-auth/drivers/router/vue-router.2.x.js’)

Chúng ta cũng thêm tùy chọn meta cho route:

 ...
meta: {
    auth: true
}
...

Thuộc tính auth xác định xem cần có sự cho phép access route hay không. True nghĩa là bạn xác định authorization này được quyền access vào dashboard.

Bạn nên xem thêm @websanova/vue-auth để biết cách sử dụng thư viện này nhé. Giờ chạy lệnh:

npm run watch

và truy cập vào dashboard trên browser. Chạy đúng thì nó sẽ redirect bạn đến trang login nha.

Jwt-auth

Tiếp tục chúng ta cần cài đặt thư viện jwt-auth trong laravel, thư viện này xử lý các authentication qua các api của chúng ta.

Chạy dòng lệnh trong terminal sau:

composer require tymon/jwt-auth

Sau đó add service JWTAuthServceProvider cho mảng providers và JWTAuth facade cho mảng aliases trong config/app.php

...
'providers' => [
    ...
    Tymon\JWTAuth\Providers\JWTAuthServiceProvider::class,
]
...
'aliases' => [
    ...
    'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,
]

Publish thử xem:

php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\JWTAuthServiceProvider"

Và generate key trong cấu hình được publish bên trên:

php artisan jwt:generate

Note: Nếu bị lỗi thì bạn check link này xem nhé.

Edit app/Http/Kernel.php để thêm jwt.auth và jwt.refresh

protected $routeMiddleware = [
    ...
    'jwt.auth' => \Tymon\JWTAuth\Middleware\GetUserFromToken::class,
    'jwt.refresh' => \Tymon\JWTAuth\Middleware\RefreshToken::class,
];

Đăng ký

Trước khi chúng ta đi sâu hơn thì cần phải tạo 1 controller và thêm required route ở routes/api.php

Tạo 1 controller cho authen:

php artisan make:controller AuthController

Thêm route

Route::post(‘auth/register’, ‘AuthController@register’);

Tạo thêm 1 FormRequest để handle validation cho tất cả registration request nhé:

php artisan make:request RegisterFormRequest

Mình chỉnh lại RegisterFormRequest một chút:

...
class RegisterFormRequest extends FormRequest
{
    public function authorize()
    {
         return true;
    }
    public function rules()
    {
        return [
            'name' => 'required|string|unique:users',
            'email' => 'required|email|unique:users',
            'password' => 'required|string|min:6|max:10',
        ];
    }
}

Bây giờ tiếp tục tạo phương thức sẽ handle các user registration trong AuthController

public function register(RegisterFormRequest $request)
{
    $user = new User;
    $user->email = $request->email;
    $user->name = $request->name;
    $user->password = bcrypt($request->password);
    $user->save();
    return response([
        'status' => 'success',
        'data' => $user
       ], 200);
 }

RegisterFormRequest class đảm bảo mỗi yêu cầu tuân thủ các quy tắc mà chúng ta đã thiết lập trong phương thức rule()Sau đó phương thức register() thu thập các input của user từ biến $requestmã hóa mật khẩu và tiếp tục đưa dữ liệu người dùng vào database.

Quay lại Vue và connect những gì ta đã làm. Đi tới Register.vue file và thêm đoạn code sau ở dưới cùng nhé:

Now let us go over to vue and connect the dots. Go to your Register.vue file and append the code below to the end of the file.

<script> 
    export default {
        data(){
            return {
                name: '',
                email: '',
                password: '',
                error: false,
                errors: {},
                success: false
            };
        },
        methods: {
            register(){
                var app = this
                this.$auth.register({
                    params: {
                        name: app.name,
                        email: app.email,
                        password: app.password
                    }, 
                    success: function () {
                        app.success = true
                    },
                    error: function (resp) {
                        app.error = true;
                        app.errors = resp.response.data.errors;
                    },
                    redirect: null
                });                
            }
        }
    }
</script>

Rồi đăng ký thử xem sao, nếu không có lỗi xảy ra thì bạn sẽ đăng ký được (tất nhiên :v):

npm run watch

Đăng nhập

Quay trở lại AuthController, chúng ta add thêm phương thức login()

public function login(Request $request)
{
    $credentials = $request->only('email', 'password');
    if ( ! $token = JWTAuth::attempt($credentials)) {
            return response([
                'status' => 'error',
                'error' => 'invalid.credentials',
                'msg' => 'Invalid Credentials.'
            ], 400);
    }
    return response([
            'status' => 'success'
        ])
        ->header('Authorization', $token);
}

Thêm phương thức user()refresh()

public function user(Request $request)
{
    $user = User::find(Auth::user()->id);
    return response([
            'status' => 'success',
            'data' => $user
        ]);
}
public function refresh()
{
    return response([
            'status' => 'success'
        ]);
}

Phương thức user() được dùng để fetch data của user trong khi phương thức refresh() là để refresh token hiện tại.

Nối thêm đống code dưới đây trong routes/api.php:

Route::post('auth/login', 'AuthController@login');
Route::group(['middleware' => 'jwt.auth'], function(){
  Route::get('auth/user', 'AuthController@user');
});
Route::group(['middleware' => 'jwt.refresh'], function(){
  Route::get('auth/refresh', 'AuthController@refresh');
});

Rồi cho connect với Vue thử xem. Trước hết đi tới Login.vue rồi thêm mớ code bên dưới:

<script>
  export default {
    data(){
      return {
        email: null,
        password: null,
        error: false
      }
    },
    methods: {
      login(){
        var app = this
        this.$auth.login({
            params: {
              email: app.email,
              password: app.password
            }, 
            success: function () {},
            error: function () {},
            rememberMe: true,
            redirect: '/dashboard',
            fetchUser: true,
        });       
      },
    }
  } 
</script>

Rồi login thử xem nghen

npm run watch

Đăng xuất

Thêm phương thức logout() trong AuthController

public function logout()
{
    JWTAuth::invalidate();
    return response([
            'status' => 'success',
            'msg' => 'Logged out Successfully.'
        ], 200);
}

Phương thức này đảm bảo rằng người dùng đăng xuất khỏi ứng dụng và làm mất hiệu lực của authentication token và xóa nó khỏi client side.

Giờ thì add them route trong routes/api.php

Route::group(['middleware' => 'jwt.auth'], function(){
   ...
   Route::post('auth/logout', 'AuthController@logout');
});

Xong thì modify App.vue

<template>
    <div class="panel panel-default">
        <div class="panel-heading">
            <nav>
                <ul class="list-inline">
                    <li>
                        <router-link :to="{ name: 'home' }">Home</router-link>
                    </li>
                    <li v-if="!$auth.check()" class="pull-right">
                        <router-link :to="{ name: 'login' }">Login</router-link>
                    </li>
                    <li v-if="!$auth.check()" class="pull-right">
                        <router-link :to="{ name: 'register' }">Register</router-link>
                    </li>
                    <li v-if="$auth.check()" class="pull-right">
                        <a href="#" @click.prevent="$auth.logout()">Logout</a>
                    </li>
                </ul>
            </nav>
        </div>
        <div class="panel-body">
            <router-view></router-view>
        </div>
    </div>
</template>

Xong rồi thử logout nha anh em:

npm run watch

Tham khảo thêm các vị trí cho lập trình viên Laravel ứng tuyển tại đây

  Instant AJAX Search với Laravel và Vuejs

Viết code sạch (Clean code) được gì? Phần 1

Gần đây tôi đã bắt đầu một công việc mới. Với mỗi công việc mới đi kèm một codebase mới. Đây có lẽ là công việc thứ 20 của tôi. Vì vậy, tôi đã nhìn thấy rất nhiều codebases. Thật không may họ đều chịu cùng một vấn đề cơ bản – không thống nhất. Có thể là kết quả của nhiều năm vá code, team dev lớn, thay đổi coder, hoặc tất cả các vấn đề trên.

Điều này tạo ra một vấn đề bởi vì chúng ta đọc code nhiều hơn chúng ta viết code. Khi tôi đọc một codebase mới, những sự mâu thuẫn này khiến tôi phân tâm và khó tập trung vào flow code chính. Chúng khiến tôi chỉ quan tâm đến các phần thụt lề code và biến mà quên đi việc quan tâm những logic code quan trọng.

Qua nhiều năm, tôi bắt đầu rút kinh nghiệm và hình thành cách thức rút gọn code cho dễ đọc. Tôi áp dụng ba phương pháp đơn giản để làm sạch code và cải thiện khả năng đọc của nó.

Để chứng minh, tôi sẽ áp dụng trong đoạn code sau đây, đoạn code mà tôi đã đọc được chỉ vài ngày trước.

function check($scp, $uid){
  if (Auth::user()->hasRole('admin')){
    return true;
  }
  else {
  switch ($scp) {
    case 'public':
      return true;
      break;
    case 'private':
      if (Auth::user()->id === $uid)
        return true;
      break;
    default: return false;
  }
  return false;
  }
}

Áp dụng một code style chuẩn

Tôi biết tôi là người thứ 1.647 nói “format your code”. Nhưng rõ ràng là cần phải thốt lên câu đó. Gần như tất cả các codebase mà tôi làm việc trước đây đều thất bại khi áp dụng một codestyle chuẩn. Với sự hiện hiện của các IDE mạnh mẽ, pre-commit hooks, và CI pipelines nên hầu như không cần phải cố gắng định dạng nhất quán 1 codebase.

Nếu mục tiêu là cải thiện code cho dễ đọc, thì việc áp dụng 1 code style là cách tốt nhất. Điều quan trọng cuối cùng đó là sự nhất quán, khi bạn hoặc team của bạn nhất quán trong việc áp dụng 1 code style thì nó mới đạt được hiểu quả trong việc tối ưu code. Sau khi nhất quán rồi thì đơn giản là chỉ cần config IDE và tool của cả team để nó tự động format code theo chuẩn mình đưa ra là được.

Vì chúng tôi sử dụng PHP, nên tôi chọn áp dụng PSR-2 code style. Tôi sử dụng Php Code Beautifier trong PHPCodeSniffer để tự động định dạng code.

Đây là đoạn code bên trên sau khi áp dụng một code style. Đoạn code mới cho ta thấy được cấu trúc code dễ dàng hơn.

function check($scp, $uid)
{
    if (Auth::user()->hasRole('admin')) {
        return true;
    } else {
        switch ($scp) {
            case 'public':
                return true;
            break;
            case 'private':
                if (Auth::user()->id === $uid) {
                    return true;
                }
                break;
            default:
                return false;
        }
        return false;
    }
}

Đặt tên mọi thứ đúng cách rõ ràng

Vâng, điều này tui nghe đi nghe lại hàng chục lần, tôi biết việc đặt tên mọi thứ là cực khó. Một trong những lý do nó khó là vì không có những rule cụ thể rõ ràng cho việc này. Nó thuộc về ngữ cảnh (context), mà ngữ cảnh thì thường xuyên thay đổi trong lúc code.

Sử dụng những ngữ cảnh để vẽ ra cái tên. Một khi bạn tìm ra cái tên rõ ràng, apply nó vào tất cả ngữ cảnh để liên kết chúng với nhau. Điều này sẽ tạo sự nhất quán và giúp follow biến dễ dàng hơn trong codebase.

Đừng lo lắng về việc sử dụng các quy ước đặt tên truyền thống. Một cái tên rõ ràng quan trọng hơn rất nhiều, hãy sử dụng nó một cách nhất quán trong ngữ cảnh hiện tại, bạn sẽ không hối hận đâu.

Nếu bạn mắc kẹt đâu đó, hãy sử dụng tên tạm thời và tiếp tục code, sau khi code xong một đoạn thì chúng ta hãy trích ra một khoảng thời gian nghĩ ngơi và đặt tên. Việc này không nên quá tốn nhiều thời gian ban đầu vì dễ làm bạn nản hoặc đi vào lối mòn là đặt đại tên, rất nguy hiểm! Tôi thường đặt tại là $bob hoặc $whatever để tránh mắc kẹt vào cái việc khó khăn này khi bắt đầu. Khi bạn hoàn thành 1 đoạn code, bạn hiểu được ngữ cảnh rõ ràng hơn, từ đó mà nghĩ ra được 1 cái tên clear hơn.

Thế thì tại sao tui phải cực dữ vậy? Đơn giản là clear name sẽ giúp cho các bạn dev kế thừa code của tui dễ đọc hơn, họ không phải là đấng toàn năng nhìn vào là hiểu ngay được. Theo quan điểm của mình thì đây là thói quen cực kỳ tốt, mà đã là thói quen thì nên luyện tập thường xuyên, đừng để sự lười biếng làm mình mất đi 1 thói quen tốt cũng như làm codebase sau này tệ hơn.

Quay lại ví dụ, sau khi phân tích code, tui có thêm nhiều ngữ cảnh để nghĩ ra được clear names.

function canView($scope, $owner_id)
{
    if (Auth::user()->hasRole('admin')) {
        return true;
    } else {
        switch ($scope) {
            case 'public':
                return true;
            break;
            case 'private':
                if (Auth::user()->id === $owner_id) {
                    return true;
                }
                break;
            default:
                return false;
        }
        return false;
    }
}

Tránh nested code

Có nhiều quy tắc bất di bất dịch liên quan đến nested code. Nhiều dev tin rằng bạn chỉ nên allow 1 cấp độ lồng code (one nesting level). Tồng thể thì tôi luôn bỏ qua bất kỳ quy tắc cứng nhắc nào, còn đối với người khác thì chắc sẽ nghĩ bỏ qua quy tắc này quy tắc kia sẽ làm code trở nên lỏng lẻo.

Quá nhiều nested code thường không cần thiết. Trong code mẫu ở trên, tôi sẽ tận dụng return statements có sẵn và chuyển switch để remove bớt một số nested code.

function canView($scope, $owner_id)
{
    if ($scope === 'public') {
        return true;
    }

    if (Auth::user()->hasRole('admin')) {
        return true;
    }

    if ($scope === 'private' && Auth::user()->id === $owner_id) {
        return true;
    }

    return false;
}

Chỉ cần vài sự thay đổi nhỏ, đoạn code trở nên dễ đọc dễ hiểu. Nó tốt ngay cả với chính bản thân mình, đừng để sau vài tháng quay lại rồi tự hỏi ai đã code cái đống này!

Lược dịch từ bài viết của tác giả Jason McCreary

  Write clean code. Why not???

5 cách chia một mảng lớn thành nhiều mảng nhỏ trong Javascript

5 cách chia một mảng lớn thành nhiều mảng nhỏ trong Javascript

Dạo này hay xử lý mảng bằng JS nên sẵn viết để chia sẻ vài tips nhỏ, bài này chia sẻ việc chia nhỏ một mảng thành các mảng nhỏ hơn bằng nhiều cách khác nhau.

1.Dùng vòng lặp For và hàm slice

Về cơ bản, mọi phương pháp đều dùng phương thức slice để cắt nhỏ mảng, trong trường hợp này là phương thức dùng vòng lặp For.

Trong trường hợp mảng  không đồng nhất thì các item còn lại cũng sẽ nằm trong một mảng nhỏ, mảng nhỏ này tất nhiên sẽ có ít item hơn mấy mảng trước. Thôi làm cái ví dụ cho dễ hiểu nghen, ta có 1 mảng có 8 item, chia làm 3 mảng nhỏ hơn thì output ra sao ta:

function chunkArray(myArray, chunk_size){
    var index = 0;
    var arrayLength = myArray.length;
    var tempArray = [];

    for (index = 0; index < arrayLength; index += chunk_size) {
        myChunk = myArray.slice(index, index+chunk_size);
        // Do something if you want with the group
        tempArray.push(myChunk);
    }

    return tempArray;
}
// chia moi group co 3 item
var result = chunkArray([1,2,3,4,5,6,7,8], 3);
// Outputs : [ [1,2,3] , [4,5,6] ,[7,8] ]
console.log(result);
  Thuật toán tìm kiếm nội suy trong JavaScript

2.Sử dụng một vòng lặp For, slice và thiết lập function trong prototype của array

Rồi, prototype của array là cái quỷ gì? Trong Javascript nó không có khái niệm Class nha các bợn (ơ kì >_<) nên để kế thừa các trường hay hàm của object thì phải sử dụng prototype nghen anh em. Vì vậy nói ngắn gọn lại là prototype của object là cha của nó.

Cách hai này là chúng ta tạo nhiều hàm tùy chỉnh trong prototype của hàm, trong trường hợp này ta tạo một hàm mang tên là chunk để quất nó:

/**
 * Dinh nghia phuong thuc cua khoi (chunk) trong prototype cua mot array
 * sau do tra ve ket qua la nhung mang nho hon voi cac item da quy dinh.
 *
 * @param chunkSize {Integer} so luong item trong tung group
 */
Object.defineProperty(Array.prototype, 'chunk', {
    value: function(chunkSize){
        var temporal = [];

        for (var i = 0; i < this.length; i+= chunkSize){
            temporal.push(this.slice(i,i+chunkSize));
        }

        return temporal;
    }
});
// chia moi group co 3 item
var result = [1,2,3,4,5,6,7,8].chunk(3);
// Outputs : [ [1,2,3] , [4,5,6] ,[7,8] ]
console.log(result);

Như bạn thấy, nguyên tắc giống nhau là sử dụng một vòng lặp for và phương thức slice nhưng thay vì sử dụng nó trong một hàm, chúng ta quy định nó trong một prototype của mảng. Thì giống như 1 bài toán có nhiều cách giải thôi, thích cách nào thì làm cách đó, vậy đi!

Tham khảo tuyển dụng javascript lương cao trên TopDev

3.Sử dụng array map trong prototype của mảng.

Object.defineProperty(Array.prototype, 'chunk', {
    value: function(chunkSize) {
        var that = this;
        return Array(Math.ceil(that.length/chunkSize)).fill().map(function(_,i){
            return that.slice(i*chunkSize,i*chunkSize+chunkSize);
        });
    }
});

var result = [1,2,3,4,5,6,7,8].chunk(3);
// Outputs : [ [1,2,3] , [4,5,6] ,[7,8] ]
console.log(result);
  Sự khác biệt giữa encodeURI và encodeURIComponent trong JavaScript

4.Sử dụng vòng lặp while và slice

Trong điều kiện bình thường thì vòng lặp while có hiệu suất nhanh hơn một chút so với các phương thức khác, đây là điều chúng ta cũng nên lưu ý về mặt hiệu suất vì khi gặp số lần lặp lớn chẳng hạn, mỗi thứ nhanh một chút cộng lại sẽ nhanh hơn nhiều lần. Vì vậy nếu mảng của bạn rất lớn và bạn muốn băm rất nhỏ thì nên cân nhắc dùng vòng lặp while để tăng performance nghen, kinh nghiệm cá nhân thoai nên ai ko nghe cũng dc.

function chunkArray(myArray, chunk_size){
    var results = [];

    while (myArray.length) {
        results.push(myArray.splice(0, chunk_size));
    }

    return results;
}

var result = chunkArray([1,2,3,4,5,6,7,8], 3);
// Outputs : [ [1,2,3] , [4,5,6] ,[7,8] ]
console.log(result);

 5.Về performance của từng cách

Rồi bây giờ thử benchmark bằng cách băm 1 mảng có 100.000 item (là con số thôi), chia thành khối nhỏ chứa 3 item thôi.

Phương thức Tổng time (ms) Thời gian trung bình cho 1 task (ms)
1 (for loop) 5778.015000000001 5.776805000000013
2 (for loop in prototype) 5681.145 5.679875000000007
3 (array map in prototype) 8855.470000000001 8.854190000000001
4 (while loop) 1468.6650000000002 1.468275000000002

Rồi xem bản chỉ số thì thấy dùng vòng lặp while chạy ngon hơn nghen, nên ngon thì dùng thôi. Cám ơn các bạn đã đọc, hy vọng sẽ giúp đỡ được ai đó!

Tham khảo thêm vị trí tuyển dụng lập trình viên hấp dẫn khác tại Topdev.vn

Cấu hình Redis Caching để tăng tốc site WordPress của bạn

Wordpress - Cách tối ưu web lên 99 điểm trên di động PageSpeed Insights

Redis là cái gì?

Hỏi hơi dư thừa vì có đầy trên mạng, nhưng tóm gọn lại cho bạn khỏi phải đi đâu lòng vòng nhé. Redis là hệ thống lưu trữ key-value với rất nhiều tính năng và được sử dụng rộng rãi. Redis nổi bật bởi việc hỗ trợ nhiều cấu trúc dữ liệu cơ bản (hash, list, set, sorted set, string. Bên cạnh lưu trữ key-value trên RAM với hiệu năng cao, redis còn hỗ trợ lưu trữ dữ liệu trên đĩa cứng (persistent redis) cho phép phục hồi dữ liệu khi gặp sự cố.

Túm tụm lại là mình có thể lưu trữ dữ liệu với Mysql và dùng Redis để caching trên Ram nên nó sẽ ít truy vấn đến DB, chạy trên ram nữa nên truy suất dữ liệu cũng nhanh hơn bình thường.

Trong tuts này mình sẽ hướng dẫn cấu hình cache với Redis để giảm các truy vấn dư thừa và tốn thời gian để render 1 page của WordPress. Hướng dẫn này cấu hình trên Ubuntu 14.04. Mình có thử benchmark trên site WP mặc định khi không có Redis và sau khi cấu hình Redis:

Default WordPress home page không Redis:

804ms page load time

Default WordPress home page có Redis:

449ms page load time

Redis vs. Memcached

Memcached cũng là 1 lựa chọn cache phổ biến. Nhưng tại thời điểm hiện tại, Redis có thể làm mọi thứ mà Memcached có thể, với nhiều tính cực ngon hơn. Các bạn có thể tham khảo thêm Stack Overflow page để  tổng hợp thông tin về Redis, rồi từ đó rút ra kết luận riêng cho mình.

Caching làm việc như thế nào?

Khi WP page load lần đầu, nó sẽ truy vấn trực tiếp Database trên server, sau đó ông Redis sẽ cache lại cái truy vấn này trên Ram. Về sau khi những user khác load trang thì kết quả sẽ được trả bởi anh Redis chứ không truy vấn anh DB nữa. Việc hạn chế truy vấn sẽ giúp cho DB ít hoạt động hơn, đỡ ngốn resource của server hơn.

Bước 1: Cài Redis

Để sử dụng Redis với WordPress, cần phải cài đặt hai gói: redis-serverphp5-redis. Gói redis-server cung cấp bởi chính Redis, trong khi gói php5-redis là 1 extension dành cho các ứng dụng PHP như WordPress để connect với Redis.

Cài đặt :

sudo apt-get cài đặt redis-server php5-redis

Bước 2: Cấu hình cahce Redis

Sửa file /etc/redis/redis.conf và thêm một số hàng ở dưới cùng:

sudo nano /etc/redis/redis.conf

Thêm 2 dòng này ở cuối file:

maxmemory 256mb
maxmemory-policy allkeys-lru

Bước 3: Redis Cache Backend Script

Cái script PHP cho WordPress được code bởi Eric Mann. Nó là Redis object cache backend cho WordPress. Bạn tải về rồi cho nó vào /wp-content.

Bước 4: Bật cache settings trong wp-config.php

Sửa file config nhé:

nano /var/www/html/wp-config.php

Thêm dòng này vào cuối dòng * Authentication Unique Keys and Salts.

define('WP_CACHE_KEY_SALT', 'example.com');

Nhớ enable cache cho WP

define('WP_CACHE', true);

Tổng quan là vầy

 * Authentication Unique Keys and Salts.

. . .

define('NONCE_SALT',       'put your unique phrase here');

define('WP_CACHE_KEY_SALT', 'example.com');
define('WP_CACHE', true);

Bước 5: Restart lại Redis và Apache (hay Nginx…)

Restart Redis:

sudo service redis-server restart

Restart Apache:

sudo service apache2 restart

Restart php5-fpm nếu bạn có sử dụng nó

sudo service php5-fpm restart

Đến đây là xong rồi, lúc này WP của bạn đang dùng Redis để caching.

Monitor Redis với redis-cli

Để monitor Redis thì dùng lệnh này:

redis-cli monitor

Lệnh này sẽ xuất ra màn hình các truy vấn được Redis caching realtime. Nếu màn hình trắng trơn thì vào lại trang chủ để nó query rồi nó cache cho xem nghen. Hết rồi, cám ơn đã đọc!

Tham khảo thêm tuyển dụng lập trình WordPress lương cao tại Topdev

  11 cách tăng tốc nhanh cho WordPress bằng file wp-conig.php