Vuex

使用 Vuex 来完成我们的数据全局交互

下载vuex

1
npm install --save vuex

在根目录新建一个文件夹,创建 store.js文件,编辑公共内容,然后在main.js里引用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
// state 类似 data
//这里面写入数据
filter: 'all',
todos:[
{title: '吃饭饭',completed: true,editing: false},
{title: '睡觉觉',completed: false,editing: false},
{title: '打豆豆',completed: false,editing: false},
{title: '我不是豆豆!',completed: true,editing: false},
],
},
getters:{
// mutations 类似methods
// 写方法对数据做出更改(同步操作)
todosCount: (state) => {//foot
return state.todos.length
},
hasCompleted: (state) => {//foot
return state.todos.some(data => data.completed)
},
allCompleted: (state) => {//list
return state.todos.every(data => data.completed)
}
},
mutations: {
// getters 类似 computed
// 在这里面写个方法
changeFilter (state, filter) {//todoVue
state.filter = filter
},
create (state, todo) {//head
state.todos.push(todo)
},
removeCompleted (state) {//foot
state.todos = state.todos.filter(data => !data.completed)
},
},
actions: {
// actions 类似methods
// 写方法对数据做出更改(异步操作)
}
})

然后在 main.js引用

1
2
3
4
mport Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

通过在根实例中注册 store 选项,该 store 实例会注入到根组件下的所有子组件中,且子组件能通过 this.$store 访问到

修改Todos.vue的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<template>
<section class="todoapp" v-cloak>
<the-header />
<the-list />
<the-footer />
</section>
</template>

<script>
import '@/assets/base.css';
import '@/assets/index.css';
import TheHeader from '@/components/TheHeader.vue';
import TheList from '@/components/TheLister.vue';
import TheFooter from '@/components/TheFooter.vue';

export default{
created() {
this.fetchFilter();
},
watch: {
'$route': 'fetchFilter'
},
methods: {
fetchFilter: function() {
let filter = this.$route.params.id || 'all';
this.$store.commit('changeFilter', filter)
},
changeFilter (key, event) {//项目筛选
this.filter = key
},
},
components: {
'the-header': TheHeader,
'the-list': TheList,
'the-footer': TheFooter,
},
}
</script>

把组件内的内容用stort连接

TheHeader.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<template>
<header class="header">
<h1>极客 todos</h1>
<input class="new-todo" placeholder="What are you 弄啥咧?" autofocus @keyup.enter="create" v-model="value">
</header>
</template>
<script>
export default{
name:'TheHeader',
data() {
return {
value: ''
}
},
methods:{
create:function(){
this.$store.commit('create',{
title: this.value,
completed: false
})
this.value='';
},
},
}
</script>

TheList.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<template>
<section class="main">
<input class="toggle-all" id="toggle-all" type="checkbox" :checked="chooseAll">
<label for="toggle-all" @click="toggleAll">Mark all as complete</label>
<ul class="todo-list">
<li v-for="(item,index) in show" :class="[item.completed && 'completed', item.editing && 'editing']">
<div class="view">
<input class="toggle" type="checkbox" :checked="item.completed" @click="toggleCompleted(index)"/>
<label @dblclick="editingMode(index,$event)">{{item.title}}</label>
<button class="destroy" @click="destroy(index)"></button>
</div>
<input class="edit" v-model="item.title"
@blur="doneEdit(item)"
@keyup.enter="doneEdit(item)" >
</li>
</ul>
</section>
</template>
<script>
export default{
name:'TheList',
data:function(){
return{
}
},
computed:{
todos() {
return this.$store.state.todos
},
filter() {
return this.$store.state.filter
},
show(){
let filter = this.filter;
let todos = this.todos.filter( data => {
if(filter === 'all'){
return data
}else if( filter === 'await'){
return !data.completed
}else if( filter === 'achieve'){
return data.completed
}
})
return todos
},
chooseAll(){
return this.todos.every(data => data.completed);
},
},
methods: {
changeFilter (key, event) { //点击切换
this.filter = key
},
toggleCompleted(index){//点击切换状态
this.todos[index]['completed'] = !this.todos[index]['completed']
},
editingMode(index,event){//编辑内容
this.todos[index]['editing'] = true
this.editeIndex = index;
},
doneEdit(item){//编辑内容后回车确认
item.editing = false;
this.editeIndex = null;
},
toggleAll(e){//全选的
let chooseAll = this.chooseAll;
let crr=this.todos.forEach( data => data.completed = !chooseAll);
this.$emit('toggleAll',crr)
},
destroy(index){// 删除个体todos
this.todos.splice(index,1)
},
},
}
</script>

TheFooter.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<template>
<footer class="footer" v-show="todosCount">
<span class="todo-count"><strong>{{todosCount}}</strong> 总数</span>
<ul class="filters">
<li>
<router-link to="/all" :class="{selected: filter === 'all'}" >全部</router-link>
</li>
<li>
<router-link to="/await" :class="{selected: filter === 'await'}">待办</router-link>
</li>
<li>
<router-link to="/achieve" :class="{selected: filter === 'achieve'}">已完成</router-link>
</li>
</ul>
<button class="clear-completed" v-show="hasCompleted" @click="removeCompleted">清除已完成</button>
</footer>
</template>
<script>
export default{
name: 'TheFooter',
data () {
return {
}
},
props: {
todos: {
type: Array,
default: () => {
return []
}
},
},
computed: {
filter() {
return this.$store.state.filter
},
todosCount() {
return this.$store.getters.todosCount
},
hasCompleted() {
return this.$store.getters.hasCompleted
},
},
methods: {
removeCompleted: function() {
this.$store.commit('removeCompleted')
}
},
}
</script>

大功告成,无Bug无报错