main.js
import Vue from 'vue'
import App from './App.vue'
import store from './store'
Vue.config.productionTip = false
// 程序中的vue实例
new Vue({
// this.$store
store,
render: h => h(App)
}).$mount('#app')
Todo.vue
<template>
<div>
<!-- 输入框 -->
<div class="form-group mt-5">
<label for></label>
<input
v-model="task"
type="text"
class="form-control"
name
id
aria-describedby="helpId"
:placeholder="$store.state.input_hint"
/>
</div>
<!-- 按钮 -->
<button @click="newTask" type="button" name id class="btn btn-primary btn-lg btn-block">创建</button>
</div>
</template>
<script>
export default {
name: "Todo",
data() {
return {
// 数据 state(状态)
task: ""
};
},
methods: {
newTask: function() {
// vue原始
// this.$emit("event",this.task);
// vuex 不推荐,子组件直接操作状态
// this.$store.state.todos.unshift(this.task);
// vuex推荐的 mutation操作数据的状态
// 1.回调
// 2.负载的数据(对象)
this.$store.commit("createTask", this.task);
// this.$store.commit("createTask",
// {
// a: 1,
// b: 2,
// info: this.task
// }
// );
// 组件中的方法修改状态 store.state
// 提交到变化,突变
// 1.简单的·同步场景
// this.$store.commit("mutation");
// 2.复杂的所有场景,包含了1
// 分发到动作,行为
// this.$store.dispatch("action");
}
}
};
</script>
List.vue
<template>
<ul class="list-group mt-5">
<li v-for="(item, index) in list" :key="index" class="list-group-item">{{item}}</li>
</ul>
</template>
<script>
export default {
name: "List",
data() {
return {};
},
methods: {},
computed: {
list:function(){
// this 当vue实例
return this.$store.state.todos;
}
},
};
</script>
App.vue
<template>
<div class="container">
<div class="jumbotron">
<!--方案一: 直接访问状态:$store.state -->
<h1 class="display-3">{{$store.state.title}}</h1>
<!--方案二: 通过getters方式:$$store.getters -->
<h1 class="display-3">{{$store.getters.titleInfo}}</h1>
<!-- 方案三:在方案二的基础上 mapGetter -->
<h1 class="display-3">{{titleInfo}}</h1>
<h1 class="display-3">{{appTitle}}</h1>
</div>
<Todo />
<List />
</div>
</template>
<script>
// import HelloWorld from './components/HelloWorld.vue'
import Todo from "./components/Todo";
import List from "./components/List";
// 导入getters映射
import {mapGetters} from 'vuex';
export default {
name: "App",
components: {
Todo,
List,
},
data() {
return {
// 数据 state(状态)
}
},
computed: mapGetters([
// 通过映射,变得更简洁
"appTitle",
"titleInfo"
]
)
};
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
index.js
import Vue from 'vue'
import Vuex from 'vuex'
// Vue启用Vuex插件,进行集中式的状态管理
Vue.use(Vuex)
export default new Vuex.Store({
// 状态(集中所有组件的状态数据)
// 状态是响应式(双向绑定)
state: {
title: "备忘录-Vue实现",
input_hint: "今日事今日毕",
todos: ["起床", "吃饭"],
},
// 同步执行的操作
mutations: {
createTask(state,data){
// 回调
state.todos.push(data);
}
},
// 可以包含多个mutations的异步操作,推荐使用actions
actions: {
},
// 模块化状态管理(拆分成多个文件分别维护和管理)
modules: {
},
// 读取状态信息
getters: {
// 函数定义
appTitle: function (state) {
return state.title;
},
// 箭头函数,一个参数时,括号可选
titleInfo: state => {
return state.title;
}
}
})
index.html
<!doctype html>
<html lang="en">
<head>
<title>Vue备忘录</title>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body>
<div id="app"></div>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>
效果如图所示: