这个结果显然不是我们要的,用户每次点开页面,还要面对一阵子的空白和响应,因为页面启动后不止要响应初始化页面的组件,还有包含在app里的其他组件,这样严重拖慢了页面打开的速度。
更好的结果是页面可以从上到下按顺序流式渲染,这样可能总体时间增长了,但首屏时间缩减,在用户看来,页面打开速度就更快了。网上一些办法大同小异,各有优缺点,所以...本人也在疯狂试验中,静待好消息。
在不同父组件中引用同一子组件时,但是各自需要接收绑定的动态样式去呈现不同的样式,在绑定css style样式这一关上,踩了个大坑:mpvue居然不支持用object的形式传style,起先处于样式一直上不去的抓狂当中,网上对于mpvue这方面的细节也少之又少,后来查找了许多地方,发现class和style的绑定都是不支持classObj和styleObj形式,就尝试用了字符串,果然...改代码改到怀疑人生,结果你告诉我人生起步就是错误,怎能不心痛?...
4.this指向问题与箭头函数的应用
这是vue文档里的原话:All lifecycle hooks are called with their 'this' context pointing to the Vue instance invoking it.
意思是:在Vue所有的生命周期钩子方法(如created,mounted, updated以及destroyed)里使用this,this指向调用它的Vue实例,即(new Vue)。 mpvue里同理。 我们都知道,生命周期函数中的this都是指向Vue实例的,因此我们就可以访问数据,对属性和方法进行运算。
props:{
goods: Array
},mounted: function(options){
let category = [
{id: 0 ,0);">name: '全部' },{1 ,0);">'JAVA'},0);">2,0);">'C++'},0);">3,0);">'PHP'},0);">4,0);">'VUE'},0);">5,0);">'CSS'},0);">6,0);">'HTML'},0);">7,0);">'JavaScript'}
]
this .categories = category
this .getGoodsList(0 )
},0);">methods: {
getGoodsList(categoryId){
console.log(categoryId);
if (categoryId == 0 ){
categoryId = ''
}
wx.request({
url: 'http://localhost:3030/shop/goods/list' , data: {
categoryId: categoryId
},96);"> method: 'POST' ,96);"> success: res => {
console.log(res);
this .goods = res.data.data;
}
})
},}
复制代码
普通函数this指向这个函数运行的上下文环境,也就是调用它的上下文,所以在这里,对于生命周期函数用普通函数还是箭头函数其实并没有影响,因为它的定义环境与运行环境是同一个,所以同样能取到vue实例中数据、属性和方法。 箭头函数中,this指向的是定义它的最外层代码块,()=>{} 等价于 function(){}.bind(this);所以this当然指向的是vue实例。起初并没有考虑到this指向的问题,在wx.request({})中success用了普通函数,结果一直报错“goods is not defined”,用了箭头函数才解决,起初普通函数的this指向 getGoodsList()的上下文环境,所以一直没办法取到值。
5.onLoad与onShow
在进行首页点击商品跳转到详情页时,onLoad()无法获取更新数据。
首先虽然onLoad: function (options) 这个是可以接受到值的,但是这个只是加载一次,不是我想要的效果,我需要在本页面(不关闭的情况下)到另外一个页面在跳转进来,接收到对应商品的数据。
所以需要将代码放在onshow内部, 在每次页面加载的时候都会进行当前状态的查询,查询对应数据的子对象,更新渲染到详情页上。
onShow: function(options){
wx.getStorage({
key: 'shopCarInfo' ,success: (res) =>{
console.log(`initshopCarInfo:${res.data }`)
this .shopCarInfo = res.data ;
this .shopNum = res.data .shopNum
}
})
wx.request({
url: 'http://localhost:3030/shop/goods/detail' ,
method: data : {
id: options.id
},success: res =>{
const dataInfo = res.data .data .basicInfo;
this .saveShopCar = dataInfo;
this .goodsDetail.name = dataInfo.name;
this .goodsDetail.minPrice = dataInfo.minPrice;
this .goodsDetail.goodsDescribe = dataInfo.characteristic;
let goodsLabel = this .goodsLabel
goodsLabel = res.data ;
this .selectSizePrice = dataInfo.minPrice;
this .goodsLabel.pic = dataInfo.pic;
this .goodsLabel.name = dataInfo.name;
this .buyNumMax = dataInfo.stores;
this .buyNumMin = (dataInfo.stores > 0 ) ? 1 : 0 ;
}
})
}
复制代码
了解小程序onLoad与onShow生命周期函数:
onLoad:生命周期函数–监听小程序初始化,当小程序初始化完成时,会触发 onLoadh(全局只触发一次)。
onShow:生命周期函数–监听小程序显示,当小程序启动,或从后台进入前台显示,会触发 onShow。
二、后台数据库及数据存取
1.架设 HTTP 服务
在全局配置文件中: 1).引入koa并实例化
const Koa = require ('koa' );
const app = new Koa()
复制代码
2).app.listen(端口号):创建并返回 HTTP 服务器,将给定的参数传递给Server#listen()。
);
new Koa();
app.listen(3000 );
这里的app.listen()方法只是以下方法的语法糖:
const http = 'http' );
'koa' );
new Koa();
http.createServer(app.callback()).listen(3000 );
复制代码
这样基本的配置完毕,我们就可以用“http://localhost3030+请求地址参数”获取到数据库的值了。
2.Koa-router路由中间件
koa-router 是常用的 koa 的路由库。
如果依靠ctx.request.url去手动处理路由,将会写很多处理代码,这时候就需要对应的路由的中间件对路由进行控制,这里介绍一个比较好用的路由中间件koa-router。
以路由切换催动界面切换,”数据化”界面。
3.建立对象模型
在构建函数库之前,先来聊聊对象的建模。
Mongoose是在node.js异步环境下对mongodb进行便捷操作的对象模型工具。该npm包封装了操作mongodb的方法。
Mongoose有两个特点:
1、通过关系型数据库的思想来设计非关系型数
2、基于mongodb驱动,简化操作
)
const db = mongoose.createConnection('mongodb://localhost/shop' )
复制代码
本地数据库shop中建了分别“地址管理”、“商品详情”、“订单详情”、“商品列表”、“用户列表”五个数据表:
Schema界面定义数据模型:
Schema用于定义数据库的结构。类似创建表时的数据定义(不仅仅可以定义文档的结构和属性,还可以定义文档的实例方法、静态模型方法、复合索引等),每个Schema会映射到mongodb中的一个collection,但是Schema不具备操作数据库的能力。
数据表跟对象的映射,同时具有检查效果,检查每组数据是否满足模型中定义的条件 同时,每个对象映射成一个数据报表,就可用该对象进行保存操作,等同操作数据表,而非mysql命令行般繁琐的操作
以“商品列表”数据表为例:
var Schema = mongoose.Schema;
const listSchema = new Schema({
barCode : String ,categoryId : Number ,characteristic : commission : commissionType : dateAdd : dateStart : id : Schema.Types.ObjectId,logisticsId : minPrice : minScore : name : numberFav : numberGoodReputation : numberOrders : originalPrice : paixu : pic : pingtuan : Boolean ,pingtuanPrice : propertyIds : recommendStatus : recommendStatusStr : shopId : status : statusStr : stores : userId : videoId : views : weight : 4.koa-router“路由库”
)()
const router = new Router();
router.post('/shop/goods/list' ,51); font-weight: 700;">async (ctx,next) => {
const params = ctx.request.body
const Goods = db.db.model('Goods' ,db.listSchema)
ctx.body = await new Promise ((resolve,reject ) => {
if (params.categoryId) {
Goods.find({categoryId : params.categoryId},(err,docs) => {
if (err) {
reject(err)
}
resolve({
code : errMsg : 'success' ,data : docs
})
})
} else {
Goods.find((err,docs ) => {
data : docs
})
})
}
})
})
复制代码
所有的数据库操作都是异步的操作,所以需要封装promise来实现,由此通过POST “http://localhost3030/shop/goods/list”便可访问本地shop数据库了。 这里顺便提一下“ctx”的使用,ctx(context)上下文,我们都知道有node.js 中有request(请求)对象和respones(响应)对象。Koa把这两个对象封装在ctx对象中。 参数ctx是由koa传入的封装了request和response的变量,我们可以通过它访问request和response (前端通过ajax请求http获取数据) 我们可以通过ctx请求or获取数据库中的数据。
Ctx.body 属性就是发送给用户的内容
body是http协议中的响应体,header是指响应头
ctx.body = ctx.res.body = ctx.response.body
5.数据缓存之模型层设置
1).为什么要做数据缓存?
在这里不得不提一句数据缓存的重要性,虽然我是从本地数据库获取的数据,但是由于需要的数据量较多,再者前面说的性能优化还未完成,每次还是有一定的请求时间,没必要每次打开都去请求一遍后端,渲染页面较慢,所以需要将需要经常用到的数据做本地缓存,这样能大大提高页面渲染速度。
2).设置模型层
setGoodsList: function (saveHidden,total,allSelect,noSelect,list) {
this .saveHidden = saveHidden,51); font-weight: 700;">this.totalPrice = total,51); font-weight: 700;">this.allSelect = allSelect,51); font-weight: 700;">this.noSelect = noSelect,51); font-weight: 700;">this.goodsList = list
var shopCarInfo = {};
var tempNumber = 0 ;
var list = [];
shopCarInfo.shoplist = list;
for (var i = 0 ; i < list.length; i++) {
tempNumber = tempNumber + list[i].number
}
shopCarInfo.shopNum = tempNumber;
wx.setStorage({
key: "shopCarInfo" ,51); font-weight: 700;">data: shopCarInfo
})
},复制代码
将需要做本地存储数据的方法封装成一个方法模型,当需要做本地存储时,直接做引用,如今vue、react中多用到的架构思想,都对模型层封装有一定的要求。
bindAllSelect() {
var list = this .goodsList;
var currentAllSelect = this .allSelect
if (currentAllSelect) {
list.forEach((item) => {
item.active = false
})
} else {
list.forEach((item) => {
item.active = true
})
}
this .setGoodsList(this .getSaveHide(),51); font-weight: 700;">this.totalPrice(),!currentAllSelect,51); font-weight: 700;">this.noSelect(),list);
},复制代码
结语:
写这个项目抓狂了很多次,因为很多vue能用的但在mpvue里实现不了,导致走了很多弯路,踩了很多坑,但是程序猿成长不就是在一个个坑里掉下去又爬起来的过程中吗?作文不易,伙伴们能打赏点就打赏点吧... 顺便附上我的项目地址:?“mpvue-demo”?,不过还有很多需要完善的地方,漫漫长路一起走啊!
作者:mosa
原文:https://juejin.im/post/5b548ce8e51d45191d79f8a6?utm_source=tuicool&utm_medium=referral
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!