YuJian920
3 years ago
5 changed files with 479 additions and 0 deletions
After Width: | Height: | Size: 30 KiB |
@ -0,0 +1,60 @@ |
|||||||
|
![[纯JS实现下拉加载.jpg]] |
||||||
|
|
||||||
|
## 写在前面 |
||||||
|
|
||||||
|
>最近在深入学习Vue框架,想试着模仿[echo回声](https://www.app-echo.com/ "echo回声")的移动端网页写一个网页出来,参考了 uncleLian 大佬的[vue2-echo](https://github.com/uncleLian/vue2-echo "uncleLian/vue2-echo")的一些实现。在这之中遇到了一个问题:uncleLian大佬使用Mint UI组件库来实现页面的下拉加载更多功能,但是我的项目并没有使用Mint UI,所以自然这个功能我就没法直接使用,没有就没有吧,大不了自己动手写,于是就有了这么一篇文章。 |
||||||
|
|
||||||
|
## 实现思路 |
||||||
|
|
||||||
|
实现的思路很简单,就是判断 滚动高度 + 可视高度 是否大于文档高度 |
||||||
|
|
||||||
|
```javascript |
||||||
|
const {} = wino |
||||||
|
window.pageYOffset + window.innerHeight >= document.documentElement.scrollHeight |
||||||
|
``` |
||||||
|
|
||||||
|
如果判断结果为真,就向后端请求更多数据,再使用push方法添加新请求返回的数据 |
||||||
|
|
||||||
|
## 实现过程 |
||||||
|
|
||||||
|
实现每次下拉都返回不同的数据,就要对内容进行分页,根据页数返回不同的数据,但是这个项目并没有后端,后端返回的数据用的是Mock.js模拟的,问题来了Mock.mock在拦截GET请求的时候是无法拦截到url后面带的参数,这样一来就没法在Mock.js对传入的参数进行判断,这时候有两种解决思路,一种是数据分6页就写6个Mock.mock分别拦截不同的页数,使用这种方法的代码会很冗余,还有一种是uncleLian大佬的实现方法:使用for循环让Mock.mock拦截不同的页数 |
||||||
|
<!--more--> |
||||||
|
|
||||||
|
```javascript |
||||||
|
for (let Page = 1; Page <= 6; Page++) { |
||||||
|
let params = { |
||||||
|
'data': [] |
||||||
|
} |
||||||
|
Mock.mock(`${baseURL}/list?Page=${Page}`, function () { |
||||||
|
return params |
||||||
|
}) |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
这样一来就实现了Mock.js对GET请求参数的模拟,光是这样还不行,需要对mock模拟的数据进行拆分,根据页数的不同返回的内容也不同,这里用到了JS的slice方法对数据拆成了6份 |
||||||
|
|
||||||
|
```javascript |
||||||
|
for (let Page = 1; Page <= 6; Page++) { |
||||||
|
let params = { |
||||||
|
'data': [] |
||||||
|
} |
||||||
|
Mock.mock(`${baseURL}/list?Page=${Page}`, function () { |
||||||
|
params.data = listJson.slice((Page - 1) * 6, Page * 6) |
||||||
|
return params |
||||||
|
}) |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
获取到了返回的分页数据,下一步就是要把数据给渲染出来,这里直接使用`push(params)`添加数据是不行的,因为params是一个数组,这里需要用到JS的展开运算(`...`) |
||||||
|
|
||||||
|
```javascript |
||||||
|
this.MusicListJson.push(...params); |
||||||
|
``` |
||||||
|
|
||||||
|
这样就完成了请求数据的添加操作 |
||||||
|
|
||||||
|
## 最后 |
||||||
|
|
||||||
|
解决了实际代码编写时可能遇到的一些难点,剩下的就是添加页数控制,事件触发之类的操作,这样无插件实现JS下拉加载的功能就完成了。 |
||||||
|
|
||||||
|
~~果然使用插件会更方便一些~~ |
@ -0,0 +1,50 @@ |
|||||||
|
![More OOXX With Vue](/images/Vue_on&emit.png) |
||||||
|
|
||||||
|
## 写在前面 |
||||||
|
|
||||||
|
**阅读Vue的源码对深入学习Vue框架是非常有必要的,只知道它表面的用法,而不知道它内部的原理那就说不上是真正熟悉掌握了这一门框架,常常出了问题一头雾水** |
||||||
|
|
||||||
|
**Vue的$emit、$on和Node.js的EventEmitter的使用方法非常类似。** |
||||||
|
|
||||||
|
## 正式开始 |
||||||
|
|
||||||
|
#### $on绑定事件 |
||||||
|
|
||||||
|
> Vue中的$on是一种将函数与事件绑定的方法。 |
||||||
|
|
||||||
|
通过Vue的源代码可以看到,$on调用时需要两个参数,第一个是字符串或数组类型作为事件的名称,第二个是触发事件执行的回调函数。$on第一步会对第一个参数做一个是否为数组的判断,这里可以看出$on允许为多个事件绑定同一个回调函数。 |
||||||
|
|
||||||
|
<!--more--> |
||||||
|
|
||||||
|
如果参数为数组,那么它会使用for遍历这个数组,并进行递归。 |
||||||
|
如果参数为字符串,那么它会在已有的事件(_events)中寻找是否已经存在相同的事件,如果没有会创建并初始化为空数组同时将传递的第二个参数也就是事件被触发时需要执行的回调函数添加进去。 |
||||||
|
|
||||||
|
![$on方法](/images/$on方法.png) |
||||||
|
|
||||||
|
> 总结:$on方法允许为多个事件绑定同一个回调函数,还在里面使用了递归~~自己日自己~~ |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### $emit 触发事件 |
||||||
|
|
||||||
|
> Vue中的$emit是一种触发事件的方法。 |
||||||
|
|
||||||
|
它接受的第一个参数是一个字符串类型,这个字符串参数也就是需要触发的事件名称,第二个参数是触发事件时需要传递的数据。 |
||||||
|
|
||||||
|
第一步$emit会将传递的事件名称转换成小写,并进行一系列的检查判断是否符合语法标准,然后它会在事件列表(_events)中寻找事件对应的回调函数,也就是在$on中传递并添加的回调函数,这里如果没有找到会直接返回,找到了会先进行一次判断,判断回调函数是否大于1,如果大于就把它转换成一个数组。 |
||||||
|
|
||||||
|
这时候第一个参数事件名已经不再需要了,$emit会将其舍弃,并把剩下的数据转换成数组。传递给一个带有try&catch的invokeWithErrorHandling()方法,并在其中使用apply()或call()来调用事件回调函数。 |
||||||
|
|
||||||
|
![调用invokeWithErrorHandling方法](/images/调用invokeWithErrorHandling方法.png) |
||||||
|
|
||||||
|
**invokeWithErrorHandling()方法源代码** |
||||||
|
|
||||||
|
![invokeWithErrorHandling方法](/images/invokeWithErrorHandling方法.png) |
||||||
|
|
||||||
|
> 总结:用$emit方法触发事件允许一个事件有多个回调函数,它们会变成数组被遍历,同时也允许携带参数,它使用了apply()或call()更改作用域来保证参数有效 |
||||||
|
|
||||||
|
**(注意:看源代码可以发现如果回调函数中有返回(return),invokeWithErrorHandling()方法是能拿到并会返回res,但是$emit中没有对这个返回的res进行赋值。)** |
||||||
|
|
||||||
|
## 最后 |
||||||
|
|
||||||
|
别看了,这里我实在不知道写什么好了 |
Loading…
Reference in new issue