mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-30 09:27:13 +00:00
commit
d7de8bf458
94
examples/vuex-store-2/README.md
Normal file
94
examples/vuex-store-2/README.md
Normal file
@ -0,0 +1,94 @@
|
||||
# Nuxt.js with Vuex 2
|
||||
|
||||
> Using a store to manage the state is important to every big application, that's why nuxt.js implement Vuex in its core.
|
||||
|
||||
> Alternative way of creating a store modularly.
|
||||
|
||||
## Activating the store
|
||||
|
||||
Nuxt.js will look for the `./store/` directory, if it exists, its will import and use Vuex. If there is no `./store/index.js` file that returns a store, Nuxt.js will go through all files of the `./store/` directory and create a store with a module for each file (`./store/index.js` being "root" module).
|
||||
|
||||
## Create the store folder
|
||||
|
||||
Let's create a file `store/index.js`:
|
||||
|
||||
```js
|
||||
export const state = { counter: 0 }
|
||||
|
||||
export const mutations = {
|
||||
increment (state) {
|
||||
state.counter++
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
and
|
||||
`store/todos.js`:
|
||||
|
||||
```js
|
||||
export const state = {
|
||||
list: []
|
||||
}
|
||||
|
||||
export const mutations = {
|
||||
add (state, { text }) {
|
||||
state.list.push({
|
||||
text,
|
||||
done: false
|
||||
})
|
||||
},
|
||||
|
||||
delete (state, { todo }) {
|
||||
state.list.splice(state.list.indexOf(todo), 1)
|
||||
},
|
||||
|
||||
toggle (state, { todo }) {
|
||||
todo.done = !todo.done
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> We don't need to install `Vuex` since it's shipped with nuxt.js
|
||||
|
||||
## Voilà !
|
||||
|
||||
We can now use `this.$store` inside our `.vue` files.
|
||||
|
||||
```html
|
||||
<template>
|
||||
<button @click="$store.commit('increment')">{{ $store.state.counter }}</button>
|
||||
</template>
|
||||
```
|
||||
|
||||
The store will be as such:
|
||||
```js
|
||||
new Vuex.Store({
|
||||
state: { counter: 0 },
|
||||
mutations: {
|
||||
increment (state) {
|
||||
state.counter++
|
||||
}
|
||||
},
|
||||
modules: {
|
||||
todos: {
|
||||
state: {
|
||||
list: []
|
||||
},
|
||||
mutations: {
|
||||
add (state, { text }) {
|
||||
state.list.push({
|
||||
text,
|
||||
done: false
|
||||
})
|
||||
},
|
||||
delete (state, { todo }) {
|
||||
state.list.splice(state.list.indexOf(todo), 1)
|
||||
},
|
||||
toggle (state, { todo }) {
|
||||
todo.done = !todo.done
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
11
examples/vuex-store-2/package.json
Normal file
11
examples/vuex-store-2/package.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "nuxt-vuex-store",
|
||||
"dependencies": {
|
||||
"nuxt": "latest"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "nuxt",
|
||||
"build": "nuxt build",
|
||||
"start": "nuxt start"
|
||||
}
|
||||
}
|
8
examples/vuex-store-2/pages/about.vue
Normal file
8
examples/vuex-store-2/pages/about.vue
Normal file
@ -0,0 +1,8 @@
|
||||
<template>
|
||||
<div>
|
||||
<p>
|
||||
<button @click="$store.commit('increment')">{{ $store.state.counter }}</button><br>
|
||||
<nuxt-link to="/">Home</nuxt-link>
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
29
examples/vuex-store-2/pages/index.vue
Normal file
29
examples/vuex-store-2/pages/index.vue
Normal file
@ -0,0 +1,29 @@
|
||||
<template>
|
||||
<div>
|
||||
<p>
|
||||
<button @click="increment">{{ counter }}</button>
|
||||
<br>
|
||||
<nuxt-link to="/about">About</nuxt-link>
|
||||
<br>
|
||||
<nuxt-link to="/todos">Todos</nuxt-link>
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
// fetch(context) is called by the server-side
|
||||
// and nuxt before instantiating the component
|
||||
fetch ({ store }) {
|
||||
store.commit('increment')
|
||||
},
|
||||
computed: mapState([
|
||||
'counter'
|
||||
]),
|
||||
methods: {
|
||||
increment () { this.$store.commit('increment') }
|
||||
}
|
||||
}
|
||||
</script>
|
41
examples/vuex-store-2/pages/todos.vue
Normal file
41
examples/vuex-store-2/pages/todos.vue
Normal file
@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<div>
|
||||
<h2>Todos</h2>
|
||||
<input placeholder="What needs to be done?" @keyup.enter="addTodo">
|
||||
<ul>
|
||||
<li v-for="todo in todos">
|
||||
<input type="checkbox" :checked="todo.done" @change="toggle({ todo })">
|
||||
<label v-text="todo.text" @dblclick="editing = true"></label>
|
||||
</li>
|
||||
</ul>
|
||||
<nuxt-link to="/">Home</nuxt-link>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapMutations } from 'vuex'
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
todos () { return this.$store.state.todos.list }
|
||||
},
|
||||
methods: {
|
||||
addTodo (e) {
|
||||
var text = e.target.value
|
||||
if (text.trim()) {
|
||||
this.$store.commit('todos/add', { text })
|
||||
}
|
||||
e.target.value = ''
|
||||
},
|
||||
...mapMutations({
|
||||
toggle: 'todos/toggle'
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
li {
|
||||
list-style: none;
|
||||
}
|
||||
</style>
|
7
examples/vuex-store-2/store/index.js
Normal file
7
examples/vuex-store-2/store/index.js
Normal file
@ -0,0 +1,7 @@
|
||||
export const state = { counter: 0 }
|
||||
|
||||
export const mutations = {
|
||||
increment (state) {
|
||||
state.counter++
|
||||
}
|
||||
}
|
20
examples/vuex-store-2/store/todos.js
Normal file
20
examples/vuex-store-2/store/todos.js
Normal file
@ -0,0 +1,20 @@
|
||||
export const state = {
|
||||
list: []
|
||||
}
|
||||
|
||||
export const mutations = {
|
||||
add (state, { text }) {
|
||||
state.list.push({
|
||||
text,
|
||||
done: false
|
||||
})
|
||||
},
|
||||
|
||||
delete (state, { todo }) {
|
||||
state.list.splice(state.list.indexOf(todo), 1)
|
||||
},
|
||||
|
||||
toggle (state, { todo }) {
|
||||
todo.done = !todo.done
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ require('es6-object-assign').polyfill()
|
||||
import Vue from 'vue'
|
||||
import Meta from 'vue-meta'
|
||||
import router from './router.js'
|
||||
<% if (store) { %>import store from '~store/index.js'<% } %>
|
||||
<% if (store) { %>import store from './store.js'<% } %>
|
||||
import NuxtChild from './components/nuxt-child.js'
|
||||
import NuxtLink from './components/nuxt-link.js'
|
||||
import Nuxt from './components/nuxt.vue'
|
||||
|
47
lib/app/store.js
Normal file
47
lib/app/store.js
Normal file
@ -0,0 +1,47 @@
|
||||
import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
Vue.use(Vuex)
|
||||
|
||||
let files
|
||||
let filenames = []
|
||||
|
||||
try {
|
||||
files = require.context('~store', false, /^\.\/.*\.js$/)
|
||||
filenames = files.keys()
|
||||
} catch (e) {
|
||||
console.warn('Nuxt.js store:', e.message)
|
||||
}
|
||||
|
||||
function getModule (filename) {
|
||||
let file = files(filename)
|
||||
return file.default
|
||||
? file.default
|
||||
: file
|
||||
}
|
||||
|
||||
let store
|
||||
let storeData = {}
|
||||
|
||||
// Check if store/index.js returns a vuex store
|
||||
if (filenames.indexOf('./index.js') !== -1) {
|
||||
let mainModule = getModule('./index.js')
|
||||
if (mainModule.commit) {
|
||||
store = mainModule
|
||||
} else {
|
||||
storeData = mainModule
|
||||
}
|
||||
}
|
||||
|
||||
// Generate the store if there is no store yet
|
||||
if (store == null) {
|
||||
storeData.modules = storeData.modules || {}
|
||||
for (let filename of filenames) {
|
||||
let name = filename.replace(/^\.\//, '').replace(/\.js$/, '')
|
||||
if (name === 'index') continue
|
||||
storeData.modules[name] = getModule(filename)
|
||||
storeData.modules[name].namespaced = true
|
||||
}
|
||||
store = new Vuex.Store(storeData)
|
||||
}
|
||||
|
||||
export default store
|
@ -191,6 +191,10 @@ function * generateRoutesAndFiles () {
|
||||
templatesFiles.push('layouts/default.vue')
|
||||
layouts.default = r(__dirname, 'app', 'layouts', 'default.vue')
|
||||
}
|
||||
// Add store if needed
|
||||
if (this.options.store) {
|
||||
templatesFiles.push('store.js')
|
||||
}
|
||||
let moveTemplates = templatesFiles.map((file) => {
|
||||
return readFile(r(__dirname, 'app', file), 'utf8')
|
||||
.then((fileContent) => {
|
||||
|
@ -51,7 +51,7 @@ class Nuxt {
|
||||
this.dir = (typeof options.rootDir === 'string' && options.rootDir ? options.rootDir : process.cwd())
|
||||
this.srcDir = (typeof options.srcDir === 'string' && options.srcDir ? resolve(this.dir, options.srcDir) : this.dir)
|
||||
// If store defined, update store options to true
|
||||
if (fs.existsSync(join(this.srcDir, 'store', 'index.js'))) {
|
||||
if (fs.existsSync(join(this.srcDir, 'store'))) {
|
||||
this.options.store = true
|
||||
}
|
||||
// Template
|
||||
|
Loading…
Reference in New Issue
Block a user