深入学习小程序框架底层原理,培养双线程思维(2023版,15章)

feilipu2023nui · · 412 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。
![1.png](http://static.itsharecircle.com/231218/2289eb20f589afd8f12b3d6989607720.png) 小程序上线以来,一直被称为便携版的 APP,关于两者之间的区别,无外乎是小程序相对轻便、开发成本低、开发周期短、收效快。 小程序并非凭空冒出来的一个概念,当微信中的 WebView 逐渐成为移动 Web 的一个重要入口时,微信就有相关的 JS API 了。 微信小程序是双线程架构,分为逻辑层和渲染层,在进行文件解析的时候不会发生阻塞。 逻辑层: (1)解析js,负责逻辑处理、事件逻辑、动态数据的处理 (2)小程序的所有代码逻辑都包含在同一个逻辑线程(逻辑层是单线程),小程序只有一个APP实例,但是有多个page,小程序编译之后将会把所有page打包至同一个js文件 与h5页面的区别 运行环境:小程序基于微信系统,而 h5 的宿主环境是浏览器。所以小程序中没有 DOM 和 BOM 的相关 API , jQuery 和一些 NPM 包都不能在小程序中使用; 系统权限:小程序能获得更多的系统权限,如网络通信状态、数据缓存能力等; 渲染机制:小程序的逻辑层和渲染层是分开的,而 h5 页面 UI 渲染跟 JavaScript 的脚本执行都在一个单线程中,互斥。所以 h5 页面中长时间的脚本运行可能会导致页面失去响应 // i18n.ts import { createI18n } from 'vue-i18n' import zh from './zh' const i18n = createI18n({ locale: 'zh', messages: { zh } }) export default i18n 使用 vue-i18n 提供的 useI18n 方法获取国际化语言实例,并且通过实例上的 t函数来处理需要国际化的字段,使用方式为t('xxx'),代码片段如下: // views/home/index.vue <script setup lang="ts"> import { useI18n } from 'vue-i18n' const { t } = useI18n() </script> <template> {{ t('message.home') }} </template> 在创建完这个 indexedDB中的一个打开数据库的 public方法之后,我们迫不及待的在 home.vue中尝试一下。首先使用 new关键字实例化一个对象,通过对象来调用其上面的方法 openStore()来新建数据库并连接数据库。代码块如下: updateItem(storeName: string, data: any) { console.log(this.db) const store = this.db.transaction([storeName], 'readwrite').objectStore(storeName) const request = store.put({ ...data, updateTIme: new Date().getTime() }) request.onsuccess = (event: any) => { console.log('数据写入成功') console.log(event) } request.onerror = (event: any) => { console.log('数据写入失败') console.log(event) } } 在第一步中,首先使用 Typescript的 interface为 store中的所有 state声明类型,然后将 interface放置在InjectionKeyd的泛型类型中,代码片段如下: // src/store/index.ts import { createStore, Store, useStore as baseUseStore } from 'vuex' import { InjectionKey } from 'vue' // ... // 重新封装useStore export function useStore() { return baseUseStore(key) } // ... 和使用 createApp 创建的、只能在客户端运行的 Vue应用不同,创建一个服务端渲染应用需要使用 createSSRApp,另外为了避免单例模式,为每个用户创建一个干净的、无污染的应用程序,我们需要封装一个工厂函数 createApp,代码片段如下: // client-entry.ts import { createApp } from './main' const { app, router } = createApp() router.isReady().then(() => { app.mount('#app') }) // server.js if (!isProd) { // 1. 读取 index.html template = fs.readFileSync( path.resolve(__dirname, 'index.html'), 'utf-8' ) // 2. 应用 Vite HTML 转换。这将会注入 Vite HMR 客户端, // 同时也会从 Vite 插件应用 HTML 转换。 // 例如:@vitejs/plugin-react-refresh 中的 global preambles template = await vite.transformIndexHtml(url, template) // 3. 加载服务器入口。vite.ssrLoadModule 将自动转换 // 你的 ESM 源码使之可以在 Node.js 中运行!无需打包 // 并提供类似 HMR 的根据情况随时失效。 render = (await vite.ssrLoadModule('/src/entry-server.ts')).render } else { // 1. 读取 index.html template = fs.readFileSync( path.resolve(__dirname, 'dist/client/index.html'), 'utf-8' ) 小程序的渲染层和逻辑层分别由两个线程管理:渲染层的界面使用 WebView 进行渲染;逻辑层采用 JSCore 运行 JavaScript 代码。一个小程序存在多个界面,所以渲染层存在多个 WebView。这两个线程间的通信经由小程序 Native 侧中转,逻辑层发送网络请求也经由 Native 侧转发 // zh.ts export default { header: { // 头部组件 orders: '房源订单中心', records: '历史足迹', language: '语言' }, footer: { // 底部组件 airbnb: '爱彼迎', careers: '工作机会', news: '爱彼迎新闻', topic: '政策', diversity: '多元化与归属感', accessibility: '无障碍设施', discovery: '发现', trustAndSafe: '信任与安全', invite: '邀请好友', evection: '商务差旅', magzine: '爱彼迎杂志', airbnborg: 'Airbnb.org', rent: '出租', whyRent: '为什么要出租?', hospitality: '待客之道', responsibleHosting: '房东义务', experiences: '开展体验', resources: '资源中心', service: '客服支持', help: '帮助', neighbors: '邻里支持' } }
412 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传