uni-app既支持vue的生命周期,也支持微信小程序的生命周期

  • 也就是我们可以这样子写
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script>
export default {
onLoad:function(){
//...
},
onShow: function() {
//...
},
onHide: function() {
//...
},
mounted(){
//...
},
}
</script>
  • 所以我们在uni-app路由跳转的时候,除了使用vue-router去跳转和接收参数,我们还可以使用小程序自带的路由跳转和接收参数,比如说wx.navigateTo去进行跳转并在onLoad去接收传递过来的参数(比如query参数)
  • 比如说单击商品图片跳转到商品详情,就可以这样子做,示例如下
1
2
3
4
5
6
7
8
methods:{
//跳转到商品详情页
checkDetail(shopItem){
wx.navigateTo({
url:"/pages/detail/detail?shopitem="+JSON.stringify(shopItem),
})
},
},

那么在商品详情组件就可以这样子接收,通过生命周期onLoad

1
2
3
4
5
6
7
8
onLoad(options){
//接收传递过来的参数
let shopItem = options.shopitem;
//参数存在才解析
if(shopItem){
this.shopDetail = JSON.parse(shopItem);
}
},

uni-app全局对象既可以是wx也可以是uni,并且rpx和upx是一样的效果

  • 看个人习惯吧,其实个人从心理上认为全局对象uniwx兼容性会更好一点在编译的时候

小程序是可以设置placeholder的样式的,但是h5却不可以

  • @官方API-input

  • 主要是通过以下二个属性设置的

    • placeholder-class:指定 placeholder 的样式类,注意页面或组件的style中写了scoped时,需要在类名前写/deep/
      • 字节跳动小程序、飞书小程序、快手小程序不支持
    • placeholder-style:指定 placeholder 的样式
  • 示例

1
<input class="search-input" placeholder="搜索内容在这里" placeholder-class="search-placeholder">
  • 设置的样式
    • 注意层级关系
1
2
3
4
5
6
7
8
9
/* 多级别下与input是同级的 */
.search-input .search-placeholder{
background-color: red;
}
/* 或者直接不通过层级 */
.search-placeholder{
font-size: 25rpx;
color: red;
}

uni-app是有默认样式的,这需要特别注意

  • 比如我们写了一个标签<button></button>
  • 我们打开小程序调试查看,可以看到设置了这么多默认样式,所以我们在设置自己的样式的时候,需要注意默认样式对我们的影响
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
button {
-webkit-tap-highlight-color: transparent;
background-color: #f8f8f8;
border-radius: 5px;
box-sizing: border-box;
color: #000;
cursor: pointer;
display: block;
font-size: 18px;
line-height: 2.55555556;
margin-left: auto;
margin-right: auto;
overflow: hidden;
padding-left: 14px;
padding-right: 14px;
position: relative;
text-align: center;
text-decoration: none;
}

uni-app引入公共样式(css)和小程序引入公共样式(css)

  • uni-app是在App.vue当中去引入
    • 注意,这里需要引入的格式是
    • @import url("地址")
  • 示例代码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//App.vue
<script>
export default {
onLaunch: function() {
console.log('App Launch')
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
}
}
</script>

<style lang="stylus">
/*每个页面公共css */
/* 引入iconfont字体图标*/
@import url("static/iconfont/iconfont.styl");
page
width 100%
height 100%
</style>

  • 微信小程序引入公共样式
    • 注意,这里引入是
    • @import "地址"
  • 示例代码如下引入公共样式在微信小程序当中
1
@import './common/main.wxss';

假如在uni-app开启display后元素没有在一行排列

  • 可以试试看设置下面这二个样式
  • white-space:nowrap:设置元素不换行
  • display:inline-block:设置元素和行内块元素(目的是让元素不单独占据一行)

nodejs模块的引入是怎么引入的,和es6又有什么区别

  • 这里只记录了下简单的,新遇到的问题,具体想看es6的暴露和引入的具体的,可以看我之前写的文章,@地址

es6

引入
  • es6的引入需要在模块的最前面,不可以出现如下代码(使用静态的import会出现的问题)
1
2
3
4
5
import a from "./a.js"

function getNumber(){
import b from "./b.js";
}

否者出现就会报错,提示导入声明只能在模块的顶层使用

  • 那是因为你使用了静态的import,标准用法的 import 导入的模块是静态的,会使所有被导入的模块,在加载时就被编译(无法做到按需编译,降低首页加载速度)。有些场景中,你可能希望根据条件导入模块或者按需导入模块,这时你可以使用动态导入代替静态导入
    • 在vue路由的时候,经常使用这种动态的导入方法
1
2
3
4
5
6
7
8
9
10
import('/modules/my-module.js')
.then((module) => {
// Do something with the module.
});
//这种使用方式也支持 await 关键字。
async function getNumber(){
const b = await import("./b.js");
console.log(b);
}
getNumber();
暴露
  • es6的暴露出去的都是对象
    • 在引入的时候除了默认暴露,其他的基本上都需要解构赋值才可以

nodejs

引入
  • nodejs是commojs的规范,他可以在使用到的时候再引入
  • 比如下面有一个需求,就是是当用户请求某一个路由的时候,我才去读取数据并返回给用户,这个时候就可以体现出nodejs引入的好处了,是代码执行到这一段的时候才去引入
1
2
3
4
5
6
// 分类页
router.get("/getCategoryData",(ctx)=>{
//读取分类页数据,代码执行到这一行才开始引入
const categoryData = require("../datas/categoryDatas.json");
ctx.body = categoryData
})
暴露
  • node提供了二种暴露方式

    • module.exports
    • exports
  • 不想看下面的可以记住这句话就可以,不要使用exports去暴露,使用module.exports去暴露

  • exportsmodule.exports是一个引用

    • 当通过exports去改变内存块里内容时,module.exports的值也会改变
    • 当通过module.exports去改变内存块里内容时,exports的值也会改变
    • 当module.exports所指向的地址被改变的时候,exports不会被改变
    • 当exports所指向的地址被改变的时候,module.exports不会被改变
  • node的暴露可以简单理解为暴露什么,引入的就是什么

暴露引入如下-暴露什么,引入的就是什么

nodejs的fs.readFileSync

  • 在没有指明编码方式的情况下,默认是Buffer

  • 官方解释

1
If the encoding option is specified then this function returns a string. Otherwise it returns a buffer.
  • 示例代码,未指明的时候为buffer流,指明了则为字符串
1
2
3
4
5
6
7
8
9
10
11
const fs = require("fs");
const path = require("path");
// 指明数据类型
var result = fs.readFileSync(path.resolve(__dirname,"data/test.json"),"utf-8");
console.log(result);
console.log(typeof result); //类型为字符串

//未指明数据类型
var result = fs.readFileSync(path.resolve(__dirname,"data/test.json"));
console.log(result);
console.log(typeof result);

设置文本超出二行隐藏

1
2
3
4
5
6
7
8
9
.show {
width: 200px;
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
/* 设置超出几行省略 */
-webkit-line-clamp: 2;
}

关于flex布局justify-content:space-around最后一个不对齐的解决方法和为什么这样子解决是讨论

  • 其实解决也很简单,在最外层添加一个伪类即可

    html结构

    1
    2
    3
    4
    5
    6
    7
    8
    9
      <!-- 外层 -->
    <div class="root">

    <!-- 遍历数据的 -->
    <div v-for="(shopItem, index) in shopList" :key="index">
    <img style="width: 200px;" :src="shopItem.url" alt="" />
    </div>

    </div>

    css解决办法,在root后面添加一个伪类即可解决

    1
    2
    3
    4
    5
    6
    .root::after{
    content: "";
    width: 200px;
    /* 不可以提供高度 */
    /* height: 200px; */
    }

那么为什么设置::after伪类就可以解决呢justify-content所带来的布局问题呢?

  • 当那个循环列表是奇数的时候会出现那个填充框框对吧?

奇数

  • 但是如果是偶数会不会出现这个伪类::after的填充框呢,我们再添加一个项目框框
    • 可以看到,并没有出现这个红色框框(不是我截图没有截到,是真的没有出现红色框框)

偶数

  • 那么为什么呢?就好像知道这个浏览器知道我们需要这个填充内容出现一样
    • 在之前我猜测可能是盒子模型计算出来了伪类::after的宽度,但是我记得盒子模型计算的是针对于块级元素的
    • 后面查看资料说

CSS伪元素::after用来创建一个伪元素,作为已选中元素的最后一个子元素。通常会配合content属性来为该元素添加装饰内容。这个虚拟元素默认是行内元素。

  • 那么肯定不是盒子模型计算的问题了,那么是为什么呢?(下面推断个人想法,可能有误)
    • 后面想了想出现这种情况是什么
      • 1.最后一行没有被填充,有空隙的时候,就会出现伪类的填充
      • 2.当容器最后没有留空的时候,就不会出现伪类的填充
  • 后面查看弹性盒属性,发现了flex-basis

CSS 属性 flex-basis 指定了 flex 元素在主轴方向上的初始大小。如果不使用 box-sizing 改变盒模型的话,那么这个属性就决定了 flex 元素的内容盒(content-box)的尺寸。

flex-basis 默认值为auto

  • 于是我设置伪类::afterflex-basis:0,看看会发生什么,
1
2
3
4
5
6
7
8
.root::after{
content: "";
width: 200px;
/* 不可以提供高度 */
/* height: 200px; */
background: red;
flex-basis:0;
}
  • 可以看到,伪类::after高度都没有,不像前面的一行没有满的情况有填充出现

flex-basis:0为伪类::after设置

  • 我们在将他设置为flex-basis:auto看看会发生什么

flex-basis:auto

  • 当然,由于我们没有设置基础的宽度,所以设置flex-basis:content也是一样的效果

flex-basis:content

  • 甚至设置height:auto是也一样的效果

flex-basis官方解释—由于最初规范中没有包括这个值,在一些早期的浏览器实现的 flex 布局中,content 值无效,可以利用设置 (widthheight) 为 auto 达到同样的效果。

总结

  • 浏览器知道我们需要这个填充内容出现是因为flex-basis默认值为auto,由浏览器为元素计算并选择一个高度或者宽度,当然,假如事先设置了宽度和高度,那么flex-basis:auto是没有用的(这里是没有设置height,所以只讨论height的情况)
  • 所以要多了解了解flex布局呀~~~

axios在某些小程序上用不了,可以用flyio模块

为什么使用jwt加密还可以解密出来

  • 还可以使用https://jwt.io/解密出来
  • 因为jwt不在于加密数据,而在于数据认证
  • jsonwebtoken⽬的不在加密保护数据,⽽是为了认证来源,认证来源,认证来源。JWT不保证数据不泄
    露,因为JWT的设计⽬的就不是数据加密和保护。

v-if可以使用template进行包裹,外面套一层,这样子渲染就不会多出一层div了

图片的alt和title

  • alt
    • 网络错误、内容被屏蔽或链接过期时,会显示alt 属性中的文本
  • title
    • 鼠标悬停时候的提示信息
    • title 属性不是 alt 属性可接受的替代品。并且,避免将 alt 属性的值直接复制到同一幅图片的title 属性上。这样可能会让一些屏幕阅读器把同一段描述读两遍,造成一定程度上的困扰。

更改this的执行的方法

假设有一个函数fn需要改变this执行,要怎么做

  • call,apply,bind方法作用
    • 让任意的函数,成为对象的方法,从而改变this的指向

call方法

  • @mdnwebDoc - call

  • fn.call(this的指向,参数1,参数2,参数3,….)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    function Product(name, price) {
    this.name = name;
    this.price = price;
    }

    function Food(name, price) {
    Product.call(this, name, price);
    this.category = 'food';
    }

    //等同于,至于为什么等于
    //这就要涉及到创建一个构造函数的时候究竟做了什么
    //创建构造函数其实就是在this(新实例化对象上)上添加赋值并返回这个this
    //所以你看构造函数都没有返回值,那是因为系统自动添加了返回值
    //自动添加了return this
    function Food(name, price) {
    this.name = name;
    this.price = price;
    this.category = 'food';
    }
    console.log(new Food('cheese', 5).name);
    // expected output: "cheese"

  • 备注:该方法的语法和作用与 apply() 方法类似,只有一个区别,就是 call() 方法接受的是一个参数列表,而 apply() 方法接受的是一个包含多个参数的数组

语法
1
function.call(thisArg, arg1, arg2, ...)

参数

thisArg

  • 可选的。在 function 函数运行时使用的 this 值。请注意,this可能不是该方法看到的实际值:如果这个函数处于非严格模式下,则指定为 nullundefined 时会自动替换为指向全局对象,原始值会被包装。

arg1, arg2, ...

  • 指定的参数列表

apply方法

语法
1
2
apply(thisArg)
apply(thisArg, argsArray)
参数说明

thisArg

  • func 函数运行时使用的 this 值。请注意,this 可能不是该方法看到的实际值:如果这个函数处于非严格模式下,则指定为 nullundefined 时会自动替换为指向全局对象,原始值会被包装。

argsArray

  • 一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 func 函数。如果该参数的值为 nullundefined,则表示不需要传入任何参数。从 ECMAScript 5 开始可以使用类数组对象。浏览器兼容性请参阅本文底部内容。

bind方法

  • fn.bind(this的指向,[参数1,参数2,…])

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    const module = {
    x: 42,
    getX: function() {
    return this.x;
    }
    };

    const unboundGetX = module.getX;
    console.log(unboundGetX()); //里面的this指向window
    //window里面没有x变量,所以返回undefined

    //更改this的执行,返回一个函数,并赋值给boundGetX
    const boundGetX = unboundGetX.bind(module);
    //执行更改this后的函数
    console.log(boundGetX());//输出42
  • bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。

语法
参数

thisArg

  • 调用绑定函数时作为 this 参数传递给目标函数的值。 如果使用new运算符构造绑定函数,则忽略该值。当使用 bindsetTimeout 中创建一个函数(作为回调提供)时,作为 thisArg 传递的任何原始值都将转换为 object。如果 bind 函数的参数列表为空,或者thisArgnullundefined,执行作用域的 this 将被视为新函数的 thisArg

arg1, arg2, ...

  • 当目标函数被调用时,被预置入绑定函数的参数列表中的参数。

使用reduce却莫名其妙返回一个undefined或者NaN

  • @webdoc-reduce
  • 需要特别注意
    • 1.当没有传入初始值的时候,就以第一个item为初始值,也就是索引为0的item项为初始值
    • 2.每一次循环遍历必须要返回上一次的计算结果(也就是必须要return一个值,不return就会返回undefined从而出现NaN)并将这个返回结果作为下一次的初始化值

代码示例-没有做到每次都返回值

  • 本来是想计算大于8的值的所有数的合,但是却返回了NaN
1
2
3
4
5
6
7
8
9
const array1 = [1, 10, 2, 3, 4, 5, 8, 10];
const initialValue = 0;
let result = array1.reduce((prev, item) => {
if (item >= 8) {
return (prev += item);
}
}, 0);
//返回NaN
console.log("相加结果", result);

正确代码如下 - 做到了每一次都有返回值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const array1 = [1, 10, 2, 3, 4, 5, 8, 10];
const initialValue = 0;
let result = array1.reduce((prev, item) => {
if (item >= 8) {
return (prev += item);
} else {
return prev;
}
}, 0);
//输出28
console.log("相加结果", result);

//或者你可以写的更简单一点
const array1 = [1, 10, 2, 3, 4, 5, 8, 10];
const initialValue = 0;
let result = array1.reduce((prev, item) => {
return (prev += item >= 8 ? item : 0);
}, 0);
//输出28
console.log("相加结果", result);

除了mapState需要手动指明返回什么,其他的mapGetters,mapActions,mapMutations都可以直接写数组(但是开启命名空间后情况是否是这样子不知道)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
computed:{
//映射vuex当中数据 - 开启了模块化
...mapState({
indexData: state => state.home.indexData,
}),
//映射vuex当中数据 - 没有开启模块化
...mapState({
indexData: state => state.indexData,
})
//也可以这样子 - 没有开启模块化
//当映射的计算属性的名称与 state 的子节点名称相同时,我们也可以给 mapState 传一个字符串数组。
//映射 this.count 为 store.state.count
...mapState(["count"])s
},

fly请求微信的code2Session对返回的结果取data项返回的是字符串,而不是对象

  • fly请求微信的code2Session对返回的结果取data项返回的是字符串,而不是对象,我们必须手动去转换下才可以转化为JSON对象,而axios的则不用
    1
    2
    3
    4
    5
    6
    7
    8
    let result = await fly.get("https://api.weixin.qq.com/sns/jscode2session", {
    appid,
    secret,
    js_code,
    grant_type: "authorization_code",
    });
    console.log(result.data);
    console.log("fly时候返回的结果",typeof result.data);

  • 注意的是,axios模块在小程序是用不了的,因为因为axios是基于window身上的XMLHttpRequest的,使用如果想在小程序中使用,可以试试看fly库

当我们修改state当中新添加字段数据的时候,注意修改为响应式数据

  • 比如通过this.$set或者Vue.set

es6简写需要注意

  • es6对象可以简写是key值和变量是一样的名字才可以简写
1
2
3
4
5
6
7
<script>
let name = "李白"
let obj = {
name,
}
console.log(obj);//{name: "李白"}
</script>
  • 这种情况就不能省略,因为后面是字符串

node引入json,自动转换为原生的对象了

  • 如果是在CommonJS模块中加载json文件,只需通过require()函数直接加载即可,即能得到json对象

其他一些小知识点

  • text-align:可以设置图片也可以设置文本,也就是设置内联样式的

  • 图片默认基线对其的,

  • 除了mapState需要手动指明返回什么,其他的mapGetters,mapActions,mapMutations都可以直接写数组(但是开启命名空间后情况是否是这样子不知道)

  • 伪元素是针对元素的一部分内容来设置的,比如说::after

  • 而伪类是针对整个元素来设置的,比如说:hover