微信小程序开发与实践(3)

第四章模块、模块与缓冲

4.1将文章数据从业务中分离

在项目的更目录下新建一个文件夹data,在该文件下新建data.js,将post,js文件中Onload函数下的postList数组的数据整体剪切到data.js文件中,从而避免污染业务层,将所有的内容都堆积在post.js文件中.

4.2小程序的模块

我们还需要使用module.exports向外部暴露一个接口。在data.js文件的最下部添加以下代码:module.exports = { postList:postList}定义好模块后,接下来就可以在其他js文件中引用这个模块。
我们需要在post.js中引入data.js这个模块。
var dataObj = require("../../data/data.js");
代码中的require(path)将模块引入到post.js中,并将模块对象赋值给dataObj。随后在onLoad函数里取出postList数据,并进行数据绑定。

onLoad:function(){
    this.setData({      
    	postList:dataObj.postList    
    })  
}
  • 使用require引用js模块时,要特别注意以下几点:
    (1)被引用的文件一定要带有扩展名js,这一点是不同于页面路径的。
    (2)path路径不可以使用绝对路径,否则会报错。应该使用相对路径。
    (3)在JavaScript文件中声明的变量和函数只在该文件中有效,不同的文件中可以声明相同名字的变量和函数,不会互相影响。
  • 注意为什么是dataObj.postList?因为在输出模块时,我们是将postList作为一个object的属性赋值给module.exports的,所以在require时,得到的也是一个object并非是postList,需要使用dataObj.postList才能获取到真实的文章数据。
    这样的做的好处是,object不仅可以包含postList,你还可以在data.js文件中定义除postList外的其他数据,并作为object的属性一起输出。

4.3小程序的模块化

要使用模板,自然需要先新建模板文件。在/pages/post下新建目录post-item,作为模板文件目录。接着在该目录下新建2个文件:post-item-tpl.wxml和post-item-tpl.wxss。

  • 在post.wxml的顶部使用<import src="templatePath" />来引用模板。对于templatePath路径
  • <template name="postItemTpl"> <template>
  • `定义模块后,其他页面也可以引用该模块
<import src="post-item/post-item-tpl.wxml"/>  
//省略代码
<block wx:for="{{postList}}" wx:for-item="item" wx:for-index="idx" wx:key="key">    
	<template is="postItemTpl" data="{{item}}"></template>  
</block>
  • template的is属性指定要使用哪个模板
  • 函数通常可以定义若干个参数,并从函数调用方传入一些数据。同样,模板也可以传入数据。通过template的data属性,可以向template传递数据。这里将wx:for得到的item传入到template里,这样就可以在template内部使用这个item了。要注意的是,向模板里传入数据,同样要使用{{}}的数据绑定语法,比如data={{item}}。

4.4消除template模板对外部变量名的依赖

  • 消除template对于外部变量名的依赖,可以使用扩展运算符“…”展开传入对象变量来消除这个问题。
  • {{…item}}可以将item这个对象展开。展开之后再传入到template里,就可以保证template不再依赖item这个变量名。

4.5include与import引用模板的区别

  • import需要先引入template,然后再使用template;但include不需要预先引入,直接在需要的地方引入模板即可。
  • 使用include需要将…item转换成item,以及post.wxml中的{{}}中添加item
  • include模式非常简单,就是简单的代码替换,不存在作用域,也不能像import一样使用data传递变量。
  • 如果模板仅仅是静态wxml,不涉及数据的传递,可以使用include。但如果模板涉及数据绑定,还是建议使用import。

4.6CSS模块化

(1)将post.wxss中同文章相关的样式(所有以post-开头的样式)全部剪切到post-item-tpl.wxss文件中,post.wxss文件只留下swiper组件相关的样式。
(2)在定义了postItemTpl后,我们需要在post.wxml中引用它。同样,当定义了模板的wxss文件后,也需要在post.wxss文件中引用它。引用样式文件的语法是@import “src”。

  • 在引入CSS文件时,既可以是以上代码中所使用的相对路径,也可以是绝对路径。保存后,文章列表的样式恢复正常。

4.7使用缓冲在本地模拟服务器数据库

4.7.1应用程序的生命周期

在页面的JS文件中,我们使用Page(object)来注册页面,并在object中指定页面的生命周期函数等。同样,可以在app.js文件中使用App(object)来注册小程序,并在object中指定小程序的生命周期函数等。

  • Object参数有以下几个:
    (1)onLaunch 监听小程序初始化,当小程序初始化完成时,会触发onLaunch(全局只触发一次)。
    (2)onShow 监听小程序显示,当小程序启动,或从后台进入前台显示,会触发onShow,相当于是onHide的反向动作。
    (3)onHide 监听小程序隐藏,当小程序从前台进入后台,会触发onHide。
    (4)onError 错误监听函数,当小程序发生脚本错误,或者API调用失败时,会触发onError并带上错误信息。
    除了以上几个MINA框架给予的特定函数,开发者还可以添加任意函数或数据到Object参数中,用"this"可以访问这些函数和数据。
    可以在开发工具中模拟应用程序的“进入后台”和“从后台显示”这两个动作,从而触发onShow和onHide。开发工具提供了一个【后台】按钮,点击后应用程序将模拟进入后台的效果,再点击一次将从后台返回到前台,

4.7.2使用 Storage缓冲初始本地数据库

进过分析,最好的初始化数据库的时机是在应用程序启动时,在app.js中加入以下代码:

var dataObj = require("data/data.js");
App({
  onLaunch:function(){
    wx.setStorage({      
    	data: dataObj.postList,      
    	key: 'postList',      
    	success:function(res){        
    		//succss      
    	},      
    	fail:function(){
    	        //fail      
    	},      
    	complete:function(){
    	        //compete 
       }    
   })  
  },
})

上述代码中,首先通过require加载data.js文件作为初始化数据。在应用程序生命周期函数onLaunch里,使用wx.setStorage方法将初始化数据存入到小程序的缓存中。

  • 缓存让小程序具备了本地存储数据的能力,它具有以下几个特点:
    (1)只要用户不主动清除缓存,则缓存一直存在。
    (2) 缓存以key:value键值对的形式存在,很类似于服务器流行的memcache或者redis缓存型数据库。
    (3)小程序提供了一系列API用来操作缓存,包括:存储、读取、移除、清除全部和获取缓存信息。每种操作同时都具有同步和异步两个方法。
  • 请注意移除和清除的区别。删除某一个key的缓存,请使用wx.removeStorage方法;而如果想清除所有的缓存请使用wx.clearStorage方法。
  • 要注意,小程序的缓存永久存在,不存在过期时间这个概念。如果想清除缓存,则需要主动调用清除缓存的API。
  • 小程序的本地缓存有容量上限,最大不允许超过10MB。
  • wx.setStorage(object)是一个异步方法,参数object包含key,data和success、fail、complete这3个通用方法(几乎所有小程序的异步API方法中都包含这3个方法)。
  • key用来设置缓存的键,而data用来设置缓存的值,可以是JavaScript对象或者字符串。

所有的缓存操作方法还有一个同步的版本,用同步的方法来改写一下代码清单

var dataObj = require("data/data.js");
App({
  onLaunch:function(){    
  	wx.setStorageSync('postList', dataObj.postList);
 }})
  • 同步方法wx.setStorageSync是在异步方法名wx.setStorage后加了一个后缀“Sync”。不仅仅是setStorage,小程序中几乎所有同步方法的方法名都是在异步方法名后增加了“Sync”。
    同步方法的参数非常简单,它接收2个参数,例如
    wx.setStorageSync(key, data)
    同步方法没有success、fail、complete等回调方法。
  • 上面的代码将在小程序每次启动时,都会执行一次require和一次setStorage。但实际上,缓存如果不主动清除,它是一直存在的,因此完全没有必要每次启动小程序时都执行一次初始化数据库。仅当缓存不存在时,执行一次上述代码即可。
    对数据库进行修改,因为如果每次启动时都重新初始化缓存,那么对数据库的修改就会被初始化数据覆盖,这并不是我们想看到的结果。
App({
  onLaunch:function(){    
  	var storageData = wx.getStorageSync('postList');
  	if(!StorageData){
  	      var dataObj = require("data/data.js");      
  	      wx.clearStorageSync();     
	      wx.setStorageSync('postList',dataObj.postList);        
	} 
  },
})

wx.getStorageSync(key)这个方法可以获取指定key的缓存内容。如果指定key的缓存不存在,则说明数据库还没有初始化。那么此时首先使用wx.clearStorageSync()清除所有的缓存数据,接着再重新读取并设置初始化数据。
以上代码只有当缓存数据库不存在时,才通过require加载data.js文件,并初始化数据库。这样可以避免每次启动应用程序都重复初始化数据库。
虽然通常来说,require都是放在代码文件的顶部,但我们也可以在需要的时候才引用它。
本地缓存数据库,我们就初步建立完成了,后续内容我们还会持续完善这个数据库。

4.9编写缓冲数据库操作类

  • 在项目根目录下新建db文件夹,并在该文件夹下新建DBPost.js文件,并在文件中写入以下代码:
var  DBPost = function(){
  this.storageKeyName = "postList";//所有文章的缓冲键值}
  DBPost.prototype={
    getAllPostData:function(){
        var res = wx.getStorageSync(this.storageKeyName);
        if(!res){
              res = require("../data/data.js").postList;      
              this.execSetStorageSync(res);    
         }    
         return res;  
    },  //本地缓存 保留/更新  
    execSetStorageSync:function(data){    
    	wx.setStorageSync(this.storageKeyName,data);  
    }
};
module.exports={
  DBPost:DBPost
};

上述代码首先定义了一个DBPost构造函数。在构造函数中,我们将post数据在缓存数据库中的key, postList,赋值给构造函数的this变量。注意,这个postList必须同app.js中我们初始化数据库时设置的文章数据的key相同,否则无法读取数据。
随后,我们在构造函数的原型链上添加一个对象,这个对象的所有属性和方法都会被构造函数的实例继承。eg:我们在这个对象中增加了一个getAllPostData方法,这个方法将可以获取缓存数据库中所有的文章数据。
在getAllPostData中,我们做了一个判断,如果缓存不存在将重新加载data.js数据文件,并存入到缓存数据库中。
最后,还是使用module.exports将DBPost输出。

4.10 使用缓冲数据库操作类

现在,我们尝试在post.js中使用上一小节中定义的数据库操作类,将post.js代码更改一下

var DBPost = require("../../db/DBPost.js").DBPost;
Page({
  data: {},
  onLoad:function(){
      var dbPost = new DBPost();
      this.setData({      
      postList:dbPost.getAllPostData()    
      });  
  }})  

需特别注意的是,这里没有直接使用require加载data.js文件,因为data.js现在只是初始化数据,它已经在app.js中被装载到缓存数据库中。所以,我们现在require的是DB操作类所在的模块文件,通过这个类来操作文章数据。
代码第一行同样使用reuqire加载DBPost.js文件,并读取DBPost。
那么,如果要使用DBPost,必须先使用操作符“new”将DBPost实例化。实例化DBPost后,就可以调用该对象的getAllPostData方法,从而读取所有文章的缓存数据并绑定到postList中。

4.11 使用ES6改写缓冲操作类

class DBPost{
  constructor(url){    
  	this.storageKeyName="postList";  
  }  
  getAllPostData(){
      var res = wx.getStorageSync(this.storageKeyName);    
      if(!res){
            res = require("../data/data.js").postList;      
            this.initPostList(res);    
      }    
      return res;  
 }  
 execSetStorageSync(data){    
 	wx.setStorageSync(this.storageKeyName,data) 
 }
};
export{DBPost}

注意Class中定义的两个函数,它们是不需要function关键字的。同时,方法之间不要加“,”,否则会报错。
最后export输出语法也非常简洁,如export {DBPost};
接着,我们再看如何使用ES6版本的DBPost。

import {DBPost} from "../../db/DBPost.js";
Page({
  data: {},  
  onLoad:function(){
      var dbPost = new DBPost();    
      this.setData({      
      	postList:dbPost.getAllPostData()    
      });  
  },
}) 

注意,这里不再使用require来加载DBPost.js这个文件,而是使用ES6导入模块的关键字import将DBPost导入进来。

4.12完善文章数据

在data.js文件中添加两篇文章
-注意:点击开发工具左侧的【缓存】按钮,随后在弹出的菜单中点击【清除数据缓存】,然后再编译项目,发现文章列表里已经有5篇文章了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值