26 前端封装(简单实用vuex,封装权限验证操作,js-promise,async+await,封装请求模块)

26 前端封装

(简单实用vuex,封装权限验证操作,js-promise,async+await,封装请求模块)

一 使用vuex(简单调用)

可以参考drf系列的这篇文章:https://www.cnblogs.com/zhangmingyan/articles/11791597.html

新建store/index.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
	state:{
		loginStatus:false
	},
	mutations:{
		changeLoginStatus(state,{num}){
			state.loginStatus = num
		}
	}
})

修改main.js

import Vue from 'vue'
import App from './App'
import store from './store/index.js';

Vue.prototype.$store = store

Vue.config.productionTip = false

// 引入全局组件
import divider from './components/common/divider.vue';
Vue.component('divider',divider)
import noThing from './components/common/no-thing.vue';
Vue.component('no-thing',noThing)

// 引入配置文件
import $C from './common/config.js';
Vue.prototype.$C = $C
// 挂在助手函数库
import $U from './common/util.js';
Vue.prototype.$U = $U

App.mpType = 'app'

const app = new Vue({
	store,
    ...App
})
app.$mount()

在项目的任意位置皆可以this.$store调用

image-20200420210008231

二 封装跳转权限验证层

思路:

1 实现如点赞点踩需要登录的操作,通过加了一个权限操作验证,如果没有登录跳转到登录页面

2 实现如跳转到发朋友圈的页面,通过加了一个权限跳转验证,如果没有登录先跳转到登录页面

如果是python技术站,可以简单理解为搞了个装饰器。

代码:

Main.js(关注两个权限验证字眼)

import Vue from 'vue'
import App from './App'
import store from './store/index.js'
// 原型上有这个store
Vue.prototype.$store = store

Vue.config.productionTip = false

// 组册全局组件
import divider from './components/common/divider.vue';
import noThing from './components/common/no-thing.vue'
Vue.component('divider',divider)
Vue.component('no-thing',noThing)

// 引入配置文件
import $C from './common/config.js';
Vue.prototype.$C = $C
// 挂在助手函数库
import $U from './common/util.js';
Vue.prototype.$U = $U

// 权限验证操作
Vue.prototype.checkAuth = (callback) =>{
	// 权限验证
	if (!store.state.loginStatus){
		uni.showToast({
			title:'请先登录',
			icon:'none'
		});
		return uni.navigateTo({
			url:'/pages/login/login'
		})
	}
	// js叫回掉函数,其实和装饰器差不多。
	callback()
}

// 权限验证跳转
Vue.prototype.navigateTo = (options)=>{
	// 权限验证
	if (!store.state.loginStatus){
		uni.showToast({
			title:'请先登录',
			icon:'none'
		})
		return uni.navigateTo({
			url:'/pages/login/login'
		})
	}
	uni.navigateTo(options)
}

App.mpType = 'app'

// 实例化的app加载 store里面的内容。
const app = new Vue({
	store,
	...App
})
app.$mount()

Common-list.vue

// 关注事件
			follow(){
				//console.log('点击了关注')
				// 通知父组件
				this.checkAuth(()=>{
					 this.$emit('follow',this.index)
					}
				)
				
				
			},
			// 顶踩操作
			doSupport(type){
				// console.log(type)
        // 先经过权限验证,如果验证通过了再回掉这个传入的箭头函数。
				this.checkAuth(()=>{
					 this.$emit('doSupport',{
					 	type,
					 	index:this.index
					 })
					})
				
			},
			// 评论
			doComment(){
				this.checkAuth(()=>{
					if (!this.isdetail) {
						return this.openDetail()
					}
					this.$emit('doComment')
				})
			},

index.vue

// 监听导航按钮点击事件
		onNavigationBarButtonTap() {
      // 使用自己封装的权限验证跳转
			this.navigateTo({
				url: '../add-input/add-input',
			})
		},

三 promise方法:

核心:

0 promise 是异步的不会阻塞下面代码。

1 promise对象支持.then(res=>{}).catch(err=>{})

2 promise对象代码体内 resolve(xxx) 触发---->其对象的.then() 方法并且把xxx传给res 执行then内的回掉函数

3 promise对象代码体内 reject(yyy) 触发---->其对象的.catch() 方法并且把yyy传给err 执行catch内的回掉函数

其实就是监听内部的resolve以及reject,resolve会触发then,resolve的内容并且作为then内部回掉函数的参数,reject会触发catch,同理resolve。

简单使用:

							//ps:这个resolve,reject重要的是位置不是名字,叫啥都行。
new Promise(function (resolve, reject) {
    log('start new Promise...');
    var timeOut = Math.random() * 2;
    log('set timeout to: ' + timeOut + ' seconds.');
    setTimeout(function () {
        if (timeOut < 1) {
            log('call resolve()...');
            resolve('200 OK');
        }
        else {
            log('call reject()...');
            reject('timeout in ' + timeOut + ' seconds.');
        }
    }, timeOut * 1000);
}).then(function (r) {
    log('Done: ' + r);
}).catch(function (reason) {
    log('Failed: ' + reason);
});

image-20200421215900285

ps:直接看下方标题七 实际案例

参考博客:

参考博客:https://www.liaoxuefeng.com/wiki/1022910821149312/1023024413276544

image-20200421130308405

代码以及执行效果:

其实就是监听内部的resolve以及reject,resolve会触发then,resolve的内容并且作为then内部回掉函数的参数,reject会触发catch,同理resolve。

###### 案例1 ajax案例
use strict';

// ajax函数将返回Promise对象:
function ajax(method, url, data) {
    var request = new XMLHttpRequest();
    return new Promise(function (resolve, reject) {
        request.onreadystatechange = function () {
            if (request.readyState === 4) {
                if (request.status === 200) {
                    resolve(request.responseText);
                } else {
                    reject(request.status);
                }
            }
        };
        request.open(method, url);
        request.send(data);
    });
}

var log = document.getElementById('test-promise-ajax-result');
var p = ajax('GET', '/api/categories');
p.then(function (text) { // 如果AJAX成功,获得响应内容
    log.innerText = text;
}).catch(function (status) { // 如果AJAX失败,获得响应代码
    log.innerText = 'ERROR: ' + status;
});

// 输出:ERROR: 400
###### 案例二连续计算案例
// 0.5秒后返回input*input的计算结果:
function multiply(input) {
    return new Promise(function (resolve, reject) {
        log('calculating ' + input + ' x ' + input + '...');
        setTimeout(resolve, 500, input * input);
    });
}

// 0.5秒后返回input+input的计算结果:
function add(input) {
    return new Promise(function (resolve, reject) {
        log('calculating ' + input + ' + ' + input + '...');
        setTimeout(resolve, 500, input + input);
    });
}

var p = new Promise(function (resolve, reject) {
    log('start new Promise...');
    resolve(123);
});

p.then(multiply)
 .then(add)
 .then(multiply)
 .then(add)
 .then(function (result) {
    log('Got value: ' + result);
});

image-20200421130412641

四 补充async+await方法

拓展连接:
https://segmentfault.com/a/1190000007535316
http://www.ruanyifeng.com/blog/2015/05/async.html

核心():

  • 一旦调用了个async a()函数如,x = a() , 那么相当于x 直接隐式的拿到了个promise对象,此时a并没有执行内部的代码。a执行的时候如果一旦发生return行为,那么就相当于promise的resolve行为,也就会传给x.then了。

  • ps特殊的情况: async执行的时候里面的有异步代码就会跳过接着往下执行,就相当于去函数的结束的位置return了个null,也就相当于这个async的then等到了resolve行为,然并卵里面的异步并没有执行完。

  • 根据上一条,想使用then等完async 那么要把里面的异步统统await,然后发生return也就是发生resolve然后执行then里的逻辑。

  • async 定义的函数里面的return的内容直接封装成了promise的resolve值,async函数直接可以进行then操作。

  • await要写在async定义的函数内部,await 了一个promise对象则会阻塞进行等待这个promise对象完事儿。await的不是promise对象则正常执行(相当于没写await)。

第一点:async 是一个修饰符,async 定义的函数会默认的返回一个Promise对象resolve的值.

就算你不写, 直接return 任何, 它都会封装一下,让你return的东西相当于Promise的resolve() ,就是这么刚!

// 这俩效果是一样的
function getData_1 () {
    return '100'
}

function getData_2 () {
    return new Promise((resolve, reject) => {
        resolve('100')
    })
}
// 0. async基础用法测试

async function fun0() {
    console.log(1)
    return 1
}

fun0().then( x => { console.log(x) })  //  输出结果 1, 1,


async function funa() {
    console.log('a')
    return 'a'
}

funa().then( x => { console.log(x) })  //  输出结果a, a,


async function funo() {
    console.log({})
    return {}
}

funo().then( x => { console.log(x) })   // 输出结果 {}  {}

async function funp() {
    console.log('Promise')
    return new Promise(function(resolve, reject){
        resolve('Promise')
    })
}

funp().then( x => { console.log(x) })   // 输出promise  promise

第二点 await 也是一个修饰符

概念:

1) await 关键字 只能放在 async 函数内部, await关键字的作用 就是获取 Promise中返回的内容, 获取的是Promise函数中resolve或者reject的值

2) 如果await 后面并不是一个Promise的返回值,则会按照同步程序返回值处理(就相当于await失效)

三个小案例带你走向人生巅峰:

//----------------- 1.await后面跟着的是promise对象则会等待。--------------------
//  await 关键字 只能放在 async 函数内部, await关键字的作用 就是获取 Promise中返回的内容, 获取的是Promise函数中resolve或者reject的值
// 如果await 后面并不是一个Promise的返回值,则会按照同步程序返回值处理,为undefined
const bbb = function(){ return 'string'}

async function funAsy() {
   const a = await 1
   const b = await new Promise((resolve, reject)=>{
        setTimeout(function(){
           resolve('time')
        }, 3000)
   })
   const c = await bbb()
   console.log(a, b, c)
}

funAsy()  //  运行结果是 3秒钟之后 ,输出 1, time , string,


//----------------- 2.await后面跟着的不是promise对象则不会等待。---------------------

function log2(time) {
   setTimeout(function(){
       console.log(time)
       return 1
    }, time)
}

async function fun1() {
    const a = await log2(5000)
    const b = await log2(10000)
    const c = log2(2000)
    console.log(a)
    console.log(1)
}

fun1()
// 以上运行结果为: 立刻输出undefined   立刻输出1  2秒后输出2000  5秒后输出5000  10秒后输出10000


//----------------- 3 async / await 后面凡是promise对象必等其结束再往下运行。---------------------

const asy = function(x, time) {
    return new Promise((resolve, reject) =>{
        setTimeout(()=>{
            resolve(x)
        }, time)
    })
}

const add = async function() {
    const a = await asy(3, 5000)
    console.log(a)
    const b = await asy(4, 10000)
    console.log(b)
    const c =  await asy(5, 15000)
    console.log(a,b,c)
    const d = a + b +c  
    console.log(d)
}

add();

// 5秒后输出3  又10秒后输出4 又15秒后输出5  然后立刻输出3,4,5,然后输出12

五 封装请求模块(简单封装)

思路:

1 就是把原有的uni.request(xxx)里面的xxx封装起来更方便我们使用。

2 封装的时候要注意一点异步的方法,如果不传入 success、fail、complete 等 callback 参数,将以 Promise 返回数据。(人话:如果不传入success,fail...这些方法 。request就会返回个promise对象,就可以使用then和catch了)

代码:

common/request.js

import $C from '@/common/config.js'
export default {
	common:{
		method:'GET',
		header:{
			"content-type":"application/json"
		},
		data:{}
	},
	
	request(options = {}){
		
		options.url = $C.webUrl + options.url
		options.method = options.method || this.common.method
		options.header = options.header || this.common.header
		// 验证权限token
		
		// 该有的参数传入进去,返回了一个promise对象可以直接.then使用了就。
		return uni.request(options)
	},
	
	
	get(url, data={}, options={}){
		options.url = url
		options.data = data
		options.method = 'GET'
		return this.request(options)
	},
	
	post(url, data={}, options={}){
		options.url = url
		options.data = data
		options.method = 'POST'
		return this.request(options)
	},
	
}

main.js 挂载一下

// 挂载请求模块
import $H from './common/request.js'
Vue.prototype.$H = $H

pages/index/index.vue测试

// 获取分类
				// this.$H.get('/postclass').then(res=>{
				// 	let [err,result] = res
				// 	console.log(result);
				// })
			
				let res = await this.$H.get('/postclass')
				let [err,result] = res
				console.log(result);
posted @ 2020-04-24 12:39  张明岩  阅读(860)  评论(0编辑  收藏  举报