开场白
开始使用
API
- API: The <client-only> Component
- API: <nuxt-child> 组件
- API: <nuxt-link> 组件
- API: <nuxt> 组件
- API: 构建配置
- API: buildDir 属性
- API: 缓存配置
- API: CSS 配置
- API: dev 属性配置
- API: dir 属性
- API: 环境变量配置
- API: generate 属性配置
- API: globalName 属性
- API: head 属性配置
- API: The hooks Property
- API: ignore 属性
- API: The loading indicator Property
- API: loading 属性配置
- API: The mode Property
- API: modern 属性
- API: modules 属性
- API: modulesDir 属性
- API: performance 属性
- API: plugins 属性配置
- API: The render Property
- API: rootDir 属性配置
- API: router 属性配置
- API: server 属性
- API: serverMiddleware 属性
- API: srcDir 属性配置
- API: transition 属性配置
- API: vue.config 属性
- API: watch 属性
- API: watchers 属性
- API: 上下文对象
- API: asyncData 方法
- API: The Builder Class
- API: The Generator Class
- API: The ModuleContainer Class
- API: The Nuxt Class
- API: The Renderer Class
- API: Nuxt Modules Intro
- API: nuxt.renderAndGetWindow(url, options)
- API: nuxt.renderRoute(route, context)
- API: nuxt.render(req, res)
- API: Nuxt(options)
- API: fetch 方法
- API: head 方法
- API: key 属性
- API: layout 属性
- API: loading 属性
- API: middleware 属性
- API: scrollToTop 属性
- API: transition 属性
- API: validate 方法
- API: The watchQuery Property
配置
- 外部资源
- 预处理器
- JSX
- Postcss 插件
- 如何扩展 Webpack 的配置
- Webpack 插件
- Caching Components
- 如何更改应用的主机和端口配置?
- 如何集成 Google 统计分析服务?
- 如何发起跨域资源请求?
- How to extend Webpack to load audio files?
部署
- 如何使用 Now.sh 进行部署?
- 使用 Surge.sh 部署
- 在 Google App Engine 上部署
- Netlify 部署
- AWS: S3+Cloudfront 部署
- Dokku 部署
- nginx 代理
- 如何部署至 GitHub Pages?
- 部署至 Heroku
其他
Vuex 状态树
对于每个大项目来说,使用状态树 (store) 管理状态 (state) 十分有必要。这就是为什么 Nuxt.js 内核实现了 Vuex。
在Vue School 上观看关于Nuxt.js 和 Vuex 的免费课程
使用状态树
Nuxt.js 会尝试找到应用根目录下的 store
目录,如果该目录存在,它将做以下的事情:
- 引用
vuex
模块 - 将
vuex
模块 加到 vendors 构建配置中去 - 设置
Vue
根实例的store
配置项
Nuxt.js 支持两种使用 store
的方式,你可以择一使用:
模块方式:
store
目录下的每个.js
文件会被转换成为状态树指定命名的子模块 (当然,index
是根模块)Classic(不建议使用):
store/index.js
返回创建Vuex.Store实例的方法。
无论使用那种模式,您的state
的值应该始终是function
,为了避免返回引用类型,会导致多个实例相互影响。
普通方式
Nuxt.js允许您拥有一个
store
目录,其中包含与模块对应的每个文件。
首先,只需将状态导出为 函数,将变量和操作作为 store/index.js
中的对象导出:
export const state = () => ({
counter: 0
})
export const mutations = {
increment (state) {
state.counter++
}
}
然后,您可以拥有 store/todos.js
文件:
export const state = () => ({
list: []
})
export const 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
}
}
Vuex将如下创建:
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
}
}
}
}
})
在您的 pages/todos.vue
中,使用 todos
模块:
<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>
模块方法也适用于顶级定义,而无需在
store
目录中实现子目录
示例:您创建文件 store/state.js
并添加以下内容
export default () => ({
counter: 0
})
相应的可以在文件夹中添加 store/mutations.js
export default {
increment (state) {
state.counter++
}
}
模块文件
您可以将模块文件分解为单独的文件:state.js
,actions.js
,mutations.js
和getters.js
。如果您使用index.js
来维护state
,getters
,actions
和mutations
,同时具有单个单独的操作文件,那么仍然可以正确识别该文件。
注意:在使用拆分文件模块时,必须记住使用箭头函数功能,
this
在词法上可用。词法范围this
意味着它总是指向引用箭头函数的所有者。如果未包含箭头函数,那么this
将是未定义的(undefined
)。解决方案是使用 "normal" 功能,该功能会将this
指向自己的作用域,因此可以使用。
插件
您可以将其他插件添加到store(在模块模式下),将其放入store/index.js
文件中:
import myPlugin from 'myPlugin'
export const plugins = [ myPlugin ]
export const state = () => ({
counter: 0
})
export const mutations = {
increment (state) {
state.counter++
}
}
有关插件的更多信息: Vuex 文档.
fetch 方法
fetch 方法会在渲染页面前被调用,作用是填充状态树 (store) 数据,与 asyncData 方法类似,不同的是它不会设置组件的数据。
关于 fetch
方法的更多信息,请参考 页面 fetch 方法API。
nuxtServerInit 方法
如果在状态树中指定了 nuxtServerInit
方法,Nuxt.js 调用它的时候会将页面的上下文对象作为第2个参数传给它(服务端调用时才会酱紫哟)。当我们想将服务端的一些数据传到客户端时,这个方法是灰常好用的。
举个例子,假设我们服务端的会话状态树里可以通过 req.session.user
来访问当前登录的用户。将该登录用户信息传给客户端的状态树,我们只需更新 store/index.js
如下:
actions: {
nuxtServerInit ({ commit }, { req }) {
if (req.session.user) {
commit('user', req.session.user)
}
}
}
如果你使用_状态树模块化_的模式,只有主模块(即
store/index.js
)适用设置该方法(其他模块设置了也不会被调用)。
这时context被赋予nuxtServerInit
作为第二个参数,它与asyncData
或fetch
方法相同。
nuxtServerInit
方法接收的上下文对象和 fetch
的一样,但不包括 context.redirect()
和 context.error()
。
注意:异步
nuxtServerInit
操作必须返回Promise来通知nuxt
服务器等待它们。
actions: {
async nuxtServerInit({ dispatch }) {
await dispatch('core/load')
}
}
Vuex 严格模式
默认情况下,在开发模式下启用严格模式,在生产模式下关闭模式。要在dev中禁用严格模式,请遵循以下示例。
Module Mode
export const strict = false
经典模式
此功能已经弃用,将在Nuxt 3中删除。
要使用经典模式创建Vuex,我们应该创建store/index.js
到处返回Vuex实例的方法的文件:
import Vuex from 'vuex'
const createStore = () => {
return new Vuex.Store({
strict: false,
state: () => ({
counter: 0
}),
mutations: {
increment (state) {
state.counter++
}
}
})
}
export default createStore
我们不需要安装,因为Vuex由Nuxt.js提供。
我们现在可以在我们的组件中使用this.$store
:
<template>
<button @click="$store.commit('increment')">{{ $store.state.counter }}</button>
</template>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论