探索小程序实现菜鸟教程下载_小程序教程视频

随着小程序的发展与功能的逐步完善,越来越多的产品需要小程序与 APP 的功能能有一些共性,社区跨平台的解决方案越来越多,比如 taro 等为代表的把一套代码编译成多端运行的机制,本文会使用 Swift 作为原生语言,在 iOS 应用上运行一个小程序 Demo, 使用 Android && React Native 也可以采用同样的思路实现。相关代码仓库: h

探索小程序实现菜鸟教程下载

随着小程序的发展与功能的逐步完善,越来越多的产品需要小程序与 APP 的功能能有一些共性,社区跨平台的解决方案越来越多,比如 taro 等为代表的把一套代码编译成多端运行的机制,本文会使用 Swift 作为原生语言,在 iOS 应用上运行一个小程序 Demo, 使用 Android && React Native 也可以采用同样的思路实现。

探索小程序实现菜鸟教程下载_小程序教程视频

相关代码仓库: https://github.com/taixw2/rmini

编译层

编译的目的是为了抹平小程序的与 H5 的差异,利用 Vue 实现数据绑定,利用 Web Component 实现小程序的组件功能。

从官网文档中可以看出来,运行一个小程序需要框架(数据绑定渲染)、组件(小程序渲染单元)、api(与原始交互的能力)。

探索小程序实现菜鸟教程下载_小程序教程视频

框架实现

转换成单页应用(一种可行的方案)

把所有页面打包成一个 js, 再由 js 管理所有的路由和状态,这种方案适合在 web 端运行,并且是单引擎的方案,在模拟原生的右滑返回等效果也会不尽人意。

探索小程序实现菜鸟教程下载_小程序教程视频

转换成多页面

众所周知,小程序是一个双引擎的框架,上面的方案显然不能达到要求, 双引擎的特点是在运行 javascript 的黑盒子中,无法访问到 DOM && BOM 等。将所有的逻辑代码在原生的 JavascriptCore 中运行,WebView 中的 Javascript 引擎负责数据绑定,需要解决的难点是 JavascriptCore 中的 setData 怎么通知 WebView 渲染, WebView 的事件怎么执行 JavascriptCore,接着往下看。

探索小程序实现菜鸟教程下载_小程序教程视频

抹平WXML

wxml 是一种类 html 标记语言,他负责所有的渲染规则,包括条件渲染、列表渲染、数据绑定等,与其再实现一种框架,还不如直接利用 Vue 实现同样的功能,再利用各种转换库将 wxml 中的事件转换成 Vue 能够识别的事件,如利用 post-html 可以做到如下的转换:

探索小程序实现菜鸟教程下载_小程序教程视频

每一个事件绑定的方法全都在原生的 JSContext 中运行,所以此时的事件只需要传递给 JSContext 的作用。

抹平WXSS

wxss 作为小程序的样式语言,其余 css 的主要区别就是多了一个 rpx 单位,以下是官网的换算表:

探索小程序实现菜鸟教程下载_小程序教程视频

根据上表可得知, rpx = (750 / 屏幕宽度) * px ;

在传统的移动端页面,我们的高清方案,一般需要获取 dpr, 然后修改动态修改 viewport 和 html 上的 font-size,但是小程序的代码因为是放在了设备本地,所以可以在下载小程序页面之后,我们还有一次编译机会,这时就可以把 rpx 根据当前设备的屏幕宽度替换成对应的 px。

还有一个 @import ,则利用 scss 或 less 就可以合并到同一个 css 文件中,

而全局样式则可以在构建 WXML 的时候再植入进入

抹平组件

组件具有独特的功能和自己的渲染规则,比如 scroll-view 具有 scroll-x 和 scroll-y 等属性控制滚动条。在 HTML5 中有一个重大的功能 web-component ,它能够自定义 html 元素,并且能够监控属性的变化,非常适合实现小程序组件。如:(使用了 lit-element 框架)

探索小程序实现菜鸟教程下载_小程序教程视频

这里用了 lit-element 这个框架,能够简化一些操作。

抹平 Page 和 App

App 负责整个应用的生命周期以及存一些全局的数据, getApp 能获取到 app 的信息。 所以类似的结构可能是这样的:

探索小程序实现菜鸟教程下载_小程序教程视频

getApp 能够直接访问到内部对象,并且在最顶层声明,这样每一个的地方都能访问到 getApp。

初始化一个页面都需要是实例化 PageClass, 即使再次进入(不是返回到这个页面)这个页面页需要再次重新实例化,每次实例化都需要关联一个 webviewId, 这个 ID 与原始的 webview 关联,这样每个 PageClass 中的 setData 都能找到对应的 webview 进行再次渲染,所以对应的代码可能是这样的:

探索小程序实现菜鸟教程下载_小程序教程视频

抹平 API

通过 API 能够直接调用原生的功能,比如 wx.request , 如果直接在 webview 中的 JSContext 中运行的话,则可能存在跨域,但是放在原生就不会存在这个问题。

实现JSContext 调用原生代码的功能,需要给 JSContext 中植入一个 JSBridge,如: JSBridge.invoke 和 JSBridge.on , invoke 负责同步任务,on 负责异步任务,原生再利用反射(原生的反射真麻烦)调用对应的原生方法,原生可以利用 while(true) 挂起 JSContext,既可以达到同步和异步的方法。

探索小程序实现菜鸟教程下载_小程序教程视频

打包 Javascript

Javascript 代码打包后被放在 JavascriptCore 中运行,唯一与 Webview 中的 JSContext 打交道的只有 setData , 先看一下打包流程:

  1. 利用 App.json 构建入口文件
  2. 利用 rollup 等工具将所有 Javascript 打包成一个文件(目前没有分包)

打包流程及其简单,接下来看一下两个 Javascript 引擎的交互过程。

打通 JSContext 到 WebView JavascriptCore

每次进入一个页面的时候都需要为这个页面的 webview 分配一个 id, 这个 id 至关重要,作为 native 与 JSContext (原生运行 javascript 的上下文对象) 与 webview 交互的唯一标识,JSContext 中需要实例化一个新的 PageClass 关联这个 id, native 中通过 id 保留 webview 的引用。在 JSContext 中植入一个 JSBridge 用于与原生交互,如: JSBridge.setData(webviewId, appId, data), 当 JSBridge 的 setData 被调用后,通过 appId + webviewId 就能找到对应的 webview, 再将 setData 传入 webview 中,在 Vue 接收到 data 后进行渲染, 整个过程如图:

探索小程序实现菜鸟教程下载_小程序教程视频

打通 Webview JavascriptCore 到 JSContext

有了前面的铺垫,接下来再看 webview 如何调用 JSContext 的方法, Webview 唯一能与 JSContext 交互的方式只有事件,事件触发后,需要通过某种方式触发 JSContext 中的方法,最后调用 setData 再返回来重新渲染 webview。

webview 中绑定的方法名众多,如: bindtap=”a”, bindtap=”b”, bindtap=”c” 等,但是可以通过 “抹平 WXML” 的时候最终只保留一个出口,如:

v-on:click=”callClick(‘a’, $event)” 等,这样 vue 中的 method 只需要实现对应的几个事件便可:

探索小程序实现菜鸟教程下载_小程序教程视频

结尾

利用原生作为桥梁,在两个引擎之间通信,webview 中的 JSContext 负责接收渲染通知,以及发送事件到 Native 的 JSContext 中,JSContext 独立运行,所以既访问不到 window 对象,也访问不到 document 对象。

原文 http://www.cnblogs.com/Amy-so/p/12152225.html

海计划公众号
(0)
上一篇 2020/03/20 07:33
下一篇 2020/03/20 07:33

您可能感兴趣的内容

  • 血淋淋的事实告诉你:你为什么不应该在JS文件中保存敏感信息使用攻略_文件使用帮助

    在JavaScript文件中存储敏感数据,不仅是一种错误的实践方式,而且还是一种非常危险的行为,长期以来大家都知道这一点。而原因也非常简单,我们可以假设你为你的用户动态生成了一个包含API密钥的JavaScript文件:apiCall= function(type, api_key, data) { … }
    var api_key = ‘1391f6bd

    2020/04/03
  • 微信小程序代码优化总汇教程视频_优化菜鸟教程网

    之前有一篇文章是:微信小程序性能优化入门指南. 主要讲述的是:小程序的加载流程、启动性能优化、首屏加载性能优化、汇渲染性能优化等方面讲解的。这写篇文章的目的,是以开发小程序代码的层面的优化。1、条件判断将wx:if换成了hidden 在小程序中使用wx-if,是基于局部渲染的形式。比如wx:if初始渲染条件为false时,框架什么都不会做;只有为真的时候才

    2020/04/03
  • CSS 不定宽高的垂直水平居中方式总汇小白基础_居中使用帮助

    垂直居中,在 CSS 中是一个老生常谈的问题,面试的时候也会时常被提及。所以,今天我们就来聊聊 9 种不同的居中方法。有常见的 flex、transform、absolute 等等。也有 CSS3 的网格布局。还有伪元素的方法,是的,你没有看错,::after 和 ::before 也可以实现居中。1、flex大家的第一反应,可能就是 flex 了。因为它的

    2020/03/24
  • Vue项目优化入门攻略_优化使用教程

    在日常的Vue项目开发中,随着业务的日渐负责,代码量的日益增加,随之带来的问题就是打包后的vendor.js体积过大,导致加载时空白页时间过长,给用户的体验太差。为此我们需要减少vendor.js的体积,从本质上来解决这种问题。这里大概例举几个在项目中实际用到过的方法,优化后的js大概缩小了50%左右,效果还是挺明显的。1,webpack externals

    2020/03/29
  • 一道面试题引起的思考小白帮助_面试小白攻略

    今天在认真干(划)活(水)的时候,看到群里有人发了一道头条的面试题,就顺便看了一下,发现挺有意思的,就决定分享给大家,并且给出我的解决方案和思考过程。题目如下:实现一个get函数,使得下面的调用可以输出正确的结果const obj = { selector: { to: { toutiao: “FE Coder”} }, target: [1, 2, { n

    2020/04/03
  • ES6之Promise入门基础_Promise小白攻略

    ES6之Promise入门基础 前言 Promise,用于解决回调地域带来的问题,将异步操作以同步的操作编程表达出来,避免了层层嵌套的回调函数。 什么是 Promise 所谓的 p…

    2020/03/20
  • Js集合的实现与应用教程视频_算法基础入门

    与数学中的集合概念类似,集合由一组无序的元素组成,且集合中的每个元素都是唯一存在的。可以回顾一下中学数学中集合的概念,我们这里所要定义的集合也具有空集(即集合的内容为空)、交集、并集、差集、子集的特性。在ES6中,原生的Set类已经实现了集合的全部特性,稍后我们会介绍它的用法。我们使用JavaSctipt的对象来表示集合,下面是集合类的主要实现方法:clas

    2020/03/26
  • js设计模式:观察者和发布订阅模式小白常识_模式小白知识

    总是把这两个当作同一个模式,但其实是不太一样的,现在重温一下。观察者模式观察者直接订阅目标,当目标触发事件时,通知观察者进行更新简单实现class Observer {constructor(name) {this.name = name;}update() {console.log(`${this.name} update`)}
    }class subjec

    2020/03/22
  • 最流行的七个 PHP Web 框架指南攻略_框架菜鸟指南

    PHP 是什么?PHP 代表超文本预处理器(Hypertext Pre-processor)。早期的 PHP 被用于个人主页,然后才升级更新为超文本预处理器。PHP 是一种服务器端脚本语言,用于开发静态或动态网站和 Web 应用程序。为什么要使用 PHP 进行服务器端编程?PHP 是开源的,并且免费。PHP 可以在目前主要的平台上运行,并具有独立于平台的特性

    2020/03/26
  • javascript引擎有哪些?攻略教程_引擎菜鸟知识

    JavaScript引擎是一个专门处理JavaScript脚本的虚拟机,一般会附带在网页浏览器之中。在2008年到2009年的第二次浏览器大战之前,JavaScript引擎(JavaScript engine)仅简单地被当作能阅读执行JavaScript源代码的解释器。主要的网页浏览器JavaScript引擎:Mozilla● SpiderMonkey,第一

    2020/03/22
  • Derby.js小白帮助_一个基于node全栈框架

    Derby.js小白帮助 官方网址:https://github.com/derbyjs/derby GitHub:http://derbyjs.com 简介描述:一个基于node…

    2020/03/06
  • vue 全局前置守卫引起死循环的原因与解决方法基础教程_循环小白攻略

    我们经常会用到全局前置守卫,如判断用户有没有登陆过,如果登陆过就直接跳到目的页面,如果没有登陆过,就跳转到登陆页。先看官网对全局前置守卫的介绍使用 router.beforeEach 注册一个全局前置守卫:const router = new VueRouter({ … })router.beforeEach((to, from, next) => {/

    2020/03/20
  • Algolia Places小白指南_为您的网站提供一个快速、简单的方式,自动化产生地址建议列表的Js函数库

    Algolia Places小白指南 官方网址:https://community.algolia.com/places/ GitHub:https://github.com/al…

    2020/03/06
  • 你的下一款应用可能没有后端入门攻略_应用小白教程

    今天,我们谈一谈JAMStack 和它的未来演变。历史总是喜欢重演。我在 1999 年建立了自己的第一个网站,使用的是当时的 Web 高手(这里我还没法用“开发者”这个词)能接触到的最先进技术:所见即所得的编辑器。对我(以及许多其他许多人!)而言,这种技术最早指的就是 微软 FrontPage ——现在回想起来,我的脸上还会浮现出掺杂着怀旧和羞愧的尴尬笑容。

    2020/03/23
  • react 高阶组件的 理解和应用菜鸟教程网_react小白教程

    高阶组件是什么东西简单的理解是:一个包装了另一个基础组件的组件。(相对高阶组件来说,我习惯把被包装的组件称为基础组件)注意:这里说的是包装,可以理解成包裹和组装;具体的是高阶组件的两种形式吧:a、属性代理(Props Proxy)可以说是对组件的包裹,在包裹的过程中对被包裹的组件做了点什么(props的处理,把基础组件和其他元素组合),然后返回,这就成了一个

    2020/04/05
  • rxjs入门指南基础指南_rxjs小白基础

    使用场景在复杂的,频繁的异步请求场景,使用rxjs。在依赖的多个异步数据,决定渲染的情景,使用rxjs。总之:在前台频繁的、大量的、和后台数据交互的复杂项目里面,使用rxjs(web端,iOS,android端等,客户端都可考虑使用)rxjs初步认识数据和数据观察者的绑定。数据变化,观察者动作——监听或者观察者模式。观察者的迭代执行动作——观察者注册任意个异

    2020/04/03