### vuex
### vuex传递数据的流程:
import Vue from "vue"; import Vuex from "vuex"; Vue.use(Vuex); const store=new Vuex.Store({ state:{ n:10 }, actions:{ handleActionsAdd({commit},params){ commit("handleMutationsAdd",params); } }, mutations:{ handleMutationsAdd(state,params){ state.n++; console.log(params) } } }); export default store;
import store from './store'; new Vue({ store, render: h => h(App) }).$mount('#app');
methods: { handleAdd(){ this.$store.dispatch("handleActionsAdd","wql"); } }
### vuex的底层原理
let Vue; function install(_Vue){ Vue=_Vue; Vue.mixin({// Vue.mixin()----给vue的当前组件扩展一些属性和方法 // 将store的实例挂在vue的实例身上 beforeCreate(){ if(this.$options.store){ Vue.prototype.$store = this.$options.store; } } }); } class Store{ constructor(options){ // 将state中的状态转换为响应式状态 this.state=new Vue({ data:options.state }); this.mutations=options.mutations||{};// 初始化mutations this.actions=options.actions||{};// 初始化actions options.getters&&this.handleGetters(options.getters);// 初始化getters } commit(eventName,params){ let fn=this.mutations[eventName]; fn(this.state,params); } dispatch(eventName,params){ let fn=this.actions[eventName]; // dispatch()是在组件中调用的,this执行那个组件,这里用bind()将this重新指向Store,bind()和call()、apply()的区别就是bind()应用于回调函数的绑定对象,在回调函数触发的时候执行,而call()、apply()会立即执行 fn({commit:this.commit.bind(this),dispatch:this.dispatch.bind(this),state:this.state},params); } handleGetters(getters){ let that=this; this.getters={}; Object.keys(getters).forEach(key=>{ // 这里的this指向的是Object,而我们需要让this指向当前的类Store,用that替换this。有的时候改变this指向需要用到bind(),bind()是用于回调函数的绑定this对象,当函数触发时执行,回调函数的绑定this不能用call()或apply(),因为它们俩会立即执行。 Object.defineProperty(that.getters,key,{ get:function(){ return getters[key](that.state); } }); }); } } export default {Store,install};
import Vuex from "vuex"; 可以改为 import Vuex from "../wql-vuex";
### vuex实现todolist
<template> <div> <!-- 这里的事件函数如果不写(),就是不传参数,此时在methods中方法可以接收到e对象;如果写了(),而没有手动传递$event,此时methods中方法无法接收到e对象 --> <input type="text" :value="$store.state.inputVal" @input="handleInput($event)"> <button @click="add">添加</button> </div> </template> <script> export default { name:"Input", methods: { handleInput(e){ this.$store.dispatch("handleActionsChange",e.target.value); }, add(){ this.$store.dispatch("handleActionsListAdd"); } }, } </script>
<template> <div> <ul> <li v-for="(item,index) in $store.state.list" :key="index">{{item}}</li> </ul> </div> </template>
import Vue from "vue"; import Vuex from "../wql-vuex"; Vue.use(Vuex); const store=new Vuex.Store({ state:{ inputVal:"", list:[] }, actions:{ handleActionsChange({commit},value){ commit("handleMutationsChange",value); }, handleActionsListAdd({commit}){ commit("handleMutationsListAdd"); } }, mutations:{ handleMutationsChange(state,params){ state.inputVal=params; }, handleMutationsListAdd(state){ state.list.push(state.inputVal); state.inputVal=""; } } }); export default store;
import InputVal from "components/InputVal.vue"; import List from "components/List.vue"; export default { name: "app", components: { One, Two, InputVal, List } };
<h1>todolist</h1> <InputVal></InputVal> <List></List>
export default { name:"Input", methods: { handleInput(e){ console.log(e) this.$store.commit("handleMutationsChange",e.target.value); // this.$store.dispatch("handleActionsChange",e.target.value); }, add(){ this.$store.commit("handleMutationsListAdd"); // this.$store.dispatch("handleActionsListAdd"); } } }
import Vue from "vue"; import Vuex from "../wql-vuex"; Vue.use(Vuex); const store=new Vuex.Store({ state:{ inputVal:"", list:[] }, mutations:{ handleMutationsChange(state,params){ state.inputVal=params; }, handleMutationsListAdd(state){ state.list.push(state.inputVal); state.inputVal=""; } } }); export default store;
### vuex辅助函数
state:{ name:"吴小明", age:24 }
<h2>{{$store.state.name}}</h2> <h2>{{$store.state.age}}</h2>
computed: { name(){ return this.$store.state.name; }, age(){ return this.$store.state.age; } }
<h2>{{name}}</h2> <h2>{{age}}</h2>
computed: { ...mapState(["name","age"]) // 利用辅助函数可以省略name()和age()方法 }
computed: { ...mapState({ name:state=>state.name, age:state=>state.age }) }
mutations:{ mutationsAgeAdd(state){ state.age++; } }
methods:{ ageAdd(){ this.$store.commit("mutationsAgeAdd"); } }
methods:{ ...mapMutations(["mutationsAgeAdd"]) }
methods:{ ...mapMutations({ ageAdd:"mutationsAgeAdd" }) }
actions:{ actionsAgeAdd({commit}){ commit("mutationsAgeAdd"); } }
methods: { actionsAgeAdd(){ this.$store.dispatch("actionsAgeAdd"); } }
methods: { ...mapActions({ actionsAgeAdd:"actionsAgeAdd" }) }
getters:{ double(state){ return state.age*2; } }
<p>{{$store.getters.double}}</p>
computed: { ...mapGetters({ double:"double" }) }
### vuex的modules配置项
export default{ state:{ cityName:"北京" }, actions:{ actionsSonHandle({commit}){ commit("mutationsSonHandle") } }, mutations:{ handleMutationsAdd(){ console.log("子模块") }, mutationsSonHandle(){ console.log("调用子模块了") } }, getters:{ }, // 实现子模块私有化,当子模块和主模块有同名方法时,子模块的方法前会加 city/ 如 handleMutationsAdd 为 city/handleMutationsAdd namespaced:true }
import city from "./city";
modules:{
city
}
<p>{{$store.state.city.cityName}}</p>
methods: { sonHandle(){ // this.$store.dispatch("city/actionsSonHandle"); this.$store.commit("city/mutationsSonHandle"); } }
Question:
2、vuex中数据刷新浏览器丢失了如何解决
### mock数据和json-server的使用
{ "data":[ { "username":"wql", "age":24, "id":1 }, { "username":"吴小明", "age":23, "id":2 } ] }
\{^_^}/ hi! Loading data.json Done Resources http://localhost:3000/data Home http://localhost:3000 Type s + enter at any time to create a snapshot of the database
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>jsonserver</title> </head> <body> <button onClick="insert()">增</button> <button onClick="remove()">删</button> <button onClick="update()">改</button> <button onClick="find()">查</button> </body> </html> <script src="https://cdn.bootcss.com/jquery/1.11.3/jquery.js"></script> <script> /* json-server mock数据: 接口地址:/user/login 请求类型:GET 测试接口:http://www.baidu.com 请求字段: username password 响应字段: { data:{ list:[], code:"" } } 安装:npm install json-server -g 启动mock数据:json-server 文件名称 在json-server中请求的类型有很多种: get---获取 post---提交 put---修改 patch---修改某一个属性 delete---删除数据 */ function insert(){ $.ajax({ type:"post", url:"http://localhost:3000/data",// mock数据没有跨域问题 data:{ username:"吴彦祖", age:20 }, success:function(data){ console.log(data) } }); } function remove(){ $.ajax({ type:"delete", url:"http://localhost:3000/data/1",// 删除id为1的数据 success:function(data){ console.log(data) } }); } function update(){ $.ajax({ type:"patch",// 不建议用put方式,put会将data数据替换掉data.json中的对应数据 url:"http://localhost:3000/data/1",// 修改id为1的数据 data:{ name:"孙艺珍", age:200 }, success:function(data){ console.log(data) } }); } function find(){ $.ajax({ type:"get", url:"http://localhost:3000/data?q=彦",// /1---拿到第一条数据 ?id=1---拿到第一条数据,数组包裹 ?q=彦---模糊查询 success:function(data){ console.log(data) } }); } </script>