VueJS: Vuex Store
Giải phóng thời gian, khai phóng năng lực
Sử dụng một store để quản lý state rất quan trọng đối với mọi ứng dụng lớn. Đó là lý do tại sao Nuxt.js triển khai Vuex trong cốt lõi của nó.
Kích hoạt Store
Nuxt.js sẽ tìm thư mục store
, nếu nó tồn tại, nó sẽ:
- import Vuex,
- Thêm tùy chọn
store
vào ví dụ Vue gốc.
Nuxt.js cho phép bạn quyết định giữa 2 chế độ lưu trữ . Bạn có thể chọn cái bạn thích:
- Các mô-đun: mọi
.js
tệp trongstore
thư mục được chuyển đổi dưới dạng một mô-đun không gian tên (index
là mô-đun gốc). - Classic ( deprecated ):
store/index.js
trả về một phương thức để tạo một thể hiện cửa hàng.
Bất kể chế độ nào, state
giá trị của bạn phải luôn làfunction
để tránh trạng thái chia sẻ không mong muốn ở phía máy chủ.
Chế độ mô-đun
Nuxt.js cho phép bạn có một
store
thư mục với mỗi tệp tương ứng với một mô-đun.
Để bắt đầu, chỉ cần xuất trạng thái dưới dạng hàm và các đột biến và hành động dưới dạng đối tượng trong store/index.js
:
export const state = () => ({
counter: 0
})
export const mutations = {
increment (state) {
state.counter++
}
}
Sau đó, bạn có thể có một store/todos.js
tệp:
export const state = () => ({
list: []
})
export const mutations = {
add (state, text) {
state.list.push({
text: text,
done: false
})
},
remove (state, { todo }) {
state.list.splice(state.list.indexOf(todo), 1)
},
toggle (state, todo) {
todo.done = !todo.done
}
}
Cửa hàng sẽ được tạo như vậy:
new Vuex.Store({
state: () => ({
counter: 0
}),
mutations: {
increment (state) {
state.counter++
}
},
modules: {
todos: {
namespaced: true,
state: () => ({
list: []
}),
mutations: {
add (state, { text }) {
state.list.push({
text,
done: false
})
},
remove (state, { todo }) {
state.list.splice(state.list.indexOf(todo), 1)
},
toggle (state, { todo }) {
todo.done = !todo.done
}
}
}
}
})
Và trong của bạn pages/todos.vue
, sử dụng todos
mô-đun:
<template>
<ul>
<li v-for="todo in todos">
<input type="checkbox" :checked="todo.done" @change="toggle(todo)">
<span :class="{ done: todo.done }">{{ todo.text }}</span>
</li>
<li><input placeholder="What needs to be done?" @keyup.enter="addTodo"></li>
</ul>
</template>
<script>
import { mapMutations } from 'vuex'
export default {
computed: {
todos () {
return this.$store.state.todos.list
}
},
methods: {
addTodo (e) {
this.$store.commit('todos/add', e.target.value)
e.target.value = ''
},
...mapMutations({
toggle: 'todos/toggle'
})
}
}
</script>
<style>
.done {
text-decoration: line-through;
}
</style>
Phương thức mô-đun cũng hoạt động cho các định nghĩa cấp cao nhất mà không thực hiện một thư mục con trong
store
thư mục
Ví dụ cho trạng thái: bạn tạo một tệp store/state.js
và thêm vào như sau
export default () => ({
counter: 0
})
Và các đột biến tương ứng có thể có trong tệp store/mutations.js
export default {
increment (state) {
state.counter++
}
}
Tập tin mô-đun
Bạn có thể tùy chọn phá vỡ một tập tin mô-đun vào các tập tin riêng biệt: state.js
, actions.js
, mutations.js
và getters.js
. Nếu bạn duy trì một index.js
tệp có trạng thái, getters và đột biến trong khi có một tệp riêng cho các hành động, thì nó vẫn sẽ được nhận dạng đúng.
Lưu ý: Trong khi sử dụng các mô-đun chia tệp, bạn phải nhớ rằng sử dụng các hàm mũi tên,
this
chỉ có sẵn về mặt từ vựng. Phạm vi từ vựng đơn giản có nghĩa làthis
luôn luôn tham chiếu chủ sở hữu của hàm mũi tên. Nếu chức năng mũi tên không được chứa thìthis
sẽ không được xác định. Giải pháp là sử dụng chức năng "bình thường" tạo ra phạm vi riêng và do đó cóthis
sẵn.
bổ sung
Bạn có thể thêm các bổ sung vào cửa hàng (ở chế độ mô-đun) bằng cách đưa chúng vào store/index.js
tệp:
import myPlugin from 'myPlugin'
export const plugins = [ myPlugin ]
export const state = () => ({
counter: 0
})
export const mutations = {
increment (state) {
state.counter++
}
}
Thông tin thêm về các plugin: Tài liệu Vuex .
Phương pháp tìm nạp
Các
fetch
phương pháp được sử dụng để điền vào các cửa hàng trước khi render trang, nó giống như cácasyncData
phương pháp trừ nó không thiết lập các dữ liệu thành phần.
Thông tin thêm về phương pháp tìm nạp: Tìm nạp trang API .
Hành động nuxtServerInit
Nếu hành động nuxtServerInit
được xác định trong cửa hàng, Nuxt.js sẽ gọi nó với ngữ cảnh (chỉ từ phía máy chủ). Nó hữu ích khi chúng tôi có một số dữ liệu trên máy chủ mà chúng tôi muốn cung cấp trực tiếp cho phía khách hàng.
Ví dụ: giả sử chúng tôi có các phiên ở phía máy chủ và chúng tôi có thể truy cập người dùng được kết nối thông qua req.session.user
. Để cung cấp cho người dùng được xác thực vào cửa hàng của chúng tôi, chúng tôi cập nhật các thông tin store/index.js
sau:
actions: {
nuxtServerInit ({ commit }, { req }) {
if (req.session.user) {
commit('user', req.session.user)
}
}
}
Nếu bạn đang sử dụng chế độ Mô-đun của cửa hàng Vuex, chỉ mô-đun chính (trong
store/index.js
) sẽ nhận được hành động này. Bạn sẽ cần xâu chuỗi các hành động mô-đun của bạn từ đó.
Các bối cảnh được trao cho nuxtServerInit
như là đối số thứ 2, nó cũng giống như asyncData
hoặc fetch
phương pháp.
Lưu ý: Các
nuxtServerInit
hành động không đồng bộ phải trả lại Promise hoặc tận dụng async / await để cho phépnuxt
máy chủ chờ chúng.
actions: {
async nuxtServerInit({ dispatch }) {
await dispatch('core/load')
}
}
Chế độ nghiêm ngặt của Vuex
Chế độ nghiêm ngặt được bật theo mặc định trên chế độ dev và tắt trong chế độ sản xuất. Để tắt chế độ nghiêm ngặt trong dev, hãy làm theo ví dụ dưới đây trong store/index.js
:
export const strict = false
Chế độ cổ điển
Tính năng này không được dùng nữa và sẽ bị xóa trong Nuxt 3.
Để kích hoạt cửa hàng với chế độ cổ điển, chúng tôi tạo store/index.js
tệp sẽ xuất một phương thức trả về một thể hiện Vuex:
import Vuex from 'vuex'
const createStore = () => {
return new Vuex.Store({
state: () => ({
counter: 0
}),
mutations: {
increment (state) {
state.counter++
}
}
})
}
export default createStore
Chúng tôi không cần phải cài đặt
vuex
vì nó được phân phối với Nuxt.js.
Bây giờ chúng ta có thể sử dụng this.$store
bên trong các thành phần của mình:
<template>
<button @click="$store.commit('increment')">{{ $store.state.counter }}</button>
</template>
Giải phóng thời gian, khai phóng năng lực