Promise
-
是异步编程的一种解决方案
什么时候会用
-
有异步操作时,对异步操作进行封装
-
网络请求
-
网络请求函数不能同步获取请求, 会阻塞
-
所以往往会回调一个函数, 在回调里拿到请求的数据
-
这样如果多次回调, 回调里还有回调, 网络请求复杂,会造成回调地狱
-
-
Promise优雅的解决问题
<script>
//参数是一个函数
//函数本身有两个参数,参数本省也是函数
//resolve 接收
//reject 拒绝
// new Promise((resolve,reject)=>{
// setTimeout(()=>{//异步操作
// console.log("hello");
// console.log("hello");
// console.log("hello");
// console.log("hello");
// console.log("hello");
// setTimeout(()=>{//模拟再来一次操作
// console.log("vue");
// console.log("vue");
// console.log("vue");
// console.log("vue");
// console.log("vue");
// setTimeout(()=>{//模拟再来一次操作
// console.log("js");
// console.log("js");
// console.log("js");
// console.log("js");
// console.log("js");
// },1000)
// },1000)
// },1000)
// })///回调地狱
//改造 代码虽然复杂 但结构清晰
//链式编程
new Promise((resolve,reject)=>{
//第一次请求
setTimeout(()=>{//异步操作
resolve();
},1000)
}).then(()=>{
//第一次请求处理
console.log("hello");
console.log("hello");
console.log("hello");
console.log("hello");
console.log("hello");
return new Promise(resolve,reject){
//第二次请求
setTimeout(()=>{//模拟再来一次操作
resolve();
},1000).then(()=>{
//第二次请求处理
console.log("vue");
console.log("vue");
console.log("vue");
console.log("vue");
console.log("vue");
return new Promise(resolve,reject){
// 第三次请求
setTimeout(()=>{//模拟再来一次操作
resolve();
},1000).then(()=>{
// 第三次请求处理
console.log("js");
console.log("js");
console.log("js");
console.log("js");
console.log("js");
});
}
});
}
})
</script>
new Promise((resolve,reject){
setTimeout(()=>{
//这里data不存在 模拟
//成功
resolve(data);
//或者
//失败
reject(error);
},1000);
}).then(data=>{
console.log(data);
console.log(data);
console.log(data);
}).catch(err=>{
console.log(err);
console.log(err);
console.log(err);
})
//new 构造函数
1.保存了一些状态
2.执行传入的函数
在执行传入的回调函数时,会传入两个参数,resolve,reject,本身又是函数
三种状态
-
pending 等待状态 正在网络请求 或 定时器时间未到
-
fulfill 满足状态 当我们住的回调resolve时 并且回调then()
-
reject 拒绝状态 当我们住的回调reject时 并且回调catch()
另一种处理形式
new Promise((resolve,reject){
setTimeout(()=>{
//这里data不存在 模拟
//成功
resolve(data);
//或者
//失败
reject(error);
},1000);
}).then(data=>{//成功
console.log(data);
console.log(data);
console.log(data);
},err=>{//拒绝
console.log(err);
console.log(err);
console.log(err);
});
链式操作
<script>
//wrapped init 包裹
//网络请求: aaa -> 自己处理(10行)
//处理: aaa111 -> 自己处理(10行)
//处理: aaa111222 -> 自己处理(10行)
new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('aaa');
},1000);
}).then(res =>{
//1.自己处理10行代码
console.log(res,"第一层的10行处理代码");
// 2.对结果进行第一次处理
return new Promise(resolve=>{
resolve(res+'111');
}).then(res => {
console.log(res,"第二层的10行处理代码");
return new Promise(resolve=>{
resolve(res+'222');
}).then(res => {
console.log(res,"第三层的10行处理代码");
})
})
})
</script>
简写
new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('aaa');
},1000);
}).then(res =>{
//1.自己处理10行代码
console.log(res,"第一层的10行处理代码");
// 2.对结果进行第一次处理
return Promise.resolve(res+'111');
}).then(res => {
console.log(res,"第二层的10行处理代码");
return Promise.resolve(res+'222');
}).then(res => {
console.log(res,"第三层的10行处理代码");
})
在简化 使用内部自己封装
new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('aaa');
},1000);
}).then(res =>{
//1.自己处理10行代码
console.log(res,"第一层的10行处理代码");
// 2.对结果进行第一次处理
return res+'111';
}).then(res => {
console.log(res,"第二层的10行处理代码");
return res+'222';
}).then(res => {
console.log(res,"第三层的10行处理代码");
})
失败处理
//失败处理
new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('aaa');
},1000);
}).then(res =>{
//1.自己处理10行代码
console.log(res,"第一层的10行处理代码");
// 2.对结果进行第一次处理
// return res+'111';
//如果错误
// return Promise.reject('error message');
throw 'error message';
}).then(res => {
console.log(res,"第二层的10行处理代码");
return res+'222';
}).then(res => {
console.log(res,"第三层的10行处理代码");
}).catch(err => {
console.log(err)
})
Promise的all方法
-
处理多次请求动成功后处理的事件
-
参数为个迭代对象
new Promise([
new Promise((resovle,reject) => {
$ajax({
url:'url1',
success: function(){
resovle(data)
}
})
}),
new Promise((resovle,reject) => {
$ajax({
url:'url2',
success: function(){
resovle(data)
}
})
})
]).then(results => {
results[0]
results[1]
})
模拟
Promise.all([ new Promise((resovle,reject) => { setTimeout(()=>{ resolve('result1') },2000) }), new Promise((resovle,reject) => { setTimeout(()=>{ resolve('result2') },1000) }) ]).then(results => { console.log(results) })
Vuex
-
状态管理模式
-
集中式存储管理 应用的所有组件,并以相应的规则保证状态以一种可预测的方式发生变化
状态管理
-
多个组件
共享的状态
变量
什么时候用
-
用户登录状态 用户名称 头像,地理位置信息等等
-
商品的收藏,购物车中的物品等
vuex插件
npm install vuex --save
-
使用
-
store/index.js
-
import Vue from 'vue'; import Vuex from 'vuex';
//1.安装插件
Vue.use(Vuex);//2.创建对象
const store = new Vuex.Store({
//设置状态
state:{
counter:1000,
},
// 修改state
mutations:{
//方法 默认参数state
increment(){
this.state.counter++
},
decrement(){
this.state.counter--
},
},
// 异步操作处理(网络请求时)
actions:{},
getters:{},
modules:{
}
})// 3. 导出对象
export default store; -
main.js
-
import Vue from 'vue' import App from './App.vue' import store from './store/index.js';//导入
Vue.config.productionTip = false
new Vue({
store,
render: h => h(App)
}).$mount('#app')
-
HelloVuex.vue
-
<template> <div> <h2>{{$store.state.counter}}</h2> </div> </template>
<script>
export default {
name:"HelloVuex",
}
</script><style scoped>
</style>
-
App.vue
-
<template> <div id="app"> <h1>--------App内容--------</h1> <h2>{{$store.state.counter}}</h2> <button @click="subtraction">-</button> <button @click="addition">+</button> <h1>--------HelloVue内容--------</h1> <hello-vuex></hello-vuex> </div> </template>
<script>
import HelloVuex from "./components/HelloVuex";export default {
name:'App',
components:{
HelloVuex,
},
data(){
return {
message:'我是App组件',
}
},
methods:{
addition(){
//通过commit提交
this.$store.commit("increment");
},
subtraction(){
this.$store.commit("decrement");
},
},}
</script><style>
</style>
devtools
-
vue开发的浏览器插件
-
记录修改state的状态,跟踪state
-
state必须通过mutations修改
-
跟踪同步操作
-
安装
-
chrome扩展程序
五个Vuex核心概念
-
State (单一状态树)
-
Getters
-
Mutation
-
Action
-
Module
State
-
单一状态树 Single Source of Truth
Getters
-
两个默认参数 state,getters
-
获取的时候第state进行一些处理的操作 比如 对state的数据平方
-
state:{ counter:1000, students:[ { id:110, name:"nick", age:18, }, { id:111, name:"jack", age:24, }, { id:112, name:"mary", age:30, }, { id:113, name:"lily", age:10, }, ], },
getters:{
powerCounter(state){
return state.counter * state.counter;
},
more20stu(state){
return state.students.filter(s => s.age > 20);
},
more20stuLength(state,getters){
return getters.more20stu.length;
},
moreAgeStu(state){
// return function(age){
// return state.students.filter(s => s.age > age);
// }
return age => {
return state.students.filter(s => s.age > age);
}
}
},//当计算属性一样
<h2>{{$store.getters.powerCounter}}</h2><h2>{{$store.getters.more20stu}}</h2>
<h2>{{$store.getters.more20stuLength}}</h2>
<h2>{{$store.getters.moreAgeStu(12)}}</h2>
Mutation(状态更新)
-
分为两部分
-
字符串的事件类型(type)
-
一个回调函数(handler), 第一个参数就是state
-
-
mutations:{ //方法 默认参数state increment(){//increment事件类型 this.state.counter++ }, decrement(){ this.state.counter-- }, //接收参数 incrementdCount(state,count){ state.counter += count; }, // 添加对象 addStudent(state,stu){ state.students.push(stu) } },调用
methods:{
addition(){
//通过commit提交
this.$store.commit("increment");
},
subtraction(){
this.$store.commit("decrement");
},
addCount(count){
//传递参数 负载(Payload)
this.$store.commit("incrementCount",count);
},
//传递对象
addStudent(){
const stu = {id: 114, name: "alan", age: 35};
this.$store.commit("addStudent",stu);
}
},
提交分格二
addCount(count){ //传递参数 负载(Payload) // this.$store.commit("incrementCount",count);//特殊提交写法 this.$store.commit({ type:"incrementCount", count,//注意接收的时候是对象 }) },
//接收参数 负载(Payload)
// incrementCount(state,count){
// state.counter += count;
// },
// 特殊改写
incrementCount(state,payload){
console.log(payload);//{type: "incrementCount", count: 5}
state.counter += payload.count;
},
//接收时拿到的是 {type: "incrementCount", count: 5}
响应规则
-
提前在store中初始化好所需的属性 (响应式系统会监听这些属性)
-
当给state中的对象添新属性时,使用下的方式
-
使用Vue.set(obj,'newProp',123);
-
用新对象旧对象重新赋值
-
updataInfo(){ this.state.info.name = "ccc"; // 新增 Vue.set(this.state.info,"xxx",12); // 新对象替旧对象 const info = { name: 'aaa', age: 15. } this.state.info = info; // 删除 Vue.delete(this.state.info,'age'); }
-
不能使用
-
state.info['xxx'] = "sss"; xxx 是新增的 原来没有 所以没有响应式
-
类型常量(推荐写法)
-
mutations-types.js
-
import { INCREMENT }from './store/mutations-types.js';
methods: {
addition(){
//通过commit提交
this.$store.commit(INCREMENT);
},
}import {
INCREMENT
}from '../store/mutations-types.js';mutations:{
//方法 默认参数state 方法可以这么写
INCREMENT{
this.state.counter++
},
}
同步函数
-
mutations里必须是同步函数 方便跟踪
异步处理(actions)
-
actions 两个参数 context 和 payload
updataInfo(){//异步操作 不跟踪 不能在这里写 //模拟 // setTimeout(()=>{ // this.state.info.name = "aaa"; // },1000); //这里写操作 通过actions调用 this.state.info.name = "ccc"; //使用actions替代异步操作
}
actions:{
// 默认属性context 上下文
// aUpdateInfo(context,payload){
// //模拟异步操作
// setTimeout(()=>{
// //修改操作必须通过mutations
// context.commit('updataInfo');
// console.log(payload)
// },1000);
// }aUpdateInfo(context,payload){ //需要回调操作 就改写 使用 Promise return new Promise((resolve,reject)=>{ //模拟异步操作 setTimeout(()=>{ //修改操作必须通过mutations context.commit('updataInfo'); console.log(payload); resolve('1111'); },1000); }) }
}
调用的地方写
updataInfo(){
//无异步操作
// this.$store.commit("updataInfo");//异步操作 并传递参数 // this.$store.dispatch('aUpdateInfo','我是payload') //改写异步操作 为Promise 需要回调时使用 this.$store .dispatch('aUpdateInfo','我是payload')//这里时返回了的Promise .then(res => { console.log(res) console.log("里面完成了") }) }</pre>
modules
-
模块
-
抽离
-
modules:{ a: { state:{}, mutations:{}, actions:{}, getters:{}, }, b: { state:{}, mutations:{}, actions:{}, getters:{}, } }
//抽离出来 const moduleB = { state:{ name: 'zhangsan' }, mutations:{ updateName(state,paylode){ state.name=paylode } }, actions:{ aUpdateName(context) { // aUpdateName({state,commit,rootState}}) {//解构写法 console.log(context)//这里的context 和根下的context不一样 setTimeout(() =>{ context.commit('updateName','wangwu') },1000) } }, getters:{ fullname(state){ return state.name + '111'; }, fullname2(state,getters){ return getters.fullname +'222'; }, fullname3(state,getters,rootState){//rootState根state return getters.fullname2 + rootState.counter; }, }, }
<h1>--------modules内容--------</h1> <h2>{{$store.state.b.name}}</h2> <h2>{{$store.getters.fullname}}</h2> <h2>{{$store.getters.fullname2}}</h2> <h2>{{$store.getters.fullname3}}</h2> <button @click="updateName">更新Name</button> <button @click="asyncUpdateName">异步修改Name</button>
modules:{
a: {
state:{},
mutations:{},
actions:{},
getters:{},
},
b: moduleB,
}<h2>{{$store.state.b.name}}</h2>
目录分析
-
模块提取
-
index.js
-
modules
-
moduleB.js
-
-
mutations.js
-
actions.js
-
getters.js
-