Hỏi về cấu trúc xử lý trong vuejs
Em mới bặp bẹ học vuejs, giờ muốn học căn bản nhưng lại gặp luôn vấn đề ạ..ý tưởng của em là tạo ra một form input dùng chung cho cả create, update như e thường làm khi dùng blade ở laravel. trên là code form
<template>
<div>
<label for="postname">Name </label>
<input v-model="post.postName" placeholder="post name" id="postname" class="form-control">
<label for="description"> Description</label>
<textarea v-model="post.description" cols="30" rows="10" class="form-control" id="description"></textarea>
</div>
</template>
<script>
export default {
name: "FormComponent",
data() {
return {
post: {},
}
},
</script>
và code trang create
<template>
<div class="container">
<NavComponent></NavComponent>
<FormComponent></FormComponent>
<button @click="submitInfor()">Submit</button>
</div>
</template>
<script>
import NavComponent from './NavComponent';
import FormComponent from './FormComponent';
export default {
name: "CreateComponent",
components: {
NavComponent,
FormComponent
},
data() {
return {
post: {}
}
},
}
</script>
đây mới là bước đầu em muốn lấy dự liệu từ thằng form và đẩy vào một method rồi sử dụng ạ..em có tìm hiểu được truyền dữ liệu từ cha sang con dùng prop
và dùng emit()
từ con sang cha
nhưng với trường hợp này e k biết dùng như nào..e muốn khi nhập dữ liệu ở page form xong e ấn nút submit ở page create e lấy đc dữ liệu từ form ạ
3 CÂU TRẢ LỜI
trong trường hợp này tốt nhất anh nên vứt cái button kia vào FormComponent nhé, hoặc là anh có thể dùng https://vuejs.org/v2/guide/components-custom-events.html
<FormComponent :post.sync="post"/>
hoặc có thể truyền prop từ component cha xuống component con
@quankm1097 em ơi theo a tìm hiểu khi muốn truyền dữ liệu từ con
sang cha
thì dùng emit
mà nhỉ, theo code của e cũng đang bị lỗi
@luatvd trong component con anh phải định nghĩa props truyền vào và trong phần data không được định nghĩa post nữa
@luatvd Vâng. Muốn truyền dữ liệu từ con sang cha phải dùng emit do props chỉ là read-only. Nghĩa là anh chỉ có thể đọc props trong component con nhưng không thể ghi (nghĩa là không dùng được v-model). Nên có thể có 2 giải pháp cho anh. 1 là dùng emit để đẩy dữ liệu lại từ con lên cha sau đó sử lý ở component cha. 2 anh theo cách của @hoangken là truyền prop với để button đấy vào component con sau đây copy cái props đấy thành 1 object trong data.
<template>
<div>
<label for="postname">Name </label>
<input v-model="handlePost.postName" placeholder="post name" id="postname" class="form-control">
<label for="description"> Description</label>
<textarea v-model="handlePost.description" cols="30" rows="10" class="form-control" id="description"></textarea>
<button @click="submitInfor()">Submit</button>
</div>
</template>
<script>
export default {
name: "FormComponent",
props:['post']
data() {
return {
handlePost : this.post
}
},
methods:{
submitInfor(){
//Xử lý handlePost
}
}
</script>
@quankm1097 cảm ơn em..nhưng nếu như vậy là a xử lý luôn trong này rồi thì cần gì thằng cha nữa nhể..như code bên trên của e
@luatvd Mục đích của viết component là sử dụng được ở nhiều chỗ, ví dụ chẳng hạn về sau anh cũng có 1 form tương tự nhưng khi handle submitInfor
lại xử lí khác đi một chút thì component này của anh không có tính tái sử dụng
. Vậy thì nó có ý nghĩa gì nữa đâu ? Thà anh đừng tách ra khéo còn dễ hơn
Cái form của bạn @luatvd có thể cải tiến làm như sau để dùng chung cho cả create và update
<template>
<div>
<label for="postname">Name</label>
<input v-model="form.postName" placeholder="post name" id="postname" class="form-control">
<label for="description">Description</label>
<textarea v-model="form.description" cols="30" rows="10" class="form-control" id="description"></textarea>
<button @click="$emit('submit', form)">Submit</button>
</div>
</template>
<script>
import _get from 'lodash/get'
export default {
props: {
post: {
type: Object,
default: () => null
}
}
data() {
return {
form: {
name: _get(this.post, 'name', ''),
description: _get(this.post, 'name', ''),
...
}
}
}
}
</script>
Như bạn thấy:
- Trong form mình truyền
post
vào, nếupost
không có thì default value lànull
. - Lúc data của component được khởi tạo, mình sẽ gán giá trị từ prop
post
(nếu có) vàoform
trong component state. - Khi nhấn submit thì mình bắn event
submit
ra cho component, với parametter là dữ liệu của biếnform
trong state. - Component cha sẽ listen cái event submit và thực hiện làm hành động gì đó như create, update.
@huukimit Cách của bạn hay..mình mới học nên còn nhiều cái chưa biết..bạn có thể chỉ mình cách lắng nghe khi có sự kiện từ thằng con không, trong các lần mình làm thì mình dùng một method khác để bắt..nhưng trong trường này mình chưa biết bắt như nào
@luatvd Event (tạm dịch là Sự kiện) bạn nghiên cứu thêm tại đây nha. https://vuejs.org/v2/guide/events.html Event trong Vue.js thực tế thì bạn đã dùng rất nhiều nhưng có điều bạn chưa để ý và chưa đọc kỹ document của Vue.js. Nó tương đồng với Event trong javascript cách dùng thì tương tự như bạn dùng @click="handleClick"
, @change
...
Trong ví dụ mình đưa ra cho bạn thì nó nâng cao hơn một chút, thay vì bạn chỉ dùng các event mặc định @click, @change, thì chúng ta tạo ra một event của riêng mình có tên là submit
. Đơn giản chỉ bằng cách gọi this.$emit('event-name', parametter)
để bắn một custom event ra bên ngoài thằng cha. event-name
là tên event của bạn.
Như bạn biết, Event đi kèm với Listener, thằng cha sẽ có một bộ Listener và theo dõi event xảy trong thằng con. Nếu khai báo @event-name="yourHandler"
, bạn chỉ định cho nó luôn theo dõi sự kiện event-name
, bất cứ khi nào có event thì thực hiện method yourHandler
.
Về sự khác biết với việc bạn truyền function qua prop, bạn có thể thấy là tính chủ động của component cha, giúp tăng tính linh hoạt bởi component cha tự động thực hiện một công việc gì đó khi có event, không cần phải khai báo props, validate prop trong thằng con... Mình nói tới đây thôi nha, bạn nên chủ động tìm hiểu thêm. Bất cứ thắc mắc nào hãy đăng lên Viblo để mọi người support. (go)
VD:
<parent-component>
<child-component @hungry="giveFood"/>
</parent-component>
Mình cũng mới tìm hiểu Vuejs. nhưng mình thấy bạn thử truyền theo kiểu ref trong thằng con xem sao... nghĩa là components con khi được cha gọi thì mình chuyền ref vào vd: <FormComponent ref="child_components"></FormComponent> khi bấm submit chỉ cẩn bạn gọi this.$refs.child_components thử console nó ra xem ra gì ko...