+7

Những practices mà bạn nên dùng trong Vuejs

Thời gian gần đây mình đã được làm việc với vuejs khá nhiều và lúc đầu khi tiếp nhận dự án mình đọc code của người trước có những đoạn mình không hề biết tại sao lại viết như vậy => không hiểu là họ viết gì 😂 😂. Nhưng sau khi tìm hiểu mình mới thấy nó khá là hữu ích và giúp cho việc mở rộng trở lên dễ dàng hơn, tránh lặp code và trông clean hơn.

1, Slot tại sao không?

Thường thì khi tạo một component thường thì chúng ta sẽ để ý đến prop, state, event của component đó vì nó là những điều cơ bản của 1 component. Và chỉ cần một vài chức năng nhỏ nhỏ nữa là component có thể hoạt động ngon lành rồi.

Nhưng cứ nhỏ nhỏ cộng dồn lại sẽ thành một cục to đùng rồi cũng phải ngồi để refactor lại chúng thôi. Popup ngày trước thì nay cần mở rộng thêm và nó không còn đáp ứng được nhu cầu, hiển thị thêm cái banner hay thông tin gì gì đó như khách hàng yêu cầu - thêm vài cái prop nữa là giải quyết được ý mà 🥲🥲 - dùng thêm emit chỗ này này vậy là xong rồi 🥲🥲.

Rồi cái component trông chả khác gì một đống tạp nham đọc không đâu vào với đâu.

Vậy thì hãy để slot giải quyết giúp những đoạn code đó ngắn gọn, dễ hiểu hơn.

ví dụ cái cho dễ hiểu 😁 chứ đọc chữ không hiểu gì cả:

<template>
  <div class="c-base-popup">
    <div v-if="$slots.banner" class="c-base-popup__header">
      <slot name="banner">
    </div>
    <div v-if="$slots.info" class="c-base-popup__subheader">
      <slot name="info">
    </div>
    <div class="c-base-popup__body">
      <h1>{{ title }}</h1>
      <p v-if="description">{{ description }}</p>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    description: {
      type: String,
      default: null
    },
    title: {
      type: String,
      required: true
    }
  }
}
</script>

Đọc thêm về slot ở đây https://vuejs.org/v2/guide/components-slots.html

Sử dụng đúng chỗ sẽ giúp code dễ dàng mở rộng và dễ đọc hơn. Các sự kiện cũng được chia ra không còn tập chung trong 1 component ( vài nghìn dòng code chẳng hạn 🙃).

2, Store trong VueX

Khi bạn cần sử dụng dữ liệu ở một component khác nhưng lại phải truy cập qua vài cái component khác để lấy chúng vậy thì hãy dùng store để giải quyết thôi.

ví dụ: khi bạn muốn lấy thông tin của user đang sử dụng trang thì bạn chỉ cần tạo 1 store để lấy thông tin và lấy nó ra thôi.

export const state = () => ({
    user: null,
})

export const actions = {
    async init ({ commit }) {
        const { data } = await axios.get('/get-users').then(res => res.data)

        commit('setUser', data)
    }
}

export const mutations = {
    setUser(state, data) {
        state.user = data
    },
}

export const getters = {
    user: state => state.user
}

Component:

<tempalte>
    <div>
        <p>name: {{ user.name }}</p>
        <img :src="user.avatar">
    </div>
</template>

<script>
    import { mapState, mapActions } from 'vuex'

    export default {
        computed: {
            ...mapState('user', ['user'])
        }
    }
</script>

Và giờ chỉ cần dùng mapState thôi là có thể lấy được thông tin của user rồi. Và tất nhiên là mình cũng chỉ đặt tên theo ví dụ thôi 🤣🤣. Chính vì thế mà chúng ta nên đặt tên cho file store để người khác đọc là biết nó dùng để làm gì.

3, Call API trong action và commit data (Vuex)

Như ở ví dụ trên mình có call api bằng axios để lấy thông thi của user và bạn có để ý mình call api ở trong action và sử dụng commit để lưu thông tin của user không và tại sao phải phải làm vậy?

Vì:

  • Nếu ở 2 trang mà call cùng 1 Api thì chúng ta phải gọi lại API đó ở 2 page, co vẻ bị trùng lặp code ở đây. Nếu bạn đã call api đó ở action thì chúng ta chỉ cần dispatch action đó là xong.
  • Quan trọng hơn là code của chúng ta sẽ logic, clear hơn khi chúng ta biết api chúng ta gọi ở đâu.

4, Nên dùng mapState, mapGetters, mapMutations và mapActions

Khi mới tìm hiểu vuex. Khi muốn truy cập vào state, getters, hay dispatch action thì mình hay dùng như thế này:

export default {
  computed: {
     myGetter() {
         return this.$store.getters['myModule/myGetter'];
     },
     myGetter2() {
         return this.$store.getters['myModule/myGetter2'];
     }
  },

  methods: {
    myAction() {
        this.$store.dispatch('myModule/myAction');
    },
     myAction2() {
        this.$store.dispatch('myModule/myAction2');
    }
  }
};

Code như trên cũng đúng và không có gì sai cả nhưng trông nó quá dài dòng và không được clean lắm. Thay vào đó bạn nên sử dụng mapState, mapGetters, mapMutationsmapActions

import { mapGetters, mapActions } from "vuex";

export default {
  computed: {
    ...mapGetters(['myModule/myGetter','myModule/myGetter2'])
  },

  methods: {
    ...mapAction(['myModule/myAction','myModule/myAction2'])
  }
};

Như vậy trông code sẽ clean hơn. Bạn có thể đọc thêm về chúng ở đây:

Vậy là hết rồi đấy

Trên đây là số ít kinh nghiệm làm việc với vue của mình. Cảm ơn vì đã đọc bài của mình. Nếu hay thì cho mình 1 upvote để có thêm động lực nhé 😆😆


All rights reserved

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í