微信小程序behavior实现多继承,observer,导航栏,日期,禁用,栈溢出【诗书画唱】
目录:
例子1:把写死的期刊号和当前日期写成活的,写成可实时更新日期等等

给epsoide声明一个期刊号index属性,而日期的内容不必依赖父子组件传值,因为日期是共用的部分
为什么要声明期刊号index为String?因为我们要进行判断,如果期刊号小于10,就要在数字前面加个0
只要组件的属性的值改变,就会触发observer对应的函数(下面的图示中一开始index是空值,后面index变成8的值,所以会触发observer对应的函数)
observer
如果你做了让数据变化的逻辑处理,想界面实时更新数据,可以使用this.setData{_XXX:YYY}之类的方法
一些要调用的变量,如果是要从别的地方传值获取就写properties里面,如果是直接获取,没必要从别的地方传值获取,就写data中就可以。
对于字符串的变量,和properties中可以声明type为String不一样,在data中不可以声明为String,而是按照下图的设置来设置初始值为空字符串
常常查看微信小程序官网的API文档,同时方法等等是会更新的,有些方法可能会变,比如生命周期函数,所以要常常查看最新的API文档等等,如果不知道代码写哪里,很多时候可以写生命周期函数里面
例子2:实现导航栏

下面的给组件定义的属性赋值是和properties搭配使用,来达到传值的效果的
之后的话,我就是给导航栏设置样式,进行弹性盒子布局
例子3:实现导航栏的切换图片效果,左翻页和右翻页分别在第一页和最后一页的绑定了事件的用于切换的图标(图片)变灰色,其余情况都是黑色,实现禁用效果

下面是给导航栏navi组件的左翻页和右翻页的图标绑定事件
用控制台打印语句测试,绑定的事件是否有效
例子4:为“切换期刊的同时,期刊界面变成对应的内容(实现music,movie,sentence组件)的功能”做准备,behavior实现多继承,通过调用behavior,让很多组件都拥有behavior中的属性,减少声明属性的代码

Behavior(行为)实现多继承,Behavior可以实现类似于接口的效果,可以让很多组件都有通过调用声明了属性的Behavior相关的文件,来让很多组件拥有Behavior相关的文件中声明了的属性,可以减少声明属性的代码
例子5:实现例子1到例子4效果的代码
Q&A:个人做项目时遇到的问题和我是如何解决遇到的问题的
Q:如何解决stack栈溢出等的问题
讲义

例子1:把写死的期刊号和当前日期写成活的,写成可实时更新日期等等

给epsoide声明一个期刊号index属性,而日期的内容不必依赖父子组件传值,因为日期是共用的部分

为什么要声明期刊号index为String?因为我们要进行判断,如果期刊号小于10,就要在数字前面加个0

只要组件的属性的值改变,就会触发observer对应的函数(下面的图示中一开始index是空值,后面index变成8的值,所以会触发observer对应的函数)

observer

如果你做了让数据变化的逻辑处理,想界面实时更新数据,可以使用this.setData{_XXX:YYY}之类的方法

一些要调用的变量,如果是要从别的地方传值获取就写properties里面,如果是直接获取,没必要从别的地方传值获取,就写data中就可以。
对于字符串的变量,和properties中可以声明type为String不一样,在data中不可以声明为String,而是按照下图的设置来设置初始值为空字符串

常常查看微信小程序官网的API文档,同时方法等等是会更新的,有些方法可能会变,比如生命周期函数,所以要常常查看最新的API文档等等,如果不知道代码写哪里,很多时候可以写生命周期函数里面







例子2:实现导航栏


下面的给组件定义的属性赋值是和properties搭配使用,来达到传值的效果的

之后的话,我就是给导航栏设置样式,进行弹性盒子布局

例子3:实现导航栏的切换图片效果,左翻页和右翻页分别在第一页和最后一页的绑定了事件的用于切换的图标(图片)变灰色,其余情况都是黑色,实现禁用效果

进行判断的逻辑

下面的isFirst是cmpNavi(即为cmp-navi组件,即为navi组件)中的属性,下面赋值的过程是不可以写死的,我这里只是暂时写死,测试其效果是否有用

下面是给导航栏navi组件的左翻页和右翻页的图标绑定事件

用控制台打印语句测试,绑定的事件是否有效


下面的话绑定了自定义事件



例子4:为“切换期刊的同时,期刊界面变成对应的内容(实现music,movie,sentence组件)的功能”做准备,behavior实现多继承,通过调用behavior,让很多组件都拥有behavior中的属性,减少声明属性的代码


加上切换期刊号的后台代码

准备好素材


Behavior(行为)实现多继承,Behavior可以实现类似于接口的效果,可以让很多组件都有通过调用声明了属性的Behavior相关的文件,来让很多组件拥有Behavior相关的文件中声明了的属性,可以减少声明属性的代码





behavior

例子5:实现例子1到例子4效果的代码




// components/classic/movie/index.js
import classicBeh from '../classic_beh.js'
Component({
behaviors: [classicBeh],
/**
* 组件的属性列表
*/
properties: {
//被behaviors: [classicBeh]取代的部分 START
// content:String,
// img:String,
//被behaviors: [classicBeh]取代的部分 END
},
/**
* 组件的初始数据
*/
data: {
icon: './images/movie@tag.png'
},
/**
* 组件的方法列表
*/
methods: {
}
})







// components/epsoide/index.js
Component({
/**
* 组件的属性列表
*/
properties: {
//关于日期和期刊部分 START
index: {
type: String,
//index属性被修改了就会触发这个函数
observer: function(newVal){
//newVal修改后的值
//oldVal修改前的值
let i = newVal < 10 ? '0' + newVal : newVal
this.setData({
_index: i
})
}
}
//关于日期和期刊部分 END
},
/**
* 组件的初始数据
*/
data: {
//关于日期和期刊部分 START
_index: '',
year: '',
month: '',
cmonths: ['一月','二月','三月','四月','五月','六月',
'七月','八月','九月','十月','十一月','十二月']
},
lifetimes: {
attached(){
let now = new Date()
this.setData({
month: this.data.cmonths[now.getMonth()],
year: now.getFullYear()
})
}
},
//关于日期和期刊部分 END
/**
* 组件的方法列表
*/
methods: {
}
})



/* components/epsoide/index.wxss */
.container {
display: inline-flex;
height: 60rpx;
flex-direction: row;
}
.plain {
font-size: 32rpx;
}
.index {
font-size: 60rpx;
line-height: 60rpx;
font-weight: 800;
margin-right: 14rpx;
}
.index-container {
display: flex;
flex-direction: row;
align-items: baseline;
}
.date-container {
display: flex;
flex-direction: column;
margin-top: 6rpx;
}
.month {
font-size: 24rpx;
line-height: 24rpx;
}
.year {
font-size: 20rpx;
}
.line {
height: 44rpx;
border-left: 1px solid black;
margin-right: 14rpx;
}


// components/like/index.js
Component({
/**
* 组件的属性列表
*/
properties: {
//如果不声明变量数据类型,那么数据的内容可能无法在别的文件中调用
count: Number,
like: Boolean,
//自己写的代码 START
// bookImage:String
//自己写的代码 END
},
/**
* 组件的初始数据
*/
data: {
yesSrc: '/components/like/images/like.png',
noSrc: '/components/like/images/like@dis.png',
},
/**
* 组件的方法列表
*/
methods: {
onLike(){
let count = this.properties.count
let like = this.properties.like
//自己写的代码 START
// let bookImage= this.properties.image
//自己写的代码 END
count = like ? count - 1 : count + 1
//更新组件的状态
this.setData({
count,
like: !like,
//自己写的代码 START
// bookImage:bookImage
//自己写的代码 END
})
//关于数据库和页面的点赞数同步更新的部分 START
//触发绑定在like组件上的自定义事件
//1、需要触发的自定义事件的名字
//2、自定义事件需要传递的数据对象
//3、配置事件的属性
this.triggerEvent('myLike',{
state: this.properties.like ? 'like' : 'cancel',
nums: this.properties.count
},{})
//关于数据库和页面的点赞数同步更新的部分 END
}
}
})


// components/navi/index.js
Component({
/**
* 组件的属性列表
*/
properties: {
title: String,
isFirst: Boolean,//是否是第一期
isLatest: Boolean,//是否是最后一期
},
/**
* 组件的初始数据
*/
data: {
disLeftSrc: 'images/triangle.dis@left.png',
leftSrc: 'images/triangle@left.png',
disRightSrc: 'images/triangle.dis@right.png',
rightSrc: 'images/triangle@right.png'
},
/**
* 组件的方法列表
*/
methods: {
onLeft(){
if(!this.properties.isLatest) {
//触发navi组件的自定义事件myLeft
this.triggerEvent('myLeft',{},{})
}
},
onRight(){
if(!this.properties.isFirst) {
this.triggerEvent('myRight',{},{})
}
}
}
})


<!--components/navi/index.wxml-->
<view class="container">
<image class="icon" src="{{isLatest ? disLeftSrc : leftSrc}}" bind:tap="onLeft"/>
<text class="title">{{title}}</text>
<image class="icon" src="{{isFirst ? disRightSrc : rightSrc}}" bind:tap="onRight"/>
</view>

/* components/navi/index.wxss */
.container {
width: 600rpx;
height: 80rpx;
display: inline-flex;
background-color: #f7f7f7;
border-radius: 2rpx;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.icon {
height: 80rpx;
width: 80rpx;
}
.title {
font-size: 28rpx;
}

//导航栏的左翻页和右翻页部分 START
onNext(){
console.log('获取下一期的期刊数据')
},
onPrev(){
console.log('获取上一期的期刊数据')
},
//导航栏的左翻页和右翻页部分 END

"cmp-navi":"/components/navi"

<!--pages/classic/index.wxml-->
<view class="container">
<view class="header">
<cmp-epsoide class="epsoide" index="{{classicData.index}}"></cmp-epsoide>
<!-- 下面的话就是调用了点赞的组件: -->
<cmp-like count="{{classicData.fav_nums}}" like="{{classicData.like_status}}" bind:myLike="onLike"></cmp-like>
</view>
<cmp-movie content="{{classicData.content}}" img="{{classicData.image}}"></cmp-movie>
<cmp-navi class="navi" title="{{classicData.title}}" isFirst="{{false}}" isLatest="{{true}}" bind:myLeft="onNext"
bind:myRight="onPrev"></cmp-navi>
</view>


/* pages/classic/index.wxss */
.container{
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
}
.header {
width: 100%;
display: flex;
flex-direction: row;
height: 100rpx;
align-items: center;
justify-content: space-between;
border-top: 1px solid #f5f5f5;
border-bottom: 1px solid #f5f5f5;
}
.epsoide {
margin-left: 20rpx;
margin-top: 4rpx;
}
.like {
margin-top: 6rpx;
}
.navi {
position: absolute;
bottom: 40rpx;
}




Q&A:个人做项目时遇到的问题和我是如何解决遇到的问题的
Q:如何解决stack栈溢出等的问题

A:



讲义
准备:后台代码处理
一、创建新项目和页面
二、app.json配置导航栏
三、定义和使用点赞组件
"四、classic在生命周期函数中请求后台数据
设置-项目设置-勾选不校验..."
五、封装Http工具类。
六、将classic页面的数据传递到like组件中(父组件传数据到子组件)
七、实现movie组件
八、like组件传递数据到classic页面(子传父实现自定义事件)
"九、epsoide组件(组件的生命周期函数以及data和properties定义数据的区别)
data和properties会被合并成同一个对象,如果有同名属性,会使用properties中定义的属性
期刊号补零(observer函数)"
"十、初步完成导航组件
获取数据:title,isFirst和isLatest
自定义导航事件onLeft,onRight
禁用左翻页和右翻页"
十一、初步实现music组件和essay组件
十二、提取组件的公共部分(组件的行为Behavior实现多继承)
"十三、初步实现期刊切换前一期效果(后台getClassic实现)
classic页面的onPrev"
"十四、根据index判断是第一期还是最后一期
classicModel中的isFirst和isLatest方法,缓存(Storage)最新期刊号_setLatest方法"
"十五、实现期刊切换后一期效果
classic页面的onNext
onPrev和onNext整合"


