Asked Aug 1st, 2:12 a.m. 120 1 1
  • 120 1 1
+1

Cách sử dụng Vuejs và CMS Strapi để làm chức năng đa ngôn ngữ

Share
  • 120 1 1

Em đang sử dụng VueJS để làm giao diện và quản lý CMS + nội dung bằng Strapi, Strapi đã hỗ trợ em tạo ra các bản ghi đa ngôn ngữ trong một bảng dữ liệu chỉ cần khi call api gọi theo đúng cái key locales='xxx' là được.

Tuy nhiên em vẫn chưa biết cách làm sao để nó có thể hoạt động. Theo logic của em trong cái dropdown để thay đổi ngôn ngữ khi em click vào EN hoặc VI thì sẽ check điều kiện để thay đổi đường dẫn call api... Nhưng cú pháp thuật toán em vẫn chưa biết nên xử lý ntn, mong nhận được sự giúp đỡ từ mn ^^ em cảm ơn!

1 ANSWERS


Answered Aug 1st, 4:42 a.m.
Accepted
+1

Bạn tham khảo thử cách sau.

Ví dụ Strapi API bạn có route /api/movies để lấy danh sách phim từ Strapi. Khi call API thì nhận được content dạng như:

{
  "data": [
    {
      "id": 1,
      "attributes": {
        "name": "The Terminator",
        "slug": "the-terminator",
        "description": "Super robot saves the world from evil AI",
        "locale": "en"
      }
    }
  ]
}

Danh sách phim đã được đa ngữ sẽ có 2 route /api/movies?locale=en (EN) và /api/movies?locale=vi (VI). Route VI của bạn sẽ có dạng như:

{
  "data": [
    {
      "id": 1,
      "attributes": {
        "name": "Kẻ hủy diệt",
        "slug": "ke-huy-diet",
        "description": "Siêu người máy giải cứu khỏi bọn AI xấu xa",
        "locale": "vi"
      }
    }
  ]
}

Như bạn thấy thì chỉ có phần content được thay đổi cho đa ngữ, các attribute key như name, description vẫn giống nhau, nên trong Vue component, sau khi mount, bạn chỉ việc gọi đến API route tương ứng rồi render dựa theo các key đó là được.

<template>
  <ul>
    <li v-for="movie in movies" :key="movie.id">
      <h2>{{ movie.name }}</h2>
      <p>{{ movie.description }}</p>
    </li>
  </ul>
</template>

<script>
export default {
  data() {
    return {
      movies: []
    };
  },
  async mounted() {
    const { data } = await fetch(`/api/movies?locale=${locale}`);
    this.movies = data;
  }
};
</script>

locale bạn có thấy truy xuất từ route nếu dùng vue router, hoặc từ prop của component, hoặc thậm chí từ localStorage.

Share
Avatar Phạm Duy Vũ @binchanhkun99
Aug 1st, 7:19 a.m.

@khangnd vâng ạ nhưng điều em chưa làm được ở đây chính là cái locale ở router ấy a, thực tế em chưa làm bh ạ, bh em sẽ có 1 cái dropdown và 2 cái lá cờ click vào cờ Anh thì sẽ có thêm cái /en phía sau và load lại hết nội dung của web lun ấy ạ... Câu trả lời của anh chi tiết quá em cảm ơn nhiều nếu được anh có thể chỉ dẫn e lm luôn cái router kia đc ko ạ, em xin gửi anh ly cf với ạ ^^ một lần nữa em cảm ơn nhiều

0
| Reply
Share
Avatar Khang @khangnd
Aug 1st, 10:33 a.m.

@binchanhkun99 Mình ko rõ bạn đang dùng Vue + Vue Router version mấy với cũng lâu rồi ko code Vue 😄 nhưng nhìn chung thì ý tưởng vẫn là bạn quy định format của route như thế nào thì bạn cứ dựa vào đó mà truy xuất locale (keyword ở đây là "dynamic routing"). Ví dụ như trang danh sách phim của bạn có route dạng /movies/en hay /movies/vi, thì format sẽ là /movies/:locale, rồi trong component bạn muốn truy xuất locale thì chỉ việc gọi this.$route.params.locale.

Bạn có thể đọc thêm tại https://router.vuejs.org/guide/essentials/dynamic-matching.html. Bạn cứ đặt câu hỏi trên này, mn có thời gian thì sẽ giải đáp cho, còn hướng dẫn 1-1 thì chắc là khó 🙂

0
| Reply
Share
Avatar Phạm Duy Vũ @binchanhkun99
Aug 2nd, 12:57 a.m.

@khangnd e đang xài Vue 2 và Vue router 3.2 thôi a ạ, em muốn hỏi thêm anh là ví dụ như em đang xài cái dynamic routing này để làm luôn thanh menu thì sẽ có thêm một trường ở trong tag router link là 'exact' để làm cái mặc định nó sáng màu vậy giờ em lm đa ngôn ngữ chắc e sẽ phải dùng v-for v thì lmsao để set cho thằng đầu tiên luôn có thuộc tính exact đc ạ? Em cảm ơn

0
| Reply
Share
Avatar Phạm Duy Vũ @binchanhkun99
Aug 2nd, 1:13 a.m.
Avatar Phạm Duy Vũ @binchanhkun99
Aug 2nd, 1:15 a.m.
Avatar Phạm Duy Vũ @binchanhkun99
Aug 2nd, 1:17 a.m.
Avatar Phạm Duy Vũ @binchanhkun99
Aug 2nd, 1:42 a.m.

Ui em đã làm đc cho trang chủ rồi a, nhưng ví dụ em muốn vào một trang khác nhưng nó vẫn giữ nguyên cái ngôn ngữ khi mà em bấm chọn ở trang chủ thì em phải làm ntn ạ? thanks a ^^ image.png

0
| Reply
Share
Avatar Khang @khangnd
Aug 2nd, 2:45 a.m.

@binchanhkun99 bạn có thể xử lý trong hàm beforeEach của router (docs tham khảo). Hàm này được trigger mỗi khi bạn điều hướng đi bất kì trang nào, thường được sử dụng để xử lý authentication, nhưng bạn cũng có thể tận dụng để xử lý giữ nguyên ngôn ngữ từ trang hiện tại sang trang khác.

router.beforeEach((to, from, next) => {
  next({ 
    name: to.name,
    params: { locale: from.params.locale || 'en' }
  })
});
0
| Reply
Share
Avatar Phạm Duy Vũ @binchanhkun99
Aug 2nd, 3:19 a.m.

@khangnd Dạ vâng ạ, nhưng ví dụ em từ trang chủ muốn sang trang tuyển dụng thì phải làm như thế nào v anh? ._. image.png

0
| Reply
Share
Viblo
Let's register a Viblo Account to get more interesting posts.