微信小程序学习笔记


基础概念

  • 数据驱动
    将差异应用到Dom树上,达到更新UI的目的,意味着只有“修改”的相关属性才会刷新,而没有变化的就不动,避免了小部分字节修改导致全局页面都得刷新一遍的情况。

  • onLoad=>onShow=>onReady。

  • 不要把data中的任意一项的value设为undefined,否则可能会有引起一些不可预料的bug

  • currentTarget为当前事件所绑定的组件,而target则是触发该事件的源头组件

  • 事件触发顺序:handleTap2、handleTap4、handleTap3、handleTap1
    先捕获(从外到内),后冒泡(从内到外

    bind事件绑定不会阻止冒泡事件向上冒泡,catch事件绑定可以阻止冒泡事件向上冒泡。如果将上面代码中的第一个capture-bind改为capture-catch,将只触发handleTap2(capture-catch将中断捕获阶段和取消冒泡阶段)

    <view
      id="outer"
      bind:touchstart="handleTap1"
      capture-bind:touchstart="handleTap2"
    >
      outer view
      <view
        id="inner"
        bind:touchstart="handleTap3"
        capture-bind:touchstart="handleTap4"
      >
        inner view
      </view>
    </view>
  • hover-class属性可改变触摸时的样式

  • 为防止用户极快速度触发两次tap回调,可设个变量如hasClick当作状态锁

  • 预先展示的,如广告、导航栏、大体框架可利用初始渲染缓存

  • 双向绑定
    <input model:value="{{value}}" />页面修改了值后台也会改,可以减少绑定form传值问题了。

值得注意的小问题

块级标签和内联标签

  • 块级标签-行元素

    自带换行
    <h1-h6></h1-h6>,<p></p>,<div></div>

  • 内联标签-内联标签

    处于一行
    <span></span>,<a></a>,<img/>
    1.上下边距设置无效
    2.没有宽度和高度
    3.不会占据多余面积
    4.img标签和块级标签一样,有边距和宽高!所以img标签又叫行内块级标签

  • text-align对于行内元素和行内块级元素可能无效
    原因是:行内元素没有宽高,行内元素的宽高全部来自于内容的长度和高度。
    行内块级元素默认也是没有设置宽高,但是行内块级元素可以设置宽度和高度。一旦设置了宽高以后,只要有剩余空间就可以看到对齐方式的效果。

  • 四种display显示模式

    1. block,以块状标签进行显示
    2. inline,以内联标签进行显示
    3. inline-block,以块状内联标签进行显示 ,类似图片这样的,一行可以有多个,同时具有宽高,内外边距。
    4. none,以隐藏标签进行显示[隐藏起来的标签],类似

杂项备注

iPhone6: 1rpx = 0.5px
微信小程序:1rem=32rpx
web页面1rem=小程序1.25rem=40rpx,1rem=32rpx
wx:for-item=”page” 遍历数组重命名
wx:for-items=”“ wx:for-item=”post” 也可以这样
wx:key更重要的一个作用是保持渲染元素的状态不丢失,例如渲染的switch被选中后,数组发生改变重新渲染,选中状态不丢失。


这占位符字体大小,变大后,会稍稍往下缩一点,反正多调,就能调到光标和占位符符合的大小。
如果两个字体值相同,那占位符会比输入字体高一点。
就离谱,折腾半天不知道这玩意到底怎么回事,姑且这么记着吧。

一些值不能不设,不设置和0结果是不一样的。比如bottom right这种

bottom里的view class无效

判断数据类型

注意,JavaScript一切数据皆对象,所以typeof没用
console.log(post[i][“comment”] instanceof Array);

wx:for

wx:for="{{navbarTitle}}" wx:key="index"

index是下标,item是值

forEach

修改v,可以直接修改原数组
array.forEach((v,i)=>i===index?v.isActive=true);

class里的.



类似这样,加个disabled就能切换图标

.detail_serve_item {
    padding: 6rpx 24rpx 6rpx 0;
    display: inline-block;
    line-height: 1;
    color: #8c8c8c;
}
.detail_serve_item::before {
    content: "";
    display: inline-block;
    vertical-align: middle;
    margin-top: -4rpx;
    margin-right: 12rpx;
    width: 22rpx;
    height: 22rpx;
    background: url();
    background-repeat: no-repeat;
    background-size: 22rpx auto;
}
.detail_serve_item.disabled::before {
/*同时包含detail_serve_item和disabled*/
    background-image: url();
}

注意,写成.disabled.detail_serve_item也是可以的,他们两者并没有什么优先级

line-height 与font-size

data- 大小写问题

data-navbarindex=”“ =》navbarindex
data-navbarIndex=”“ =》navbarindex
data-navbar-index=”“ =》navbarIndex
data-navbar-Index=”“ =》navbarIndex

background问题

  • background-image和background-size 要写一起
    写分支的时候,size要写到分支里而不能写主干,可能是因为有图片才能控制大小,在图片还没有的时候大小无法掌控

forEach里读不到数据不报错

这样报错:arr.push({abc:res.data.data.adfadfasdfasdf})
这样不报错:

res.data.data.forEach((i) => {
   arr.push({abc: i.asdfasdfasdfsd,})

wxs保留小数问题



无语。。。。。。

保留整数问题

{{price|int}}

redirectTo/navigateTo/switchTap 区别

redirectTo:关闭当前页(卸载),跳转到指定页
navigateTo:保留当前页(隐藏),跳转到指定页
switchTap:只能用于跳转到tabbar页面,并关闭其他非tabbar页面,tabbar之间做切换

.then()避免数据没等到情况

.then()前的方法执行完后再执行then()内部的程序,这样就避免了,数据没获取到等的问题。

input和占位符居中问题

height: auto;
font-size: 32rpx;

主要就是height改一改,改成auto省时省力。

get发包里的data问题

wx.request里的get发包,会自动组合data里的param,试了下mock也这样,姑且认为前端都这样。
pyth似乎不会?一些客户端比如burpsuite啥的就该是哪就是哪

wx:key=’index’ 似乎只能用index?


试了下其他参数不生效,蛮怪的

width:100%问题

有可能无效,换成750rpx可以。

以下姑且认为是:不设flex,那就是画出square大小然后拉长。设了那就按照flex样式居中

&&和||

&&运算符优先级大于||
a || b

如果a是true,那么b不管是true还是false,都返回true。因此不用判断b了,这个时候刚好判断到a,因此返回a。
如果a是false,那么就要判断b,如果b是true,那么返回true,如果b是false,返回false,其实不就是返回b了吗。

a && b

如果a是false,那么b不管是true还是false,都返回false,因此不用判断b了,这个时候刚好判断到a,因此返回a。
如果a是true,那么就要在判断b,和刚刚一样,不管b是true是false,都返回b。

this.setData与this.data

this.setData({})用于将数据从逻辑层发送到视图层(异步),同时改变对应的 this.data 的值(同步)。
this.data而不用this.setData({})会造成页面内容不更新的问题。
简而言之就是:需要页面更新必须用this.setData()


写法记录

父传子属性,子传父方法

父传子属性

在父里直接写
goodsid='abcd'
然后在子里设置接收的值

这个值就当做data里的值直接用即可。

子传父方法

子绑定的事件

onNavBarTap(e) {
  this.triggerEvent("jump", { navbarTapIndex });
},

在父了写bind:jump="autoScroll",将子和父联动,执行autoScrol(e)
而传过来的参数在e.detail.navbarTapIndex

背景色占满整个屏幕

page{
background-color:#111;
}

page前面没有点

好看的红色椭圆按钮

.buy {
    margin: 12rpx 24rpx 0;
    font-weight: 700;
    display: block;
    width: 226rpx;
    height: 76rpx;
    line-height: 76rpx;
    text-align: center;
    font-size: 26rpx;
    border-radius: 40rpx;
    background-color: #f2270c;
    color: #fff;
    font-size: 28rpx;
    background-image: linear-gradient(135deg, #f2140c, #f2270c 70%, #f24d0c);
}

不是最后一个子元素

.word:not(:last-child) {}

向右小箭头css直接写

.shop_name::after {
    content: "";
    display: block;
    width: 16rpx;
    height: 16rpx;
    border-top: 2rpx solid #999;
    border-left: 2rpx solid #999;
    transform-origin: 50%;
    transform: rotate(135deg);
    position: absolute;
    width: 12rpx;
    height: 12rpx;
    right: 10rpx;
    top: 50%;
    margin-top: -8rpx;
}

图片和文字对齐

外层的view要加vertical-align: middle;
内层的img也要加vertical-align: middle;

取整

1.导入wxs
2.{{price | Int}}

多行溢出文字变成省略号

不过得确定要几行

display: -webkit-box;
-webkit-line-clamp: 2; //行数
-webkit-box-orient: vertical;

template使用

<template is="showcase-book" data="{{books: recommendBooks}}"></template>

<template name="showcase-book">
    <view wx:for="{{books}}" wx:key="id"></view>
</template>

一行map添加数组


recommendBooks: res[0].data.map((i) => i.book)
挺牛的
map相当于取数组每个元素,后面的lamda表达式相当于return每个数组的i.book

数组去重

利用对象的属性不会重复这一特性,校验数组元素是否重复

function distinct(a, b) {
 let arr = a.concat(b)
 let result = []
 let obj = {}
 for (let i of arr) {
 if (!obj[i]) {
  result.push(i)
  obj[i] = 1
 }
 }
 return result
}

利用Set成员唯一性

function distinct(a, b) {
 return Array.from(new Set([...a, ...b]))
}
//...也是一种运算符

心得积累

多设设页面状态,以便查看异步下的页面情况

this.setData({pageStatus: 'loading'})
function().catch(() => this.setData({pageStatus: 'error'}))

Promise

并非是连贯性的执行完p2执行then之后再执行catch

而是触发了resolve(),状态变成resolve,才允许执行
而且是等着一层(同步)执行完,再执行then。

let promise = new Promise(function (resolve, reject) {
    console.log("Promise");
    resolve();
});

promise.then(function () {
    console.log("resolved.");
});

console.log("Hi!");
// Promise
// Hi!
// resolved.
let promise = new Promise(function (resolve, reject) {
    console.log("Promise");
});

promise.then(function () {
    console.log("resolved.");
});

console.log("Hi!");
// Promise
// Hi!

文章作者: 巡璃
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 巡璃 !
评论
  目录