旧岛小程序学习总结

第4章 flex布局

1、block, inline, inline-block, flex

// 默认样式block(块级元素)
display: inline-block;//一般display属性,我们设置为flex,flex布局

// flex 弹性盒子布局, 容器设置为flex并不会取消容器块级元素的特性
// inline-flex:将对象作为内联块级弹性伸缩盒显示
display: flex;//一旦设置为flex,它里面的子元素就不再是块级元素,子元素设置display是无效的,默认容器里的元素横向排列.

2、flex-direction 排列方式

// row colum row-reverse colum-reverse
flex-direction: column //竖直排列
flex-direction: row-reverse; //横向倒序排列,对齐方式发生改变,靠右对齐

// 如果容器不设置宽高, 宽度默认占满屏幕100%, 高度默认自适应(根据容器里子元素的高度)

3、justify-content 主轴对齐方式, align-items 交叉轴对齐方式

// flex-start flex-end center 
// justify-content独有属性:space-between、space-around(等距分布, 子元素两侧距离相等)
// align-items独有属性: base1line(让相邻元素里面的文字基线对齐)、stretch(让容器里子元素呈现一个拉伸的效果)

4、flex-wrap换行

// 小程序处理: 如果总元素的宽度大于屏幕宽度,然后没有设置让它换行,它会让容器里面的元素重新分配宽度,相当于 总宽度/n个元素 这样一个宽度.
// nowrap(默认,不换行)、 wrap(换行, 换行后的元素平均间距居中显示,消除间距的方法:容器高度等于子元素换行后高度) 

第5章 小程序基础知识与初识小程序组件

1、组件的引入

//在.json写入代码,组件的引入
{
  "usingComponents": {
    "navi-cmp": "/components/navi/navi"
    //"文件名称随便命名" : "用绝对路径/相对路径都行"
  }
}

// 组件的使用,在.wxml重写入代码

2、尺寸单位 px, rpx

告诉设计师,设计UI时最好按照: 750*1334, 用这个尺寸用px和rpx时特别简单, 此时px与设计尺寸2:1的关系, rpx与设计尺寸是1:1的关系;

image组件默认宽度300px, 高度220px;

rpx的优势会根据屏幕自适应, px则尺寸是固定的;

3、设置全局样式(app.wxss)

// 小程序会在每个页面外部自动包裹一层page
// 比如设置全局字体大小,文字样式

// 如果使用了组件, 组件也会集成全局样式
page{
   font-family: PingFangSC-Thin; 
   font-size:16px;
  /* overflow: hidden; */
}

// 不是所有的全局样式都会被组件继承,组件能够继承的样式非常少

4、组件最好不要留有空白间距

// 设置行高 line-height 等于 font-size
font-size:24rpx;
line-height: 24rpx;

5、容器设置自适应

将容器display设置成flex,并不会改变容器块级元素的特性,需要设置宽高,只是改变了容器里子元素的特性. 所以要想让容器自适应宽度,将容器设置为 display:inline-flex;

6、bind: tap 和 catch: tap区别

bind 事件绑定不会阻止冒泡事件向上冒泡;(多用)
catch 事件绑定可以阻止冒泡事件向上冒泡;

第6章 组件数据、事件与属性

1、数据绑定

在.js文件中 
//对对外开发出来的数据(即外部可以修改属性的值),写在properties:{}里面
/*组件的属性列表*/
properties: {
  like:{
    type:Boolean, //类型(必填)
    value:false, //初始值(选填)
    observer:function(){//(选填)
      
    }    
  },
  count:{
    type:Number
  }
}

//对于组件内部所使用的变量,我们会定义在data:{}里面
/*组件初始数据*/
data:{
  //数据绑定
    count1:9
  count2:999
  yesSrc: 'images/like.png'
  noSrc: 'images/[email protected]'
}

在.wxml中使用
//可以使用三元表达式
//

{{like?count1:count2}} 

2、let,var与组件事件应用

// let允许你声明一个作用域被限制在块级中的变量、语法或者表达式, 与var关键字不同的是, 它声明的变量只能是全局或者整个函数块.
// 官方推荐使用let

/*组件的方法列表*/
methods: {
  onLike:function(event){
    let like = this.properties.like
    let count = this.properties.count
    
    count = like?count-1:count+1
    this.setState{//更新数据绑定状态
      count:count,
      like:!like
    }
  }
}

第7章 访问API数据与ES6在小程序中的应用

1、访问API获取数据

想访问外部的URL的话,必须在后台账号中把这个域名添加到合法域名列表中才可以去访问
如果开发阶段不想去设置这个域名的话,我们可以打开小程序开发工具>>设置>>项目设置>>✅不校验合法域名...

2、同步,异步与回调函数

/*生命周期函数--监听页面加载*/
  onLoad: function (options) { // 小程序里的request只有异步没有同步
    console.log(this.data.test)
    let that = this//sp1
    wx.request({
      url:'http://bl.7yue.pro/v1/classic/latest'
      header:{
        appkey:"DFLSAJFLAJASJDFLJAAJD"
        },
      success:function(res){//接收异步成功的回调函数
        console.log(res)
        //在回调函数中,由于作用域发生了改变,此时的this不是指page,如果想让this指代不变,需要下面操作:
            //console.log(this.data.test)   
        console.log(that.data.test)//sp2
        }
        
        //ES6解决this指代的问题:改用箭头函数问题解决
        success:(res)=>{
        console.log(this.data.test)
        }
    })
  },

3、正确理解Promise

promise解决两个问题:1.解决异步嵌套的问题(回调地狱) 2.解决使用异步回调时,无法使用return(return一个结果)的能力

4、const常量、 Module export与import

//在config.js配置文件中,设置常量
export const config = {//const 声明一个固定不变的常量,不能被更改
  api_base_url:'http://bs.7yue.pro/v1/',
  appkey:"KDASFLAKSDJFLSDJLFJAS"
}
export let fun1 = functino(){
  
}
//或者换一个导出方式:
export {config,fun1}

// 在其他.js中导入引用config.js
import {config as config1, fun1} from '../config.js'
// 注意:在import的时候不能使用绝对路径,必须使用相对路径
// 组件的时候,可以使用绝对路径

5、调试代码

打开小程序工具控制台>>Sources>>
xxx.js文件是源文件处理过后的文件,Console打印错误的行号,指的是这个文件里的行号;
xxx.js?[sm]文件,跟我们编写代码文件一样,可以在这打断点,进行调试

第8章 流行页面编码与组件的细节知识

1、继承

import {HTTP} from '../util/http.js'
class ClassicModel extends HTTP {
  getLatest(){
    this.request({
      
    })
  }
}

2、让文字是一个自适应的宽度,并且可换行

max-width: 550rpx

3、自定义事件的激活与监听

/ 在.js文件中,创建自定义事件
/*组件方法列表*/
methods: {
  onLike: function (event) {
    if(this.properties.readOnly){
      return
    }
    let count = this.properties.count
    count = this.properties.like ? count - 1 : count + 1
    this.setData({
      count: count,
      like: !this.properties.like
    })
    //创建并激活一个自定义事件,此自定义事件的目的: 1.通知页面用户点击了like组件 2.除了通知以为还要附加一个状态(用户取消了点赞还是用户进行了点赞)
    //sp1.定义一个变量
    let behavior = this.properties.like ? 'like' : 'cancel'
    //sp2.在onLike中激活这个事件,并且这个事件需要附带behavior这个状态
    //参数一(字符串):自定义事件的名称; 参数二(js对象):传入我们自己定义的属性,其实是在detail的event属性; 参数三(js对象):非自定义属性,有三个属性可设置,查看文档
    this.triggerEvent('likediy', {
      behavior: behavior
    }, {})
  }
}

/在其他.wxml中引入含自定义事件的组件,并监听自定义事件

4、组件的生命周期函数

共5个函数:
cerated: 在组件实例进入页面节点数执行,注意此时不能调用setData
attached: 在组件实例进入页面节点树时执行(可以在此方法测试log用)
ready: 在组件布局完成后执行,此时可以获取节点信息(使用SelectorQuery)
moved: 在组件实例被移除到节点树另一个位置时执行
detached: 在组件实例被从页面节点树移除时执行

5、组件的data与properties

/*组件属性列表*/
properties: {
  index:{
    type:String,
    observer:function(newVal,oldVal,changedPath){//sp0.observer函数的应用
      let val = newVal < 10?'0'+newVal:newVal
      this.setData({//sp1.千万不要在observer中修改自身属性,出现无限递归调用
        _index:val//sp3.用外部变量接收
      })
    }
  }
},
/*组件初始化数据*/
data: {//data里的属性是函数类型,year和month均是函数,不能指定类型,直接给值就行
  year; 0,
  month: ''
  _index:''//sp2.
}
properties和data的属性名不能相同,如果相同会被properties的属性覆盖

6、布局搭建注意事项

1.不要使用id选择器,使用类选择器
2.如果认为容器宽度是占满整个屏幕,那么设置width: 100%;,否则自适应影响布局

第9章 Behavior行为与加入缓存系统优化流行页面

1、禁用事件的技巧

1.如果想让小程序上线和运营,必须是https接口
2.微信小程序开发工具>>点击预览>>手机微信扫描二维码即可预览效果

2、组件的behavior行为(一种代码复用机制)

// behaviors 是用于组件间js代码共享的特性,类似于一些编程语言中的“mixins”或“traits”。
// 编写一个Behavior的方式和编写一个Component的方式基本上是没有区别的,可以当成编写Component来写
/在.js文件中
let classicBeh = Behavior({//定义一个Behavior
  properties:{
    img:String,
    content:String
  },
  data:{
  
    },
  methods:{
    
  }
})
export {classicBeh}

/其他.js文件中引入上面的Behavior
import{classicBeh} from '../classic-beh.js'
Component({
  behaviors:[classicBeh,beh1,beh2],//引入使用Behavior
})

// 对于Behavior多继承的情况:
1.属性和方法重复的话会依照后面引入的behavior会覆盖前面引入的behavior里的属性和方法,比如beh2会覆盖beh1和classicBeh的
2.引用类的属性和方法会覆盖被引用Behavior的属性和方法
3.生命周期函数是个例外,都不会被覆盖,如果重复会依次执行生命周期函数里的方法

3、用Storage将数据缓存到本地保存

_setLatesIndex(index){
    wx.setStorageSync(key, value)//同步写入缓存数据
}

_getLatesIndex(){
  let index = wx.getStorageSync('latest')//同步读取缓存数据
  return index
}
//逻辑变更时,记得清除缓存

第10章 新版Music、组件通讯与wxss样式复用

1、缓存

缓存中寻找 or API获取,写入到缓存中

2、ES6-模板字符串

onLoad: function (options){
  let a = 123
    console.log(`${a}456`)//反引号``
  console.log(`${this.test()}456`)
  //上面两个输出都是 123456
},

test:function(){
  return 123
}

3、ES6-扩展运算符

在.js文件中,使用扩展运算符
onLoad: function (options){
  classicModel.getLeatest((res)=>{
    this.setData({
      ...res //使用扩展运算符(之前是返回成一个classic对象,使用扩展运算符是直接将res里面的数据展开出来)
      // classic:res //使用前
    })
  })
  console.log(this.data)//可以通过这个方法打印使用扩展运算符前后变化
}

在.wxml文件中
//  //使用前

4、组件显示隐藏控制

 /*隐藏movie-cmp组件*/

5、在组件中复用wxss文件—使用模板template

/*引入复用的common.wxss文件*/
@import "../common.wxss";

6、图片变成圆形

.classic-img{
    border-radius: 50%
}

第11章 Promise正确用法与函数签名设计技巧

1、异步处理方案

异步处理方案一: 纯粹callback
异步处理方案二: promise(是一个对象,可以保存状态)
  promise的优势:
    代码风格方面: 1.解决回调地狱 2.解决callback无法return问题
    功能方面: 1.解决多个异步等待合并
异步处理方案三: async await(promise的语法糖) ES2017 小程序不支持

2、Promise基本用法

//Promise 可以理解成一个对象,可以保存状态. 精髓:用对象的方式保存了异步调用的结果
// Promise 第一步
const promise = new Promise((resolve, reject)=>{
  // 异步代码写在Promise的函数中 第二步
  // Promise整个过程状态: 进行中 已成功 已失败 凝固
  // resolve是把进行中变成已成功, 而reject是把进行中变成已失败
  wx.getSystemInfo({//微信内部异步获取用户信息的函数
    success:(res)=>{
      resolve(res)
    },
    fail:(error)=>{
      reject(error)
    }
  }) 
})
代码简写:
const promise = new Promise((resolve, reject)=>{
  wx.getSystemInfo({
    success: res => resolve(res),
    fail: error => reject(error)
  })
})

//接收有两个函数参数: 已成功时的回调函数 失败函数回调
promise.then((res)=>{
  console.log(res)
},(error)=>{
  console.log(error)
})
代码简写:
promise.then(
    res => console.log(res)
  error => console.log(error)
)

3、Promise解决回调地狱例子

// 1. 多个promise函数操作解决嵌套地狱情况
bookModel.getHotList()
    .then((res) =>{
        console.log(res)
        return bookModel.getMyBookCount()//返回promise的异步函数
    })
    .then((res)=>{
        console.log(res)
        return bookModel.getMyBookCount()
    })
    .then((res)=>{
        console.log(res)
        return bookModel.getMyBookCount()
    })
// 2. promise与非promise解决嵌套函数的情况
const promisic = function(func){//把小程序异步回调函数变promise,再执行1操作
  return function(params={}){
    new Promise((resolve, reject)=>{
      const args = Object.assign(params,{
        success:(res)=>{
          resolve(res)
        },
        fail:(error)=>{
          reject(error)
        }
      })
      func(args)
    })
  }
}

第12章 喜欢页面

1、元素的定位类型-position

absolute    
生成绝对定位的元素,相对于 static 定位以外的第一个父元素进行定位。(也就是说absolute想以父元素进行定位,必须父元素position不能为static)
元素的位置通过 "left", "top", "right" 以及 "bottom" 属性进行规定。

fixed   
生成绝对定位的元素,相对于浏览器窗口进行定位。
元素的位置通过 "left", "top", "right" 以及 "bottom" 属性进行规定。

relative    
生成相对定位的元素,相对于其正常位置进行定位。
因此,"left:20" 会向元素的 LEFT 位置添加 20 像素。

static  默认值。没有定位,元素出现在正常的流中(忽略 top, bottom, left, right 或者 z-index 声明)。

inherit 规定应该从父元素继承 position 属性的值。

2、列表渲染—循环遍历


  

或者:(给item添加别名)

  

或者:(消除小程序黄色警告: 为这个列表每一个元素指定一个唯一的标识,key不重复,是数字或字符串.下面这里比如遍历列表的元素是Object类型,用book属性下的id属性作为key;如果遍历的元素是字符串或数字,那么要用*this作为key)

  

3、如果想让容器固定在最上面

.header{
    position: fixed;
    z-index: 99;
}

4、一个页面如何接受外部传递参数

第一个.js页面
/*组件方法列表*/
组件内部跳转(最好不要从组件内部跳转,用事件转从页面跳转下一个页面)
methods:{
  onTap(event){
    const bid = this.properties.book.id
    wx.navigateTo({
      url:`/pages/book-deatil/book-detail?bid=${bid}`
    })
  }
}

要跳转到.js页面
/*生命周期函数---监听页面加载*/
onLoad: function (options){
  // 这样就可以接收到从外部传递过来的bid参数了
  const bid = options.bid
}

5、三种小程序编译模式

1. 普通编译: 每次小程序编译的时候都会打开首页
2. 通过二维码编译
3. 添加编译模式: 可以指定启动页面,还可以设置启动参数(推荐)

6、solt — 插槽

组件内:
.wxml文件


   

.js文件
component({
    
    options:{
        multipleSlots:true
    },
})

外部容器:
.wxml文件


  {{'+'+item.nums}}  

7、自定义组件样式探讨 一:hack方式

/*对小程序内置组件(view text image),从同组件中选择第一个组件进行css样式设置
*/
.comment-container text:nth-child(1){
 /*也可以写成:.comment-container text:frist-child{*/
    background-color: #fffbdd;
}

/*对小程序自定义组件,从同组件中选择第一个组件,内部的view元素进行css样式设置
*/
.comment-container v-tag:nth-child(1) view{
    background-color: #fffbdd;
}
/*上面的后代选择器的写法存在安全隐患,
所以要了解: 子元素选择器(>作用于元素的第一代后代) 后代选择器概念(空格作用于元素的所有后代)
应该用下面的子元素选择器写法比较安全:
*/
子元素选择器写法:
.comment-container > v-tag:nth-child(1) > view{
    background-color: #fffbdd;
}

/*样式修改 随心所欲 hack. 不过违反了开源组件封装的原则(没有通过组件的允许,强行修改组件内部的样式)*/
拓展:
         ...:nth-chil(odd)... 组件里面所有的奇数序号的标签进行选择设置;
         ...:nth-chil(even)... 组件里面所有的偶数数进行选择设置;

8、自定义样式探讨2:外部样式的概念

开源组件 UI : 默认样式 自定义样式
组件属性、slot、externalClass是非常好的组件机制,不违反组件原则

组件属性是对js相关变量的传递;
slot解决的是html/wxml样式传递机制;
外部样式(externalClass)解决css/wxss之间的传递;

9、自定义组件样式3:外部样式的问题

在容器.wxcss中
.ex-tag {
  background-color: #fffbdd;
}
在容器.wxml中:



在组件.js文件中定义外部样式名
Component({
    externalClasses:['tag-class'],//小程序的外部样式可以允许5个外部样式
})

在组件.wxml文件中使用
// 普通样式 外部样式,这两个无法操控谁覆盖谁的样式. 小程序的用意是:普通样式和外部样式你只能选一个使用.

/*外部样式如何强制覆盖普通样式?解决办法如下: !important*/
在容器.wxcss中
.ex-tag {
  background-color: #fffbdd !important;
}

/*总结
与属性传值的区别:这样传值只需要传一个类名,而创建属性需要实实在在的传递样式.
*/

10、外部样式类的使用技巧

在容器.wxss中
.ex-tag1 {
    background-color: #fffbdd !imaprtant;
}
.ex-tag2 {
    background-color: #eefbff !imaprtant;
}
在容器.wxml中

  
    {{'+'+item.nums}}
  


/*在上面应用中推荐使用hank方式;
但如果写开源组件,还是用这种方式*/

第13章 扩展与总结

1、分析换行符 不解析换行的原因

文字中出现\n的原因:
服务器返回的原始数据,是经过编码转义导致的,\n在此服务器原始数据中是\\n
解决方法:
用正则表达式,把\\n换成\n, 在下面2、中会具体解决.

2、在wxml里面编写js或者调用js---(通过wxs实现)

wxs解决的问题是:javascript不能在wxml里面调用方法,wxs可以在wxml里面调用方法,也可以写过滤器

wxs的代码,既可以写在wxml中,也可以像写js一样定义一个单独的文件.例子(解决1、换行符的问题):

在fillter.wxs中
var format = function(text){//wxs虽然语法跟js很像,但不等同于Javascript,是两种不同的语言, 因此不能使用ES6语法.不过跟ES5语法很像,可以当ES5语法来写.

    console.log(text)//会被打印两次,第一次输出undefined,第二次输出内容.也就是说被执行了两次,原因是数据绑定:数据初始化一次,数据更新又一次,所以要做下面判断:
    if(!text){
        return
    }

    //思路用正则\\n 替换成\n
    //此处的正则要查看wxs文档说明使用
    //sp1:创建正则表达式对象
    var reg = getregExp('\\\\n','g') /*参数一:要替换的字符转义\\n 参数二:修饰符模式*/
    //sp2:文本用正则替换(且文章首行加空格)
    //return text.replace(reg,'\n') /*替换为\n*/
  return text.replace(reg,'\n    ') /*替换为\n空格*/
}
module.exports = {//导出
    format:format
}

在容器.wxml中
//导入wxs,这里只能用相对路径导入


    内容简介
    {{util.format(book.summary)}}
    
/*decode解析字符*/

3、段落文字空格设置

.container{
    text-indent: 30rpx;//设置段首空白间距
    font-weight: 500;//字体加粗程度
}

4、在小程序wxs中编写limit过滤器--(设置显示数据不能超过n个)

在.wxs中(可以被多处复用)
var limit = function(array,length){
    return array.slice(0,length)//截取数组
}
module.exports = {//导出
    limit:limit
}

在容器.wxml中
//导入wxs,这里只能用相对路径导入


5、在wxml中编写wxs代码


  var limit = function(array, length) {
    return array.slice(0, length)
  }
  var format = function(text){
    if(!text){
      return
    }
    var reg = getRegExp('\\\\n','g')
    var text = text.replace(reg,'\n     ')
    return text
  }
  module.exports = {
    limit: limit,
    format:format
  }

第14章 搜索与高阶组件

1、并行请求与串行请求--Promise.all与Promise.race

onLoad: function (options){
    wx.showLoading()//加载loading
    // 要等里面n个请求都结束之后才能结束loading
  // .race 竞争; 与all的区别, race指谁先完成了就会执行函数,而all是都执行完了才执行函数
  Promise.all([detail, comments, likeStatus])
    .then(res =>{
        console.log(res)//res数组的返回数据序号对应上面[detail, comments, likeStatus]的Promise序号顺序
        this.setData({
        book: res[0],
        comments: res[1].comments,
        likeStatus: res[2].like_status,
        likeCount: res[2].fav_nums
      })
        wx.hideLoading()//都请求完后,结束loading
    })
}

第15章 代码重构与行为抽象

1、什么时候用户将当前页面滑动到最底部?

方法一: 小程序内置组件 scroll-view
方法二: Page页面的onReachBottom这样一个监听函数(在组件里不能触发此方法)
优先选择onReachBottom实现上拉刷新,不过这个实现起来比较复杂

2、**特别注意setData与直接赋值的区别****

setData是赋值并通知wxml页面更新数据的值;
直接赋值

第16章 高级知识与应用

1、获取用户信息

不需要用户授权就可以显示用户信息的方法:
open-data只是用来显示用户信息的,我们并不能获取到用户信息,只是一个显示作用.
在.wxml中
 显示用户头像

在.wxss中
.avatar-container{
  display: flex;
  flex-direction: column;
  align-items: center;
}

/**
  如果没有overflow: hidden是无法为圆的
**/
.avatar{
  width:120rpx;
  height:120rpx;
  overflow: hidden;/*超出部分隐藏*/
  border-radius: 50%;
  /* margin-bottom: 10rpx; */
}

2、微信授权机制

以前只需调用API,现在调用button组件来弹授权窗:
也就是说微信 希望让用户主动点击button授权

在.wxml中


在.js中
onLoad(options){
  //要判断用户是否授权
 
}

userAuthorized(){
  wx.getSetting({
    success:data=>{
      if(data.authSetting['scope.userInfo']){
         wx.getUserInfo({//只有用户授权了,才可以从这个方法获取到信息
          success:data=>{
            console.log(data)
          }
        })
      }else{
        console.log('error')
      }
    }
  })
}

getUserInfo(event){//只在按钮点击允许授权时才会调用
    console.log(event)
}

3、小程序之间的跳转

/*前提: 这两个小程序必须关联同一个公众号(服务号或订阅号)*/
在.wxml文件中

    

4、页面跳转

Page({
    onTap:function(){
  //  wx.navigateTo({//微信跳转子页面的函数, 触发onHide
  //    url:"../posts/post"
  //  });
    
    wx.redirectTo({//关闭当前页面,跳转到应用内的某个页面, 触发onUnload
      url:"../posts/post"//平行页面
    })
    
    wx.reLaunch({//关闭所有页面,打开到应用内的某个页面, 触发onUnload
      url:"../posts/post"
    })
  },
  
  onUnload:function(){
    consloe.log("页面关闭/卸载")
  },
  
  onHide:function(){
    console.log("页面隐藏")
  }
})

5、传递参数

//此时参数是回调方法
requestUserOpenID({successBack,failBack}){

}
//此时参数是对象
requestUserOpenID({successBack,failBack}){

}

你可能感兴趣的:(旧岛小程序学习总结)