• 忘掉天地
  • 仿佛也想不起自己
bingliaolongBingliaolong  2024-05-14 00:37 Aet 隐藏边栏 |   抢沙发  6 
文章评分 2 次,平均分 5.0

结构

  1. index
    1. car.png
    2. index.js
    3. index.json
    4. index.wxml
    5. index.wxss
  2. app.js
  3. app.json
  4. app.wxss

index.js

  1. app是获取到的全局的应用程序实例
    1. 这里虽然没用到,但是它确保了应用程序实例被正确获取了
  2. javascript里面的this,通常指向当前执行上下文的对象
    1. 这里小程序里面的this,指向当前页面对象
    2. 也就是Page构造函数的实例
    3. 另外,Page对象的生命周期函数中,例如onLoad等这些函数,this指向的是当前页面的对象
  3. this.position = 这些代码在这个函数内部定义并初始化的一些属性
    1. 这些属性将被绑定到页面对象上,并且可以在页面的其他方法中访问和操作
  4. 页面的生命周期一
    1. 页面生命周期指的是小程序中页面对象的生命周期,页面对象是由 Page 构造函数创建的实例
    2. 这些页面的实例是由微信客户端来创建和管理的
    3. 页面生命周期函数是指在页面不同阶段执行的特定函数,用于执行页面相关的逻辑操作
    4. onLoadonShowonReadyonHideonUnload
  5. 页面的生命周期函数
    1. 比如onLoad它是页面加载时触发的函数之一,表示页面被加载时执行的逻辑
    2. 当页面被加载时,微信客户端会创建页面的实例,并执行onLoad生命周期函数
      此时页面的数据和状态通常是未初始化的
    3. 然后执行onLoad函数,微信客户端会在页面创建完成后立即调用onLoad函数,执行其中的逻辑代码
      在这个函数中,一般进行一些初始化工作,例如获取页面参数初始化数据,发送网络请求等
    4. onLoad函数执行完成后,微信客户端会开始渲染页面,并等待页面渲染完成
      在页面渲染过程中,微信客户端会加载页面的布局、样式和资源,并将其显示在屏幕上
    5. 当页面渲染完成后,微信客户端会触发onReady生命周期函数
      表示页面渲染完成,可以进行交互操作了
  6. 页面的生命周期二
    1. 页面隐藏意味着当前页面不再处于前台显示状态,用户无法看到该页面
      通常是当前页面跳转到其他页面时,当前页面会被隐藏,新页面显示在前台
      当用户点击了底部的tab切换了页面,当前页面会隐藏
      当用户按下设备的home或切到其他应用时,当前页面会被隐藏
    2. 页面销毁
      当页面被redirectTonavigateBack到上一个页面时,当前页面实例会被销毁
      当小程序被关闭时,所有页面实例都会被销毁
      当页面通过调用wx.reLaunch重新加载时,当前页面被销毁,并重新创建一个新的页面实例
      当页面的onUnload生命周期函数被调用时,表示页面即将销毁
  7. 代码里渲染了小球和汽车,线程的问题
    1. 通常情况下,小程序的渲染是由主线程负责的,它们是在一个线程里渲染的
    2. 它们是在渲染层渲染的,而发出渲染请求的onLoad这儿,是在逻辑层
  8. 关于onLoad函数里面的渲染循环
    1. 渲染循环会一直执行渲染任务,,但是它不会阻塞在onLoad这个函数里面,因requestAnimationFrame是一个异步操作,他是向渲染层发出了一个绘制请求
    2. 一旦渲染层收到了绘制请求,它会开始执行相应的绘制工作
      包括渲染页面的布局、样式和资源,执行动画效果等
  9. 关于canvas
    1. wx.createSelectorQuery()创建了一个选择器查询对象
      用来查询页面中的节点信息
    2. select()指定了要查询的idcanvas的节点
      小程序中,节点是页面中的组件或者dom元素
    3. fields这里通过指定参数来返回目标节点的节点本身和size信息
    4. exec这里表示直线选择器查询,并指定了查询完成后要调用的回调函数init
      this.init.bind(this)就是表示将this.init函数绑定到当前页面对象上
  10. 下面代码中,init函数定义后作为参数传给了Page去构造,为什么还需要显示绑定?
    1. 为了确保在init函数内部能够正确访问到页面对象的属性和方法,所以需要显示绑定
    2. 因为javascript中,函数的执行上下文(也就是this),是在函数被调用时确定的,而在上面的代码中,init是作为回调函数传给Page的构造函数的,因此当init被调用时,它的执行上下文this的值并不是页面对象本身,而是触发回调的事件或对象决定的
    3. 如果没有绑定,那么在init函数中访问页面对象的属性或方法可能会出错,因为this的值不是页面对象
    4. 通过显示绑定,可以将init函数绑定到指定的执行上下文上,确保init函数内部访问到的this值始终指向页面对象,从而保证了函数内部的正确执行
  11. 再理解一下上面的点
    1. 我们比较清晰的一个点是onLoad是由微信客户端调用的,当页面创建完成后,微信客户端会调用这个回调函数
    2. 而到了onLoad函数内部时,this却是页面对象
    3. 为什么还要显式去绑定
      因为在javascript里面,函数是可以脱离对象存在的,它们可以作为单独的实体被传递、存储或调用
      当函数作为参数传递给其他函数时,或者以其他方式进行引用时,它们可能会丢失原始对象上下文(即函数内部的this指向)
    4. 在这里的代码中,虽然init函数被定义为Page对象的方法,但是当它作为参数传递给exec函数时,它实际上成为了exec函数的一个独立的回调函数
    5. 而在这个独立的回调函数内部,this的上下文可能会丢失,它不在指向Page对象
      因此,为了保证init内部的this指向正确,需要显式绑定
  12. this.init.bind(this) 那么这句代码里面,前面的this和后面this分别是谁
    1. this.init表示要绑定的函数是当前页面对象中的init函数
    2. bind(this),这里的this表示的是当前页面对象,指向当前页面的实例
  13. this.init.bind()这个bind函数是哪里来的,返回了什么
    1. bindjs中的一个内置函数,它是函数对象的一个方法
    2. 这个方法用于创建一个新的函数,新函数的this值被绑定到指定对象,并且在调用时无法改变
    3. bind方法不会立即调用原函数,而是返回一个新函数,这个新函数可以稍后被调用
  14. 关于onLoad等生命周期函数如果不定义会怎么样
    1. 如果在 Page 中不定义页面生命周期函数(如 onLoadonShowonReady 等),微信小程序客户端会默认认为你没有对应的逻辑需要执行
    2. 在这种情况下,微信小程序客户端会跳过这些生命周期函数的调用,不会执行任何与这些生命周期函数相关的逻辑
  15. init的参数
    1. exec方法会在查询完成时,会调用之前那个回调函数(即通过bind新建的回调函数)
      它会将查询结果作为参数传递给这个回调函数
  16. getSystemInfoSync
    1. 获取当前设备的像素比
      像素比是指设备上物理像素与逻辑像素的比例,反映了设备的屏幕分辨率和设备像素密度之前的关系
    2. 通常情况,值为1表示标准屏幕
      值大于1,表示高清屏幕。值小于1,表示低分辨率屏幕
    3. 根据像素比,将canvas的宽度和高度进行相应调整,使得canvas的绘图区域能够适应设备的像素密度
      假如像素比为2,canvas宽度和高度分别为300px150px,则设置canvas的宽度和高度为600px300px,以保证在高清屏幕上显示效果更清晰
  17. ctx.scale(dpr, dpr)
    1. canvas上下文进行缩放,将绘图环境的坐标系进行缩放,是的绘制的图形能够与设备的物理像素匹配
    2. 可以避免绘制的图形在高清屏幕上出现模糊或失真的情况
  18. const renderLoop = () => {}
    1. 使用箭头函数的语法定义了一个函数,没有显式的参数,但是在函数体内部使用了外部作用域的变量canvasctx,属于隐式引用
    2. requestAnimationFrame(renderLoop)实现了动画效果
      这个方法的作用实际上是通过请求的方式,把回调函数这个参数传给渲染层存起来
      然后,等渲染层真正绘制完一次,准备重新绘制的时候,它会先检查这个回调函数参数,发现有这么个回调函数,然后就调用了
    3. 调用到renderLoop里面的时候,先render渲染,并再次通过请求的方式执行这个回调函数参数
      这样等下次渲染完成的时候,它又循环起来了
    4. 那么什么时候开始的第一次绘制,因为上面设置的回调函数参数只是告诉渲染层下次重绘之前,检查一下这个参数
  19. 在浏览器中,第一次绘制是发生在页面加载完成后进行的
    1. 当页面的dom结构和样式加载完成,并且所有的js代码执行完毕后 ,浏览器会触发页面的第一次绘制
    2. 在微信小程序中,当页面加载完成时,微信客户端会通知渲染层开始进行第一次绘制
      这个时候,渲染层会根据页面的结构和样式,以及js代码的执行情况,开始进行页面的绘制工作
    3. 也就是,走到onLoad这里的时候,表示页面加载工作已经完成了,渲染层是可以开始绘制的
      不过,由于它要给回调函数内部设置参数的机会,所以它会立刻先调用回调函数
      所以正在的第一次渲染工作,渲染层是在onLoad函数执行完毕后开始的
  20. 关于后面的图片加载
    1. 先创建了一个图片对象
    2. 然后设置了一个回调函数,当图片加载完成的时候,会调用这个回调函数
      代码中回调函数的功能就是把img存到页面对象的_img属性里面
    3. 图片的真正加载,当执行到img.src = './car.png'这一行的时,才会开始加载指定路径的图片资源
      关于这一点
      其实是图片对象内部有能力监听图片资源路径的变化,一旦发现变化了,它就会以通知或请求的方式告诉渲染层加载指定的图片资源
  21. 也就是说,在onLoad里面创建了图片对象,并设置了资源路径的图片资源,渲染层会先于页面绘制开始渲染
    1. 但是,这两部分的渲染工作的完成所需要的时间是不确定的,所以谁先完成绘制是不确定的
    2. 也就是说,谁先完成渲染,谁先显示在浏览器上
    3. 另外,关于Z序的问题,谁后创建的,谁在下面,也就是说,在比较靠近的位置,onLoad里面指定的图片,会被网页上绘制的图片盖在上面

code

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

bingliaolong
Bingliaolong 关注:0    粉丝:0
Everything will be better.

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享