小程序旧岛复盘总结

主要页面

分别是主页流行,书单,书单详情,我的页面(喜欢)
项目gif图部分展示


-

gif图太大,不好一一做展示

对整个项目做一个回顾和复盘总结,整个项目是由12个组件,4个页面构成,我们就按页面的构成来复盘整个项目

首先是首页(流行):

首页主要由like(喜欢)组件,epsoid(月份),classic(电影,音乐,诗歌)组件构成;

like(喜欢)组件:

image.png

image.png

1.组件主要是接收外部传过来的2个参数,一个是喜欢的状态,一个是喜欢的数量,拿到后在组件内直接进行渲染

2.重点是点击事件的逻辑要在父组件进行处理,子组件只负责触发点击事件,并且把当前的状态传给父组件,如果放在组件里面进行业务逻辑处理,那这个组件的复用性就会比较差

//喜欢组件的点击事件处理
    methods: {
        typeoff: function(event) {
            //喜欢的数量
            let num = this.data.num;
            //根据当前like的状态判断是加1还是减1
            num = this.data.like ? num - 1 : num + 1;
            this.setData({
                num: num,
                like: !this.properties.like
            })
            //当前like组件的状态
            let behavier = this.properties.like ? 'like' : 'cancel'
            //激活事件,把like状态传给父组件
            this.triggerEvent('like',{
                behavier:behavier
            },{})
        }

当前月份组件:

image.png

1.主要接收外部穿过来的当前书刊序号,接口返回的数据是中文月份,主要实现的方式通过私有组件中的observer属性实现属性计算,并返回对应的月份

2.observer每当接收数值的这个值发生了变化,他就会执行一次

Component({
    properties: {
        index: {
            type: String,
            //observer类似于vue中的wacth,每当这个index的值发生改变,这个ob函数就会执行
            //无限递归的原因,不断的执行ob函数
            observer:function(newVal,odlVal){
                let val = newVal < 10? '0'+ newVal : newVal;
                this.setData({
                    _index:val
                })
            }
        },
    },
    /**
     * 页面的初始数据
     */
    data: {
        arr: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月','十二月'],
        year:'',
        month:'',
        _index:''
    },
    //第一次加载的时候会执行,在attached加载后就加载onload
    attached:function(){
        let time = new Date();
        this.setData({
            year: time.getFullYear(),
            month: this.data.arr[time.getMonth()]
        })
        console.log(this.data);
    },
})

页面展示组件(电影,诗歌,音乐)

image.png

包括三个子组件音乐,诗歌,电影,他们都有自己的公用属性,img,center属性,后台会根据类容的不同返回不同的type值

在首页接收到返回的数据的时候,通过返回数据中的type值,就可以判断是什么类型

<move wx:if="{{classic.type===100}}" img="{{classic.image}}" centent="{{classic.content}}" />
<music wx:if="{{classic.type===200}}" img="{{classic.image}}" centent="{{classic.content}}" src="{{classic.url}}" />
<essay wx:if="{{classic.type===300}}" img="{{classic.image}}" centent="{{classic.content}}" />

重点:当每次点击的时候都需要发送一次请求,于是想到用本地缓存来进行优化

思路:

1.当每次点击都会发送一次新的请求,把这次的请求数据存在,通过每次请求后返回数据中的index去做为key

2.每次点击的的时候,都会传入一个index到一个方法中,这个方法会根据当前的index的值作为参数去本地缓存中拿数据,如果拿到的数据不为空,就直接把拿到的数据作为参数返回

3.如果拿到的数据为空就发送请求,并且把这次请求存到本次缓存中

class ClassicModel extends HTTP{
    //获取最新的样刊,页面加载的时候
  getlatest(callback){
    this.request({
      url: 'classic/latest',
      success: (data) => {
       callback(data);
       //把最新期刊加载的key存入
       let key = this._name(data.data.index);
       //设置本地存储,把当前最新的的key存入一个data
       wx.setStorageSync(key,data);
       //把当前的index传入方法,方法会根据传入的最新期刊的index,在缓存中设置一个当前的最新期刊对应的index值
       this._setindex(data.data.index);
      }
    })
  }
    //每当点击下一页或者上一页
       _getClassic(index,name,callback){
        // 1.key的名字,如果是向左名字就是class拼接index+1,否则就是减1
        // let key = name == 'next' ? 'classic' + (index + 1) : 'classic'+ (index-1);
        let key = name == 'next' ? this._name(index + 1) : this._name(index-1);
        //取出本地的缓存数据
        let classic = wx.getStorageSync(key);
        //如果取出来的数据是undefined
        if(!classic){
            //发送请求
            this.request({
                url:'classic/'+ index + '/'+ name,
                success:(data=>{
                    //请求成功后
                    //1.记录当前写入的数据名称
                    let key = this._name(data.data.index);
                    //2.写入数据
                    wx.setStorageSync(key,data)
                    //3.把data作为参数传入
                    callback(data)
                })
            })
            //如果取出来的不是空,就直接把取出来的classic数据传入
        }else{
            callback(classic)
        }
    }
}

由于加入缓存出现的bug

由于like(点赞)组件是通过首页请求的数据进行赋值,而首页的切换后续拿到的是缓存中的数据,所以like组件渲染的就一直是缓存的数据

解决方案:定义一个新的中间变量去给like组件赋值,第一次请求到的参数作为默认值传给这个新变量,每次like组件被点击的时候,再把新的返回数据覆盖这个新变量

//绑定新的变量,而不是直接绑定之前的变量
<like-cmp bind:like="onlike" like="{{likeType}}" num="{{likeNum}}" />

书单页面

book组件

image.png

接收两个参数:

1.Obj:book的基本信息(img,title,text)

2.Num:书本喜欢的人数

直接书写html,css然后父组件发送请求后传参数进行渲染

搜索组件

image.png

历史搜索(注释写的非常详细了)

   //回車搜索与点击搜索
        onSearch(event) {
            //组件被点击输入的值
            //回车输入的值
            let text = event.detail.text || event.detail.value;
            //更改页面开关和vulae值双向绑定
            this.setData({
                searchoff: true,
                q: text,
                searchBook:[]
            })
            //加載
            this._loadingT();
            //获取最新的value值
            //将数据读入到缓存中(接收text读入缓存)
            keyword.sethistory(text);
            //书籍搜索的请求
            books.getbook(0, text)
                .then(res => {
                    this.setData({
                        searchoff: true,
                        searchBook: res.data.books
                    })
                    //没有加载到书籍的
                    if (this.data.searchBook.length === 0) {
                        this.setData({
                            empty: true
                        })
                    }
                    //加载开关
                    this._loadingF();
                })
        },

热门搜索

1.请求热门搜索接口后,拿到数据直接渲染短评组件

搜索后的书单懒加载

image.png

思路:
页面下拉到底部,

 /**
     * 页面下拉触底事件的处理函数
     */
    onReachBottom: function () {
        console.log('我被触发了')
        //more是自定义的一个变量,每次触发都进行累加,这样就可以重复触发子组件的observer
        this.data.more +=1;
        this.setData({
            more: this.data.more
        })
        console.log(this.data.more)
    },

主要问题:
如何避免父组件下拉发送多次请求-----通过设置Boolean值来控制请求的状态

如何避免请求数量完成,发送无效请求 ----- 记录当前书籍数量和当前书籍总数量,再加入判断

//监控父组件的下拉事件
        more: {
            type: String,
            observer: function() {
                //页面滚到底部
                //父组件的值改变触发子组件的observer方法             
                //请求参数1:从哪里开始搜索(从当前数组的最后一个下标开始)
                //请求参数2:搜索的内容
                let q = this.data.q;
                let length = this.properties.searchBook.length;
                //请求的开关(避免无效请求)
                console.log(this.properties.searchbuttom)
                //如果开关为trun就可以发送请求
                if (this.properties.searchbuttom) {
                    //发送请求后立马改为false
                    this.properties.searchbuttom = false;
                    //当前的请求数量是否等于数组返回最大的响应数量
                    if (this.properties.start == this.properties.total || length ==0) {
                        //如果相等就不要再发送无效的请求了
                        //同时把请求的开关改为true
                        this.properties.searchbuttom = true;
                        return;
                    } else {
                        //正在加载中
                        this.loadingCenterT();
                        books.getbook(length, q)
                            .then(res => {
                                console.log('我发送了一次请求')
                                //1.拼接数组返回给searchbook
                                console.log(res)
                                let newarr = res.data.books;
                                //2.数组的拼接
                                let arr = this.properties.searchBook.concat(newarr)
                                //3.避免多次无效请求,记录当前的书籍数量和总数量
                                this.properties.start = res.data.start;
                                this.properties.total = res.data.total;
                                //把拼接的数组传给searchBook,渲染页面
                                this.setData({
                                    searchBook: arr
                                })
                            //加载结束
                                this.loadingCenterF()
                                this.properties.searchbuttom = true;
                            })
                        }
                } else {
                    return
                }
            }
        }

页面优化

书单详情页总共发送了3次请求,但是短评的响应速度较慢,页面渲染的速度不统一,

采用promise.all()方法进行优化

  • promise.all()接收一个数组,数组中传入promise实例,当数组中所有的promise实例都请求成功后,才能进行调用

  • 与之对应的还有一个promise.race(),他接收的promise实例只要有一个成功后他就会调用

  • 调用成功的参数中通过下标就可以拿到传入的promise实例调用成功后的数据

//获取详情
        const getinfo = books.getinfo(id);
        //获取点赞
        const getfavor = books.getfavor(id);
        //获取短评
        const getshort = books.getshort(id);
        /**
         * 接收一个参数array
         * array中存放promise实例
         * res返回的是实例对象中的res数据,根据对应的下标可以取到
         */
        Promise.all([getinfo,getfavor,getshort])
        .then(res=>{
            this.setData({
                info: res[0].data,
                favor:res[1].data,
                count:res[1].data.fav_nums,
                short:res[2].data.comments
            })
            //停止加载
            wx.hideLoading()
        })

书单详情页

短评组件:实现输入短评后渲染用户输入的value,如果点击是旧值,就直接进行加1渲染

1.短评组件

image.png

1.考虑到要在搜索组件进行复用,在这个组件中启用了插槽,启用插槽,要在组件的js文件中加入这一段代码

//支持插槽
options:{
        multipleSlots:true
},  

2.当短评被点击的时候,把当前的短评text作为参数传给父组件去做业务处理

  onTap(event){
         this.triggerEvent('gettext', { 
         text: this.properties.text
      })
 },

喜欢页面

image.png

用户授权组件

需要用户点击按钮后才能拉起授权弹窗,但是微信提供的默认按钮的样式是固定的

思路:
1.让子组件来拉起授权,button需要传入的参数open-type让父组件给他
2.当子组件拉起授权后,把授权的用户信息通过自定义事件作为参数传给父组件进行业务处理

1.子组件触发

<button bind:getuserinfo="onGetUserInfo" open-type='{{openType}}'  plain='{{true}}' class="container">
  <slot name="img"></slot>
</button>
methods: {
        onGetUserInfo(event) {
            //授权的信息
            console.log(event.detail)
            this.triggerEvent('getuserinfo', event.detail, {})
        },
    }

2.父组件的业务处理

 //子组件监听授权点击函数
    onGetUserInfo: function (event) {
        //获取用户信息
        let userInfo = event.detail.userInfo
        //如果信息不为空,则已经授权,把信息传入userinfo中
        if (userInfo) {
            this.setData({
                hasUserInfo: true,
                userInfo: userInfo
            })
        }
    },

用户授权检查

 onLoad: function (options) {
        //查看用户是否已经授权
        this.getUserInfo();
        //加载用户喜欢的书籍数
        this.getMyBook();
        //获取用户喜欢的书刊
        this.GetMyfavor();
    },
  //获取用户信息
    getUserInfo(){
        wx.getSetting({
            success: (res) => {
                console.log(res);
                if (res.authSetting['scope.userInfo']) {
                    //这里表示已经授权成功了
                    wx.getUserInfo({
                        success: (res) => {
                            this.setData({
                                hasUserInfo: true,
                                userInfo: res.userInfo
                            })
                        }
                    })
                    //没有授权成功的话
                } else {
                    this.setData({
                        hasUserInfo: false,
                    })
                }
            }
        })
    },

本文正在参加“写编程博客瓜分千元现金”活动,关注公众号“饥人谷”回复“编程博客”参与活动。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容