一.以异步方法封装设置本地储存
在微信小程序中,设置本地存储通常使用 `wx.setStorageSync` 或 `wx.setStorage` 方法。由于 `wx.setStorage` 是异步的,而 `wx.setStorageSync` 是同步的,这里我会展示如何使用 `wx.setStorage` 以异步方式封装设置本地存储的方法。
二.localStorage、sessionStorage、cookie的区别
localStorage、sessionStorage和cookie都是前端开发中常见的用于临时存储客户端会话信息或数据的方法,但它们之间存在一些重要的区别。
1. 存储大小:localStorage和sessionStorage的存储大小限制比cookie大得多,通常可以达到5MB或更大。这意味着你可以存储更多的数据在localStorage和sessionStorage中,而cookie由于大小的限制,通常用于存储较小的数据。
2. 数据有效期:三者的数据有效期不同。sessionStorage中的数据仅在当前浏览器窗口关闭之前有效,当窗口关闭后,存储的数据会被清除。而localStorage中的数据始终有效,即使窗口或浏览器关闭,数据也会一直保存,因此它常被用作持久数据。对于cookie,其有效期是在设置的cookie过期时间之前,即使窗口或浏览器关闭,只要cookie未过期,数据仍然有效。
3. 作用域:sessionStorage的数据不在不同的浏览器窗口中共享,即使是同一个页面。这意味着,如果你在一个浏览器窗口中设置了sessionStorage的数据,然后在另一个窗口中尝试访问这些数据,你将无法获取到。相反,localStorage和cookie的数据在所有同源窗口中都是共享的,无论在哪个窗口中设置的数据,都可以在其他窗口中访问到。
4. 事件通知机制:web Storage(包括localStorage和sessionStorage)支持事件通知机制,可以将数据更新的通知发送给监听者。而cookie则没有这种机制。
5. API接口使用:web Storage的API接口使用更为方便,提供了诸如setItem、getItem、removeItem等方法来操作存储的数据。而cookie则需要通过document.cookie来操作,使用起来相对复杂一些。
总的来说,localStorage、sessionStorage和cookie各有其特点,你需要根据你的应用需求来选择使用哪一种。例如,如果你需要存储大量的数据,并且这些数据需要在用户的多个浏览器会话中持久存在,那么你可能会选择使用localStorage。如果你只需要在当前浏览器会话中存储一些数据,并且这些数据不需要在其他窗口中共享,那么你可能会选择使用sessionStorage。而如果你需要存储的数据量较小,并且需要在用户的多个浏览器会话中保持有效,那么你可能会选择使用cookie。
三、分清不同的storage方法
在前端开发中,不同的存储方法(storage)有各自的用途和特点,包括 `localStorage`、`sessionStorage` 和 `cookie`。以下是它们之间的主要区别和适用场景:
### localStorage
- **生命周期**:永久存储,除非用户手动清除或开发者通过代码删除。
- **作用域**:跨浏览器窗口和选项卡共享。这意味着在一个窗口或选项卡中存储的数据可以在其他窗口或选项卡中访问。
- **存储大小**:通常较大,可以存储较多数据。
- **API接口**:提供了 `getItem`、`setItem`、`removeItem` 和 `clear` 等方法。
### sessionStorage
- **生命周期**:会话期间有效,页面会话结束时数据会被清除(例如,关闭浏览器窗口或选项卡)。
- **作用域**:数据独立于其他选项卡和窗口。在一个窗口或选项卡中存储的数据不会在其他窗口或选项卡中反映。
- **存储大小**:与 `localStorage` 类似。
- **API接口**:同样提供了 `getItem`、`setItem`、`removeItem` 和 `clear` 等方法。
### Cookies
- **生命周期**:由开发者设置,可以设置为会话期间有效(当浏览器窗口关闭时过期)或设置为特定的过期时间。
- **作用域**:通常在整个域名下有效,可以跨不同的路径和子域名共享。
- **存储大小**:通常较小,限制在4KB左右(具体取决于浏览器)。
- **操作方式**:通过 `document.cookie` 来读取、设置和删除。操作相对复杂,需要手动编码和解码。
### 如何选择
- **如果你需要长期存储大量数据,并且这些数据需要在用户的多个浏览器会话中保持有效,那么应该选择 `localStorage`。**
- **如果你只需要在当前浏览器会话中存储一些数据,并且这些数据不需要在其他窗口或选项卡中共享,那么 `sessionStorage` 可能是更好的选择。**
- **如果你需要存储的数据量较小,并且需要在用户的多个浏览器会话中保持有效,同时还需要考虑跨域名或跨路径的数据共享,那么 `cookie` 可能是一个合适的选择
一.HTTP请求方法
不同的业务场景会使用不同的请求方法,
HTTP1.0 定义了三种请求方法: GET, POST 和 HEAD 方法。
HTTP1.1 新增了六种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方法。
GET 请求指定的页面信息,并返回实体主体。
HEAD 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。
PUT 从客户端向服务器传送的数据取代指定的文档的内容。
DELETE 请求服务器删除指定的页面。
CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
OPTIONS 允许客户端查看服务器的性能。
TRACE 回显服务器收到的请求,主要用于测试或诊断。
POST和PUT请求的区别
幂等性:幂等通俗来说是指不管进行多少次重复操作,都是实现相同的结果。
1.POST请求非幂等性操作
GET,PUT,DELETE都是幂等操作,而POST不是,以下进行分析:
首先GET请求很好理解,对资源做查询多次,此实现的结果都是一样的。
PUT请求的幂等性可以这样理解,将A修改为B,它第一次请求值变为了B,再进行多次此操作,最终的结果还是B,与一次执行的结果是一样的,所以PUT是幂等操作。
同理可以理解DELETE操作,第一次将资源删除后,后面多次进行此删除请求,最终结果是一样的,将资源删除掉了。
get
从服务器端获取数据,请求body在地址栏上
用于获取资源,是幂等的,无副作用
post
向服务器端提交数据,请求数据在报文body里
发送一个修改数据的请求,需求数据要从新创建
用于创建,更新,删除资源,查询资源都可以,是不幂等的
二·Promise 基本用法
1、在微信小程序中执行命令
npm install --save miniprogram-api-promise
2、重新构建npm
3、在app.js中配置全局对象
//app.js
import { promisifyAll } from 'miniprogram-api-promise'
// 添加一个wx.p的属性,并将地址保存至wxp
const wxp = wx.p = {}
// 将wx 的属性转换成可以使用promise的属性 并保存到wxp中
// 同时不会影响到 wx
promisifyAll(wx,wxp)
4、在页面是使用
// then方式
wx.p.request({
url: '.....',
}).then(res => {
console.log(res);
})
// async await方式
const {data:res} = await wx.p.request({
url: '.....',
})
console.log(res);
三.Object.assign的用法
Object.assign(target, ...sources)
参数:target--->目标对象
source--->源对象
返回值:target,即目标对象
四.async&await用法
async 表示函数里有异步操作,
await 表示紧跟在后面的表达式需要等待结果。
同 Generator 函数一样,async 函数返回一个 Promise 对象,可以使用 then 方法添加回调函数。当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,再接着执行函数体内后面的语句。
五.baseUrl的使用
六.class类
ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过 class 关键字,可以定义类。
基本上,ES6 的 class 可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已;
类可以看做是对象的模板,用一个类可以创建出许多不同的对象
2、基本用法
calss 类名 {} 没有分号,类名首字母大写,内容写在花括号里面。实例化执行构造方法,所以必须有构造方法constructor ,但可以不写出来。在构造方法constructor 中定义属性,在构造方法constructor外面定义方法。
request.js页面目前完成了哪些效果,每个代码段的作用
1.定义拦截对象,包括请求拦截和响应拦截方法
2.封装GET实例方法
封装POST实例方法
封装PUT实例方法
封装DELETE实例方法
3.对wxRequest进行实例化 配置请求拦截器
4.响应拦截器
5.将WxRequest实例暴露出去,方便在其他文件中进行使用
class WxrRequest{
默认参数对象
defaults ={
请求基地址
baseURL:'',
服务接口地址
url:'',
请求方式
method:'GET',
请求参数
data:null,
请求头:
header: {
'Content-type': 'application/json'
设置数据的交互格式
},
默认时间为一分钟
timeout:60000
}
定义拦截对象,包括请求拦截和响应拦截方法,方便在请求或响应之前进行处理。
interceptors ={
请求拦截器
request:(config)=> config,
响应拦截器
response:(response)=>response
}
用于创建和初始化类的属性和方法
constructor(params={}){
使用object.assign方法合并并默认参数以及传递的请求参数
需要传入的参数,会覆盖默认参数,因此传入的参数放在最后
this.defaults = Object.assign({},this.defaults,params)}
request实例方法接受一个对象类型的参数
request(options){
拼接完整的请求路径
options.url=this.defaults.baseURL + options.url
合并请求参数
options ={...this.defaults,...options}
在发送请求之前调用请求拦截器
options = this.interceptors.request(options)
console.log(options);
return new Promise((resolve,reject)=>{
wx.request({
使用扩展运算符将request函数传来的对象参数展开
...options,
当接口调用成功就会触发success回调函数
success:(res) =>{
不管接口成功还是失败 都需要调用响应拦截器
响应拦截器需要接受服务器响应的数据,然后对数据进行逻辑处理 处理好后进行返回
在给响应拦截器传递参数时 需要将请求参数也一起上传
方便进行代码的调试或者其他逻辑处理 所以需要合并参数
然后将合并的参数给响应拦截器
第一个参数:需要合并的对象
第二个参数:服务器响应的数据
第三个参数:请求配置以及自定义属性
const mergetRes= Object.assign({},res,{config:options})
resolve(res)
resolve(this.interceptors.response(mergetRes))
},
当接口调用失败时会触发fail回调函数
fail:(err) =>{
const mergetErr= Object.assign({},err,{config:options})
resolve(this.interceptors.response(mergetErr))
}
})
})
}
封装GET实例方法
get(url,data={},config={}){
return this.request(Object.assign({url,data,method:'GET',config}))
}
封装POST实例方法
post(url,data={},config={}){
return this.request(Object.assign({url,data,method:'POST',config}))
}
封装PUT实例方法
put(url,data={},config={}){
return this.request(Object.assign({url,data,method:'PUT',config}))
}
封装DELETE实例方法
delete(url,data={},config={}){
return this.request(Object.assign({url,data,method:'DELETE',config}))
}
}
对wxRequest进行实例化
const instance =new WxrRequest({
baseURL:'https://gmall-prod.atguigu.cn/mall-api',
timeout:15000
})
配置请求拦截器
instance.interceptors.request=(config)=>{
在发送请求之前做什么
return config
}
响应拦截器
instance.interceptors.response=(response)=>{
在发送请求之前做什么
return response
}
将WxRequest实例暴露出去,方便在其他文件中进行使用
export default instance
1.对async/await的理解
(1)async/await是编写异步代码的新方式,它是generator的语法糖,以前的方式有回调函数和promise。
(2)async/await是基于Promise实现的,它不能用于普通函数的回调函数;async/await与Promise一样,是非阻塞的。
(3)async/await使得异步代码看起来像同步代码,这正是它的魔力所在;单一的Promise链并不能发现async/await的优势,但是如果需要处理由多个Promise组成的then链的时候,优势就能体现出来了。
2.async/await和Promise有什么区别
(1)函数前面多了一个async关键字。await关键字只能用在async定义的函数内。async函数会隐式返回一个promise。
(2)简洁:使用async和await明显节约了不少代码,不需要.then,不需要写匿名函数处理promise的resolve的值,不需要定义多余的data变量,还避免了嵌套代码。
(3)async/await让try/catch 可以同时处理同步和异步错误。try/catch不能处理JSON.parse的错误,因为他在promise中。此时需要.catch,这样的错误处理代码非常冗余。并且,在我们的实际生产代码会更加复杂。
(4)async/await能够使得代码调试更简单,能把异步代码当成同步代码来处理。
(5)当需要异步操作的数据的时候使用async/await,promise不能获取到异步操作的数据。
Promise.resolve 方法功能分析:
调用 Promise.resolve() 返回一个 promise 对象;
如果参数是 promise 对象,则 promise 对象返回的状态结果就是 Promise.resolve 返回的 promise 对象的状态结果,成功则成功,失败则失败;
如果参数是非 promise 对象,则 Promise.resolve 返回一个状态为成功的结果;
Promise.resolve() 中无参数时,返回一个状态为成功 [[PromiseState]]: fulfilled ,结果为[[PromiseResult]]: undefined的 promise 对象。
Promise.reject 方法功能分析:
调用 Promise.reject() 返回一个 promise 对象;
如果参数是一个 promise 对象,则参数为 promise 的对象返回的状态结果与 Promise.reject 返回的 promise 对象的状态结果无关;
如果参数是非 promise 对象,则 Promise.reject 返回一个状态为失败的结果;
Promise.reject() 中无参数时,返回一个状态为失败 [[PromiseState]]: rejected ,结果为[[PromiseResult]]: undefined的 promise 对象。
romise.all的使用
说明
Promise.all 可以将多个Promise实例包装成一个新的Promise实例,等待所有都完成(或第一个失败)
返回值
成功的时候返回的是一个数组,失败的时候则返回先被reject失败状态的值
一般在使用axios时,会用到拦截器的功能,一般分为两种:请求拦截器、响应拦截器。
请求拦截器 在请求发送前进行必要操作处理,例如添加统一cookie、请求体加验证、设置请求头等,相当于是对每个接口里相同操作的一个封装;
响应拦截器 同理,响应拦截器也是如此功能,只是在请求得到响应之后,对响应体的一些处理,通常是数据统一处理等,也常来判断登录失效等。
比如一些网站过了一定的时间不进行操作,就会退出登录让你重新登陆页面,当然这不用拦截器你或许也可以完成这功能,但是会很麻烦而且代码会产生大量重复,所以我们需要用到拦截器
在前端开发中,loading(加载中)效果的使用主要是为了提升用户体验,减少用户在等待页面或数据加载时的焦虑感。以下是在前端中使用loading效果的一些常见方法:
1. 页面加载loading:当页面加载速度较慢时,可以在页面上方或下方显示一个loading提示,告诉用户页面正在加载中。这种loading效果通常是一个动画或加载提示文字,直到页面加载完成后再消失。
2. 数据加载loading:在异步获取数据(如通过Ajax请求从服务器获取数据)时,可以在需要加载数据的位置显示一个loading效果。例如,在表格或列表的上方显示一个加载动画,直到数据加载完成后再显示具体的数据。
3. 表单提交loading:在表单提交时,为了防止用户多次点击提交按钮,可以在提交按钮上显示一个loading效果,告诉用户表单正在提交中。
在前端中使用loading效果时,需要注意以下几点:
合适的时机:loading效果应该在合适的时机出现,如页面加载、数据加载或表单提交等。如果频繁出现或长时间不消失,可能会影响用户体验。
简洁明了:loading效果应该简洁明了,不要过于复杂或花哨,以免分散用户的注意力。
可控制:loading效果应该可以通过代码进行控制,如手动显示和隐藏,或根据特定条件自动显示和隐藏。
此外,一些前端框架(如Vue.js、React等)也提供了内置的loading效果或相关插件,可以更方便地在前端中使用loading效果。
100-199 客户端相应操作
100-是否可以再后续的请求中发送附件
101-服务器将按照其上的头信息变为一个不同的协议
200-299 表示请求成功
200-表示一切正常
201-表示在服务器请求中建立了新文档
202-客户端请求正在被执行,但还没有处理完
203-表示文档被正常的返回
204-确保浏览器继续显示先前的文档
205-重置内容,强制浏览器清除表单域
300-399 已经移动的文件
300-被请求的文档可以在多个地方找到
301-所请求的文档在别的地方
302-定位头信息中所给的URL应被理解为临时文件而不是永久的
303-最初的请求如果是post,新文档要用get找回
304-缓冲的版本已经被更新并且客户端应刷新文档
305-所请求的文档要通过定位头信息中代理服务器获得
307-在303的基础上进行重定向
400-499 指出客户端错误
400-表示错误请求
401-客户端在授权头信息中没有有效的身份信息访问受保护
403-除非拥有授权否则服务器拒绝提供所请求资源
404-客户端所给的地址无法找到任何资源
405-请求方法对某些特定的资源不允许使用
406-所请求的资源与客户端中头信息指定类型不一致
407-指出客户端必须通过代理服务器的认证
408-服务器等待客户端发送请求的时间过长
409-用于试图上传版本不正确的文件
410-告诉客户端所请求的文件不存在
411-表示服务器不能处理请求
412-指出请求头信息中的某些先决条件是错误的
413-告诉客户端现在所请求的文档比服务器现在想要处理的要大
414-用于在URI过长的情况时
415-意味着请求所带的附件的格式类型服务器不知道如何处理
416-表示客户端包含了一个服务器无法满足的Range头信息的请求
417-告诉浏览器服务器不接收该附件
500-599 指出服务器错误
500-是常用的“服务器错误”状态。该状态经常由CGI程序引起
501-告诉客户端服务器不支持请求中要求的功能
502-指出接收服务器接收到远端服务器的错误响应
503-表示服务器由于在维护或已经超载而无法响应
504-指出接收服务器没有从远端服务器得到及时的响应
505-是说服务器并不支持在请求中所标明 HTTP 版本
解构赋值
1、解构赋值:是对赋值运算符的扩展,把对象或数组的属性或值提取出来,进行赋值给变量;在解构中,解构的源:解构赋值表达式右边部分;解构的目标:解构赋值表达式左边部分;好处:让语法更加简洁优雅;
2、解构赋值的分类:
(1)数组解构赋值
(2)对象解构赋值
(3)字符串解构赋值
(4)布尔值解构赋值
(5)函数参数解构赋值
(7)数值解构赋值
3、解构赋值使用场景:
(1)变量交换
(2)直接返回函数return有多个值的内容
(3)可以选择赋值
(4)取出第一个赋值,剩余的赋值为数组
(5)提取对象中需要的属性值;
(6)json对象可以使用json.parse转换成字符串,通过解构只取出其中的一部分;
4、数组解构赋值要注意的事项:
(1)“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值;
(2)如果等号的右边不是数组(或者严格地说,不是可遍历的结构,那么将会报错);
5、对象解构赋值要注意的事项:
(1)对象的属性没有次序,变量名必须与属性名同名,才能取到正确的值;
(2)对象解构也可以用于相套结构对象;
6、默认值:只有当赋的值严格为undefined时,默认值才会生效;
7、():对已声明的变量进行解构,要加上();
三元表达式
微信小程序中的三元表达式是一种简洁的条件判断语法,用于根据条件返回不同的值。它的语法形式为:
condition ? value1:value2
其中,condition 是一个布尔表达式,当它的值为真时,返回 value1;当它的值为假时,返回 value2.举个例子,假设有一个变量 age 表示用户的年龄,我们想根据年龄是否大于等于18来判断用户是否成年,可以使用三元表达式来实现:const isAdult=age>=18 ?'成年' :'未成年':
上述代码中,如果 age 大于等于18,则 isAdult 的值为'成年';否则,isAdult 的值为'未成年'三元表达式在简单的条件判断场景下非常便捷,但如果条件罗辑较复杂,建议使用 if-else 语句来实现更清晰的逻辑。
样式优先级
标签样式的优先级是:单独页面的id(#)样式 >app.wxss中的id(#)样式 >单独页面的class(.)样式>app.wxss中的class(.)样式 >单独页面的标签样式 > app.wxss中的标签样式
监视属性watch:
当监视的属性变化时,回调函数自动调用,进行相关操作
监视的属性必须存在,才能进入监视
监视的两种写法:
new Vue时传入watch配置
通过vm.$watch()监视
immediate初始化时让handler调用一下
深度监视:
Vue中的watch默认不监视对象内部值的变化(只监视一层)
配置deep:true可以监视对象内部值变化(监视多层结构)
监听watch:
一个状态的改变 影响多条数据,没有return
没有缓存
可以异步
不传参
bindchange是一个小程序中的事件绑定属性,用干临听某个组件的变化事件。当该组件的状态发生变化时,绑定在bindchanae 的事件函数将被触发执行。
例如,可以在一个input组件上使用bindchange属性绑定一个函数,当用户在输入框中输入内容并且内容发生变化时,该函数就会被调用。
通常情况下,bindchange的使用场景包括但不限于表单输入、选择器的选中状态等需要监听变化的组件。
流程(发送请求-拿到数据-渲染页面
1. 发送请求:在微信小程序中,你可以使用`wx.request`方法来发送网络请求。这个方法接受一个对象作为参数,该对象包含请求的URL、请求方法(GET、POST等)、请求头、请求数据等信息。
2. 拿到数据:在请求成功的回调函数中,你可以通过`res.data`拿到服务器返回的数据。这些数据通常是一个JSON对象或者数组,你可以根据需要进行处理。
3. 渲染页面:拿到数据后,你可以使用微信小程序的数据绑定机制来渲染页面。首先,你需要在页面的`.js`文件中定义数据,然后,在页面的`.wxml`文件中使用`{{}}`语法来绑定数据,
这样,当数据发生变化时,页面会自动更新以显示最新的数据。
wx:for / v-for的用法
wx:for
在组件上使用 wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。默认数组的当前
项的下标变量名默认为 index,数组当前项的变量名默认为 item
wx:if
1、在框架中,使用 wx:if="" 来判断是否需要渲染该代码块。
2、也可以用 wx:elif 和 wx:else 来添加一个 else 块:
<view wx:if="{{length > 5}}"> 1 </view>
<view wx:elif="{{length > 2}}"> 2 </view>
<view wx:else> 3 </view>
3、block wx:if
因为 wx:if 是一个控制属性,需要将它添加到一个标签上。如果要一次性判断多个组件标签,可以使用一个
<block/> 标签将多个组件包装起来,并在上边使用 wx:if 控制属性。
<block wx:if="{{true}}">
<view> view1 </view>
<view> view2 </view>
</block>
注意: <block/> 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。
4、wx:if和hidden
因为 wx:if 之中的模板也可能包含数据绑定,所以当 wx:if 的条件值切换时,框架有一个局部渲染的过程,
因为它会确保条件块在切换时销毁或重新渲染。
同时 wx:if 也是惰性的,如果在初始渲染条件为 false,框架什么也不做,在条件第一次变成真的时候才开
始局部渲染。
相比之下,hidden 就简单的多,组件始终会被渲染,只是简单的控制显示与隐藏。
一般来说,wx:if 有更高的切换消耗而 hidden 有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,
用 hidden 更好,如果在运行时条件不大可能改变则 wx:if 较好。
hidden=""的判断条件与wx:if=""相反。
完成的微信小程序页面有