Reactjs 和 Vuejs 建立 Component 的方式比對
最近這陣子剛好有機會接觸到 Vuejs,之前覺得會寫一點 Reactjs 應該就可以騙吃騙喝了(誤),但是這陣子感受到蠻多人好像都開始寫 Vuejs,不稍微碰一下感覺會落伍啊!其實學 Vuejs 是為了在 Laravel 前端上使用,之前稍微看過一些文章感覺真的蠻棒的!
以下的文章或許會有錯誤,I'm Vuejs rookie!希望在讀文章的各位不要鞭的太用力,若有錯誤歡迎指正!
Create Simple Todo List
How to create Reactjs Todo List Component:
const Todo = ({ todo }) => (<li>{todo.text}</li>);const TodoList = ({ todos }) => {const todoNode = todos.map(todo => <Todo todo={todo} key={todo.id} />);return (<ul>{todoNode}</ul>);};class App extends Component {constructor() {super();this.state = {todos: [{ id: 1, text: 'Write Some Code' },{ id: 2, text: 'Running' },{ id: 3, text: 'Play Baskebtall' },]};}render() {return (<div><TodoList todos={this.state.todos} /></div>);}}
How to create Vuejs Todo List Component:
<div id="app"><ul><todo-item v-for="todo in todos" :key="todo.id" :todo="todo"></todo-item></ul></div>
Vue.component('todo-item', {props: ['todo'],template: `<li>{{ todo.text }}</li>`,});new Vue({el: '#app',data: {todos: [{ id: 1, text: 'Write Some Code' },{ id: 2, text: 'Running' },{ id: 3, text: 'Play Baskebtall' },]}});
觀察 Reactjs 和 Vuejs 他們是如何傳遞 props
Reactjs 部分
Reactjs 主要透過自己特殊的 jsx
語法,看到 class App
return 的地方:
<TodoList todos={this.state.todos} />
- 在 App constructor 初始化的 todos state。
<TodoList todos={this.state.todos} />
的 tag todos,這是要傳到 child component 的 props name,可以透過這樣的方式不斷的往下傳遞 props,除了傳值之外也可以傳 function。const TodoList = ({ todos }) => { ... }
我們 destructuring 傳下來的 props,再把這些 todos 做 map 往<Todo />
傳下去。
Vuejs 部分
Vuejs 主要是從 HTML 上的 attribute 特性來實現的:
<todo-item v-for="todo in todos" :key="todo.id" :todo="todo"></todo-item>
看到 Vuejs 自己特殊的
v-for
attribute,這裡就是 iteratortodos
的 Object,也是我們熟悉的 for-in。:key="todo.id"
是v-bind:key="todo.id"
的縮寫,後面的:todo
也是。
- 註:這裡的
:todo
是動態的,它會受到 parent component 影響,更多請參考官方文件說明
todo-item
是由我們自己所定義的 Component,可以看到第二個參數物件內的props
:
Vue.component('todo-item', {props: ['todo'],template: `<li>{{ todo.text }}</li>`,});
props: ['todo']
是由 parent:todo
傳下來的 ,所以我們可以在 child component 內的props
來接收。
我們在 root component 內已經先初始化 todos
的資料:
new Vue({el: '#app',data: {todos: [{ id: 1, text: 'A' },{ id: 2, text: 'B' },{ id: 3, text: 'C' }]}});
加入新增 Todo 的方法
Reactjs 部分
// 新增一個 functional componentconst InputTodo = ({ addTodo }) => {let inputText;return (<div><input ref={input => inputText = input} /><button onClick={() => {addTodo(inputText.value);inputText.value = '';}}>Add</button></div>);};
// 在 App 新增一個 `addTodo` methodaddTodo = (todo) => {const todoLength = this.state.todos.length;this.state.todos.push({id: todoLength + 1,text: todo,});this.setState({ todos: this.state.todos });}//// 在 App return 內把 InputTodo Component 加入,// 並把 `this.addTodo` function 作為 props 傳下去<InputTodo addTodo={this.addTodo} />
Vuejs 部分
- 在 HTML 內加入一個
input
和button
。 - input 使用
v-model
來 binding。 - button 監聽 onClick 事件,當被點擊時,觸發並使用
addTodo
這個 method 來處理。
<input v-model="text" /><button @click="addTodo">Add</button>
- 在
data
新增一個text
,主要是和input
的v-model="text"
做 binding,當 input 輸入值改變時,也會改變data.text
。 methods
是當一些 event 被觸發時,要對應到哪個 method 來做處理,這裡我們在 button 設定@click="addTodo"
,所以在 methods 也要有對應的 addTodo method。
// 更新 JavaScript 部分data: {text: '',todos: [{ id: 1, text: 'Write Some Code' },{ id: 2, text: 'Running' },{ id: 3, text: 'Play Baskebtall' },]},methods: {addTodo() {let todoLength = this.todos.length;this.todos.push({id: todoLength + 1,text: this.text,});this.text = '';}},
大概可以稍微感受一下 Vuejs,不過看了一下官方文件,不過還蠻多很棒的特性都還沒有使用到啊!