Skip to content

Commit

Permalink
add: files for demo vuex
Browse files Browse the repository at this point in the history
  • Loading branch information
Thunf committed Feb 26, 2018
1 parent a9ebdb2 commit 17460a0
Show file tree
Hide file tree
Showing 12 changed files with 349 additions and 0 deletions.
8 changes: 8 additions & 0 deletions controller/vuex.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
'use strict';
exports.index = function*() {
yield this.bindDefault()

yield this.render('vuex', {
siteInfo: this.siteInfo
})
}
105 changes: 105 additions & 0 deletions vues/vuex/components/App.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<template>
<section class="todoapp">
<!-- header -->
<header class="header">
<h1>{{headerText}}</h1>
<input v-show="loaded" class="new-todo"
autofocus
autocomplete="off"
placeholder="What needs to be done?"
@keyup.enter="addTodo">
</header>
<!-- main section -->
<section class="main" v-show="todos.length">
<input class="toggle-all" id="toggle-all"
type="checkbox"
:checked="allChecked"
@change="toggleAll({ done: !allChecked })">
<label for="toggle-all"></label>
<ul class="todo-list">
<todo v-for="(todo, index) in filteredTodos" :key="index" :todo="todo"></todo>
</ul>
</section>
<!-- footer -->
<footer class="footer" v-show="todos.length">
<span class="todo-count">
<strong>{{ remaining }}</strong>
{{ remaining | pluralize('item') }} left
</span>
<ul class="filters">
<li v-for="(val, key) in filters">
<a :class="{ selected: visibility === key }"
@click="visibility = key">{{ key | capitalize }}</a>
</li>
</ul>
<button class="clear-completed"
v-show="todos.length > remaining"
@click="clearCompleted">
Clear completed
</button>
</footer>
</section>
</template>

<script>
import { mapMutations, mapGetters } from 'vuex'
import Todo from './Todo.vue'
export default {
components: { Todo },
data () {
return {
loaded: false,
visibility: 'all'
}
},
computed: {
...mapGetters([
'todos',
'filters',
'remaining',
'allChecked'
]),
headerText () {
return this.loaded ? 'todos' : 'Loading'
},
filteredTodos () {
return this.$store.getters.filteredTodos(this.visibility)
}
},
mounted () {
this.$store.dispatch('getStorageItems').then(() => {
this.loaded = true
})
},
methods: {
addTodo (e) {
if (!this.loaded) return
var text = e.target.value
if (text.trim()) {
this.$store.commit('addTodo', { text })
}
e.target.value = ''
},
...mapMutations([
'toggleAll',
'clearCompleted'
])
},
filters: {
pluralize: (n, w) => n === 1 ? w : (w + 's'),
capitalize: s => s.charAt(0).toUpperCase() + s.slice(1)
}
}
</script>

<style src="todomvc-app-css/index.css"></style>
<style lang="less">
.todoapp{
.header,
.footer{
user-select: none;
}
}
</style>
71 changes: 71 additions & 0 deletions vues/vuex/components/Todo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<template>
<li class="todo" :class="{ completed: todo.done, editing: editing }">
<div class="view">
<input class="toggle"
type="checkbox"
:checked="todo.done"
@change="toggleTodo({ todo: todo })">
<label v-text="todo.text"
@click="toggleTodo({ todo: todo })"
@dblclick="editing = true">
</label>
<button class="destroy" @click="deleteTodo({ todo: todo })"></button>
</div>
<input class="edit"
v-show="editing"
v-focus="editing"
:value="todo.text"
@keyup.enter="doneEdit"
@keyup.esc="cancelEdit"
@blur="doneEdit">
</li>
</template>

<script>
import { mapMutations } from 'vuex'
export default {
name: 'Todo',
props: ['todo'],
data () {
return {
editing: false
}
},
directives: {
focus (el, { value }, { context }) {
if (value) {
context.$nextTick(() => {
el.focus()
})
}
}
},
methods: {
...mapMutations([
'editTodo',
'toggleTodo',
'deleteTodo'
]),
doneEdit (e) {
const value = e.target.value.trim()
const { todo } = this
if (!value) {
this.deleteTodo({
todo
})
} else if (this.editing) {
this.editTodo({
todo,
value
})
this.editing = false
}
},
cancelEdit (e) {
e.target.value = this.todo.text
this.editing = false
}
}
}
</script>
34 changes: 34 additions & 0 deletions vues/vuex/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import Vuex from 'vuex'
import VueRouter from 'vue-router'
import VueResource from 'vue-resource'
import routes from './router.js'
import store from './store'
import App from './index.vue'

// 置入组件
Vue.use(Vuex)
Vue.use(VueRouter)
Vue.use(VueResource)

// 初始化
/* eslint-disable no-new */
new Vue({
/**
* 提供的元素只能作为挂载点。
* 不同于 Vue 1.x,所有的挂载元素会被 Vue 生成的 DOM 替换。
* 因此不推荐挂载root实例到 <html> 或者 <body> 上。
*/
el: '#app',
// vuex store
store: new Vuex.Store(store),
template: '<App/>',
components: { App },
/**
* 置入路由
*/
router: new VueRouter(routes)
})
/* eslint-enable no-new */
17 changes: 17 additions & 0 deletions vues/vuex/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<template>
<div id="vuex">
<router-view></router-view>
</div>
</template>

<script>
export default {
name: 'vuex'
}
</script>

<style lang="less">
#vuex{
/* some style */
}
</style>
9 changes: 9 additions & 0 deletions vues/vuex/router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
routes: [{
path: '/index',
component: require('./components/App.vue')
}, {
path: '*',
redirect: '/index'
}]
}
12 changes: 12 additions & 0 deletions vues/vuex/store/actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { STORAGE_KEY } from './state'

export const getStorageItems = ({ commit }) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
commit('init', {
list: JSON.parse(window.localStorage.getItem(STORAGE_KEY) || '[]')
})
resolve()
}, 1000)
})
}
23 changes: 23 additions & 0 deletions vues/vuex/store/getters.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export const filters = () => {
return {
all: todos => todos,
active: todos => todos.filter(todo => !todo.done),
completed: todos => todos.filter(todo => todo.done)
}
}

export const todos = state => {
return state.todos
}

export const allChecked = state => {
return state.todos.every(todo => todo.done)
}

export const remaining = state => {
return state.todos.filter(todo => !todo.done).length
}

export const filteredTodos = (state, getters) => visibility => {
return getters.filters[visibility](state.todos)
}
17 changes: 17 additions & 0 deletions vues/vuex/store/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { state } from './state'
import * as actions from './actions'
import * as getters from './getters'
import { mutations } from './mutations'
import plugins from './plugins'

export default {
strict: process.env.NODE_ENV !== 'production',
state,
getters,
mutations,
actions,
plugins,
modules: {
// some modules
}
}
34 changes: 34 additions & 0 deletions vues/vuex/store/mutations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
export const mutations = {
init (state, { list }) {
state.todos.push.apply(state.todos, list || [])
},

addTodo (state, { text }) {
state.todos.push({
text,
done: false
})
},

deleteTodo (state, { todo }) {
state.todos.splice(state.todos.indexOf(todo), 1)
},

toggleTodo (state, { todo }) {
todo.done = !todo.done
},

editTodo (state, { todo, value }) {
todo.text = value
},

toggleAll (state, { done }) {
state.todos.forEach((todo) => {
todo.done = done
})
},

clearCompleted (state) {
state.todos = state.todos.filter(todo => !todo.done)
}
}
9 changes: 9 additions & 0 deletions vues/vuex/store/plugins.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { STORAGE_KEY } from './state'

const localStoragePlugin = store => {
store.subscribe((mutation, { todos }) => {
window.localStorage.setItem(STORAGE_KEY, JSON.stringify(todos))
})
}

export default [localStoragePlugin]
10 changes: 10 additions & 0 deletions vues/vuex/store/state.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// for testing
if (navigator.userAgent.indexOf('PhantomJS') > -1) {
window.localStorage.clear()
}

export const STORAGE_KEY = 'todos-vuejs'

export const state = {
todos: []
}

0 comments on commit 17460a0

Please sign in to comment.