小言_互联网的博客

Vite + Vue3 项目中,使用 vw/vh 适配移动端,并通过 Android Studio 打包

590人阅读  评论(0)

目录

1. 使用 vw/vh 适配移动端

1.1 使用 vite 初始化项目

1.2 安装插件,将 px 转化成 vw

1.2.1 在 vite.config.ts 中,声明插件

1.2.2 手写 postcss 类型声明文件,解决 路径爆红、没有提示

1.2.3 tsconfig.config.json VS tsconfig.json

2. 将 vue 项目丢到 Android app 中

2.1 创建 Android app

2.2 Android app 目录结构

2.3 创建并启动虚拟机

2.4 修改布局 activity_main.xml

2.5 修改主任务逻辑 MainActivity

2.6 解决运行时网络连接失败的问题

2.7 打包项目(debug 包)


 

1. 使用 vw/vh 适配移动端

开发移动端,最麻烦的一点就是适配不同尺寸的屏幕

之前自适应,采用 rem / 百分比 / 媒体查询 等方式实现,现在可以采用 vm/vh 方案:

  • vw —— 视口的最大宽度,1vw 等于视口宽度的百分之一
  • vh —— 视口的最大高度,1vh 等于视口高度的百分之一

1.1 使用 vite 初始化项目

npm init vue@latest

如果有报错信息:error when starting dev server: Error: Cannot find module 'node:path'

解决方案:

  • 升级 node.js 至16
  • 常见的版本是12、14、16,一般使用大版本中的最新版本

1.2 安装插件,将 px 转化成 vw

npm install postcss-px-to-viewport -D

 

1.2.1 在 vite.config.ts 中,声明插件

安装完成后,直接修改 vite.config.ts,声明插件(由于 vite 中已经内联了 postcss,所以无需创建 postcss.config.js文件来声明插件)


  
  1. import { fileURLToPath, URL } from 'url'
  2. import { defineConfig } from 'vite'
  3. import vue from '@vitejs/plugin-vue'
  4. import vueJsx from '@vitejs/plugin-vue-jsx'
  5. // 将 px 转换为 vw
  6. import postcsspxtoviewport from "postcss-px-to-viewport"
  7. export default defineConfig({
  8. plugins: [ vue(), vueJsx()],
  9. css: {
  10. postcss: {
  11. plugins: [
  12. postcsspxtoviewport({
  13. unitToConvert: 'px', // 要转化的单位
  14. viewportWidth: 750, // UI设计稿的宽度,一般写 320
  15. // 下面的不常用,上面的常用
  16. unitPrecision: 6, // 转换后的精度,即小数点位数
  17. propList: [ '*'], // 指定转换的css属性的单位,*代表全部css属性的单位都进行转换
  18. viewportUnit: 'vw', // 指定需要转换成的视窗单位,默认vw
  19. fontViewportUnit: 'vw', // 指定字体需要转换成的视窗单位,默认vw
  20. selectorBlackList: [ 'ignore-'], // 指定不转换为视窗单位的类名,
  21. minPixelValue: 1, // 默认值1,小于或等于1px则不进行转换
  22. mediaQuery: true, // 是否在媒体查询的css代码中也进行转换,默认false
  23. replace: true, // 是否转换后直接更换属性值
  24. landscape: false // 是否处理横屏情况
  25. })
  26. ]
  27. }
  28. },
  29. resolve: {
  30. alias: {
  31. '@': fileURLToPath( new URL( './src', import. meta. url))
  32. }
  33. }
  34. })

 

注意:直接从 postcss-px-to-viewport 依赖中读取内容,路径会爆红,并且 postcsspxtoviewport 中也没有智能提示,这是因为缺少声明文件

如何解决 路径爆红、没有提示 这两个问题呢?根据提示,得到两种方案:

  • 使用命令下载 postcss 的声明文件
  • 自己写一个 postcss 的声明文件

如果使用命令下载 postcss 声明文件,则会出现报错(当前社区内没有 ts 声明文件)

所以还是手写一个 postcss 声明文件吧 —— postcss-px-to-viewport.d.ts

1.2.2 手写 postcss 类型声明文件,解决 路径爆红、没有提示

通过 declare module 'postcss-px-to-viewport' 给 postcss 扩充声明 


  
  1. declare module 'postcss-px-to-viewport' {
  2. type Options = {
  3. unitToConvert: 'px' | 'rem' | 'cm' | 'em',
  4. viewportWidth: number,
  5. // 下面的不常用,上面的常用
  6. viewportHeight: number, // 目前未使用;TODO:需要不同的单位和不同属性的数学
  7. unitPrecision: number,
  8. viewportUnit: string,
  9. fontViewportUnit: string, // vmin更适合
  10. selectorBlackList: string[],
  11. propList: string[],
  12. minPixelValue: number,
  13. mediaQuery: boolean,
  14. replace: boolean,
  15. landscape: boolean,
  16. landscapeUnit: string,
  17. landscapeWidth: number
  18. }
  19. // 注意:这里导出一个函数,如果使用箭头函数容易报错,推荐使用 function 这种写法
  20. export default function( options: Partial<Options>): any
  21. }

类型声明文件注意问题:

  • 类型声明文件,最终导出一个函数
  • 如果使用箭头函数容易报错,推荐使用 function 这种写法
  • Partial 可以让 ts 中的属性全部变成可选项(非必填项)

1.2.3 tsconfig.config.json VS tsconfig.json

这俩文件是有区别的:

  • tsconfig.config.json —— 用于配置 vite 需要的各种工具
  • tsconfig.json —— 用于配置 Vue 需要的各种工具

postcss 是针对 vite 的工具,因此要在 tsconfig.config.json 中引入 1.2.2 手写的声明文件


  
  1. {
  2. "extends": "@vue/tsconfig/tsconfig.web.json",
  3. "include": [ "env.d.ts", "src/**/*", "src/**/*.vue", "postcss-px-to-viewport.d.ts"],
  4. "exclude": [ "src/**/__tests__/*"],
  5. "compilerOptions": {
  6. "composite": true,
  7. "baseUrl": ".",
  8. "paths": {
  9. "@/*": [ "./src/*"]
  10. }
  11. }
  12. }

这样就配置完成了:

  • 在项目里,我们会继续用 px 写代码
  • 运行后,浏览器样式则会被自动改成 vw

2. 将 vue 项目丢到 Android app 中

2.1 创建 Android app

打开 Android Studio 后,会弹出这个界面,选择 Empty Activity

 

如果之前开启过别的项目,也可以通过下面的路径,重新打开上面的弹框

 

选择 Empty Activity 后,会出现下面的弹框,给项目起个好听的名字

点击 Finish,会开始初始化一个 Android 项目,最终如下所示:

  • 左侧是 Android app 源码
  • 顶部有个启动 app 的按钮,还有个创建虚拟机的按钮

2.2 Android app 目录结构

2.3 创建并启动虚拟机

可以创建多个虚拟机

 

启动虚拟机,并让当前 Android app 运行

2.4 修改布局 activity_main.xml

先把 图形化编辑模式 切换成 代码编辑模式

 

添加一个类似于前端 display:flex 概念的线性布局 LinearLayout

再添加一个 WebView 容器,用于容纳网页


  
  1. <?xml version= "1.0" encoding= "utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:id= "@+id/activity_main"
  4. android:layout_width= "match_parent"
  5. android:orientation= "vertical"
  6. android:layout_height= "match_parent">
  7. <WebView
  8. android:id= "@+id/web_view"
  9. android:layout_width= "match_parent"
  10. android:layout_height= "match_parent" />
  11. </LinearLayout >

2.5 修改主任务逻辑 MainActivity

隐藏默认头部

import android.app.Activity;

public class MainActivity extends Activity { ... }

 

设置 WebView 属性,使他能够执行 Javascript 脚本

view.getSettings().setJavaScriptEnabled(true);

 

加载需要显示的网页(也就是正在运行的 vue 应用):

  • 不能使用局域网地址,只能虚拟机专属地址 http://10.0.2.2
  • 端口是 vue 项目运行端口(启动 app 的同时,也要启动 vue 项目)

最终代码如下: 


  
  1. package com. example. myapplication;
  2. import androidx. appcompat. app. AppCompatActivity;
  3. import android. os. Bundle;
  4. import android. webkit. WebView;
  5. // 隐藏默认头部
  6. import android. app. Activity;
  7. import android. webkit. WebViewClient;
  8. public class MainActivity extends Activity {
  9. @Override
  10. protected void onCreate( Bundle savedInstanceState) {
  11. super. onCreate(savedInstanceState);
  12. // 设置一个 Activity 的显示界面,
  13. setContentView(R. layout. activity_main);
  14. // 这句类似 js 中的 document.querySelector()
  15. WebView view = ( WebView) findViewById(R. id. web_view);
  16. // 设置 WebView 属性,使他能够执行 Javascript 脚本
  17. view. getSettings(). setJavaScriptEnabled( true);
  18. // 加载需要显示的网页
  19. // 不能使用局域网地址,只能虚拟机专属地址 http://10.0.2.2
  20. // 端口是 vue 项目运行端口(就是启动 app 的同时,也要启动 vue 项目)
  21. view. loadUrl( "http://10.0.2.2:3000");
  22. view. setWebViewClient( new WebViewClient());
  23. }
  24. }

2.6 解决运行时网络连接失败的问题

完成上面的修改后,点击右上角的运行按钮,在虚拟机里重启项目,会发现 —— 网络连接失败

这时候需要去 主入口文件 AndroidManifest.xml 里,增加一些权限配置

增加了 4 行代码,如下所示:

完整代码: 


  
  1. <?xml version= "1.0" encoding= "utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools= "http://schemas.android.com/tools"
  4. package= "com.example.myapplication">
  5. <application
  6. android:allowBackup= "true"
  7. android:dataExtractionRules= "@xml/data_extraction_rules"
  8. android:fullBackupContent= "@xml/backup_rules"
  9. android:icon= "@mipmap/ic_launcher"
  10. android:label= "@string/app_name"
  11. android:roundIcon= "@mipmap/ic_launcher_round"
  12. android:supportsRtl= "true"
  13. android:theme= "@style/Theme.MyApplication"
  14. android:usesCleartextTraffic= "true"
  15. tools:targetApi= "31">
  16. <activity
  17. android:name= ".MainActivity"
  18. android:exported= "true">
  19. <intent-filter>
  20. <action android:name="android.intent.action.MAIN" />
  21. <category android:name="android.intent.category.LAUNCHER" />
  22. </intent-filter>
  23. </activity>
  24. </application>
  25. <uses-permission android:name="android.permission.INTERNET" />
  26. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  27. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
  28. </manifest>

这样,就能顺利预览本地运行的项目了

2.7 打包项目(debug 包)

打包项目时,需要把 2.5 中的路径,改成线上地址

打包项目,可以参考我的其他文章,在 capacitor / 工作记录 专栏里

 


转载:https://blog.csdn.net/Lyrelion/article/details/126901618
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场