Bài viết được sự cho phép của tác giả Kiên Nguyễn
Bắt đầu với lí do tại sao lại có chuỗi bài Vuejs Anti Pattern.
Trong quá trình lead một team làm việc chủ yếu với Nuxtjs và Typescript. Bản thân tôi thấy rất nhiều member bị dính những con bug khá khoai (đại loại như out of control)
Sau khi bỏ time điều tra, hầu hết do các bạn code không theo một quy củ nào. Cũng không có tài liệu nào cho biết cách làm A thì tốt hơn cách làm B. Hoặc cách làm C sẽ gây khó khăn sau này khi maintain
Xem thêm các chương trình tuyển dụng Vuejs hấp dẫn trên TopDev
Chính vì vậy tui viết chuối bài Vuejs Anti Pattern liệt kê những pattern cần tránh khi làm việc với Vuejs
Có 2 phần nha, phần này là phần 1
Bắt đầu thôi nào!
1. Communication – Giao tiếp giữa các component
Communication là giao tiếp, trong Vuejs Anti Pattern thì pattern này khá phổ biến và cũng được biết tới rất nhiều. Hiện nay có vẻ không còn nhiều người còn dính pattern này trong quá trình làm
Giả sử ta cố 2 component, một là Todo List và thứ hai là Todo Item. Component Todo List sẽ render một loạt các component Todo Item. Lúc này việc giao tiếp giữa các component sẽ trở nên quan trọng.
Thông thường Vue sẽ cho phép ta access được tới $parent (component cha) và $child (component) con. Bằng cách này:
BAD
export default { props: ['todo'], methods: { completeTodo(todo) { this.$parent.$options.methods.completeTodo(todo); } } }
Cách làm này có một cái dở, 2 component cha con bị dính lấy nhau. Component cha mặc định sẽ phải có method completeTodo
Với emit, giao tiếp giữa 2 component cha con trở nên đơn giản và gọn gàng hơn nhiều
GOOD
methods: { completeTodo(todo) { this.$emit('completeTodo', todo) } }
Pattern này khá phổ biến và cũng thường xuyên được áp dụng. Anh em có thể đã khá quen với pattern này rồi.
2. Children mutating props – Thay đổi props
Mục đích chính của pattern này là tuyệt đối không thay đổi props khi đã đưa qua component con
Props should be considered the source of truth when passed down to a component and thus, change the value from within a child component is typically bad practice
Props nên được cân nhắc để không thay đổi khi đã gửi qua component, thay đổi props khi gửi qua child component cũng là bad practice
Thay đổi props
BAD
methods: { completeTodo(todo) { this.todo = [{id: 1, name: 'Do the dishes.'}]; this.$emit('completeTodo', todo) } }
Component props tuyệt đối không nên thay đổi, chỉ được sử dụng
GOOD
export default { props: { age: { type: Number, } }, data() { return { personAge: this.age } }, }
Nếu muốn thay đổi giá trị props thì tạo variable mới, việc thay đổi hoặc change value của props rất dễ gây confuse cho việc sử dụng sau này, cũng như tiềm ẩn nhiều bug out of control.
3. Mutating property arrays
Trong danh sát Vuejs Anti Pattern được liệt kê ở bài viết này, mutating là pattern không được nhiều người để ý tới. Hoặc sau khi có bug ẩn mới phát hiện và chú ý tới. Pattern này cũng liên quan tới props, tuy nhiên cái cần để tâm là liên quan tới arrays
An important consideration to make when passing down arrays and objects as properties within JavaScript is the fact that they are passed by reference
Một điểm quan trọng khi pass props có kiểu dữ liệu array hoặc object thì kiểu gửi này là kiểu gửi tham chiếu (reference)
Chính vì kiểu gửi tham chiếu nên khi thay đổi data ở component con rất có thể sẽ ảnh hưởng tới props truyền vào ở component cha.
BAD
<template> <div> <h1>Parent Component</h1> <ul> <li v-for="friend in friendList" :key="friend.id">{{friend.name}}</li> </ul> <Person :friendList="friendList" /> </div> </template> <script> import Person from './components/Person'; export default { data() { return { friendList: [{ id: 1, name: 'John Doe' }] } }, components: { Person } } </script>
Ở component con, nếu ta thay đổi value của array truyền vào, sẽ ảnh hưởng trực tiếp tới value ở component cha
<template> <div> <h1>Child Component</h1> <ul> <li v-for="friend in friendList" :key="friend.id">{{friend.name}}</li> </ul> <button @click="addFriend">Add Friend</button> </div> </template> <script> export default { props: { friendList: { type: Array, } }, methods: { addFriend() { this.friendList.push({ id: 2, name: 'Sarah Doe' }) } } } </script>
Việc thay đổi mất kiểm soát này có thể phát sinh bug, để tránh những vấn đề không đáng có này, ta có thể tạo variable mới có cùng value với props truyền vào
GOOD
export default { props: { friendList: { type: Array, } }, data() { return { fList: [...this.friendList] } }, methods: { addFriend() { this.fList.push({ id: 2, name: 'Sarah Doe' }) } } }
4. Using data as an object
Đây là anti pattern cuối trong chuỗi bài Vuejs Anti Pattern. Pattern này nói về cách sử dụng data. Tuyệt đối tránh sử dụng data như là một object
When creating components with Vue, it’s important that the data option is a function that returns a new object holding data, rather than just a plain data object.
Khi tạo component với Vue, điều quan trọng là data option bản thân nó là một function trả về một object mới, không phải là một data object thuần túy
Nếu ta sử dụng data object không phải là một function, tất cả instance của component sẽ dùng chung một data, không tốt.
Mỗi khi data change, tất cả instance của component cũng sẽ thay đổi theo, cái này khá tệ về mặt performance. Để đảm bảo component chỉ quản lý data thuộc về nó, tránh những component khác bị kéo theo. Ta nên sử dụng return
BAD
data: { recipeList: [], selectedCategory: 'Desserts' }
GOOD
data () { return { recipeList: [], selectedCategory: 'Desserts' } }
By creating the
return
statement, it allows each instance created to have its own object rather than a shared one. This then allows the code to be used multiple times without the conflict of shared data.Bằng cách sử dụng return, việc này cho phép mỗi instance khi được tạo sẽ có data object của riêng nó. Việc này cũng cho phép code được sử dụng nhiều lần mà không gây ra đụng độ do việc chia sẻ data
Component cũng có thể reuse nhiều lần mà không bị đụng độ cũng như tránh việc update data liên tục ở các component khác.
5. Tham khảo thêm về Vuejs Anti Pattern
- 3 Anti-Patterns to avoid in Vue.js
- Vue.js 2 Design Patterns and Best Practices by Paul Halliday
- Vue 3 có gì mới? – What’s new from Vue 3?
Thank for your time to read – Have a great day! – Happy coding!
Bài viết gốc được đăng tải tại kieblog.vn
Có thể bạn quan tâm:
- Nên học lập trình web cơ bản ở nhà hay ở trung tâm?
- Các loại Design patterns
- Protected: Viết code sạch (Clean code) được gì? Phần 1
Xem thêm Việc làm IT hấp dẫn trên TopDev