Yêu cầu thg 1 10, 2019 7:07 SA 216 0 3
  • 216 0 3
0

Hỏi về cấu trúc xử lý trong vuejs

Chia sẻ
  • 216 0 3

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


Đã trả lời thg 1 10, 2019 7:14 SA
Đã được chấp nhận
+2

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

Chia sẻ
thg 1 10, 2019 7:35 SA

@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 ggggg.png

thg 1 10, 2019 7:40 SA

@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

thg 1 10, 2019 7:41 SA

@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>
thg 1 10, 2019 8:02 SA

@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

Avatar Quiet @simple1805
thg 1 10, 2019 8:09 SA

@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

Đã trả lời thg 1 10, 2019 8:18 SA
+2

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ếu post 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ào form 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ến form trong state.
  • Component cha sẽ listen cái event submit và thực hiện làm hành động gì đó như create, update.
Chia sẻ
thg 1 10, 2019 10:07 SA

@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

thg 1 10, 2019 3:05 CH

@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>
Đã trả lời thg 1 12, 2019 10:04 SA
0

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...

Chia sẻ
Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí