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

news2024/11/20 18:39:48

目录

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文件来声明插件)

import { fileURLToPath, URL } from 'url'
 
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
// 将 px 转换为 vw
import postcsspxtoviewport from "postcss-px-to-viewport"

export default defineConfig({
  plugins: [vue(), vueJsx()],
  css: {
    postcss: {
      plugins: [
        postcsspxtoviewport({
          unitToConvert: 'px', // 要转化的单位
          viewportWidth: 750, // UI设计稿的宽度,一般写 320
    
          // 下面的不常用,上面的常用
          unitPrecision: 6, // 转换后的精度,即小数点位数
          propList: ['*'], // 指定转换的css属性的单位,*代表全部css属性的单位都进行转换
          viewportUnit: 'vw', // 指定需要转换成的视窗单位,默认vw
          fontViewportUnit: 'vw', // 指定字体需要转换成的视窗单位,默认vw
          selectorBlackList: ['ignore-'], // 指定不转换为视窗单位的类名,
          minPixelValue: 1, // 默认值1,小于或等于1px则不进行转换
          mediaQuery: true, // 是否在媒体查询的css代码中也进行转换,默认false
          replace: true, // 是否转换后直接更换属性值
          landscape: false // 是否处理横屏情况
        })
      ]
    }
  },
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  }
})

 

注意:直接从 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 扩充声明 

declare module 'postcss-px-to-viewport' {
 
    type Options = {
        unitToConvert: 'px' | 'rem' | 'cm' | 'em',
        viewportWidth: number,

        // 下面的不常用,上面的常用
        viewportHeight: number, // 目前未使用;TODO:需要不同的单位和不同属性的数学
        unitPrecision: number,
        viewportUnit: string,
        fontViewportUnit: string,  // vmin更适合
        selectorBlackList: string[],
        propList: string[],
        minPixelValue: number,
        mediaQuery: boolean,
        replace: boolean,
        landscape: boolean,
        landscapeUnit: string,
        landscapeWidth: number
    }
 
    // 注意:这里导出一个函数,如果使用箭头函数容易报错,推荐使用 function 这种写法
    export default function(options: Partial<Options>):any
}

类型声明文件注意问题:

  • 类型声明文件,最终导出一个函数
  • 如果使用箭头函数容易报错,推荐使用 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 手写的声明文件

{
  "extends": "@vue/tsconfig/tsconfig.web.json",
  "include": ["env.d.ts", "src/**/*", "src/**/*.vue", "postcss-px-to-viewport.d.ts"],
  "exclude": ["src/**/__tests__/*"],
  "compilerOptions": {
    "composite": true,
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  }
}

这样就配置完成了:

  • 在项目里,我们会继续用 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 容器,用于容纳网页

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent">
 
    <WebView
        android:id="@+id/web_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</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 项目)

最终代码如下: 

package com.example.myapplication;
 
import androidx.appcompat.app.AppCompatActivity;
 
import android.os.Bundle;
 
import android.webkit.WebView;
 
// 隐藏默认头部
import android.app.Activity;
 
import android.webkit.WebViewClient;
 
public class MainActivity extends Activity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // 设置一个 Activity 的显示界面,
        setContentView(R.layout.activity_main);

        // 这句类似 js 中的 document.querySelector()
        WebView view = (WebView)findViewById(R.id.web_view);

        // 设置 WebView 属性,使他能够执行 Javascript 脚本
        view.getSettings().setJavaScriptEnabled(true);

        // 加载需要显示的网页
        // 不能使用局域网地址,只能虚拟机专属地址 http://10.0.2.2
        // 端口是 vue 项目运行端口(就是启动 app 的同时,也要启动 vue 项目)
        view.loadUrl("http://10.0.2.2:3000");
 
        view.setWebViewClient(new WebViewClient());
    }
}

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

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

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

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

完整代码: 

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.example.myapplication">
 
    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.MyApplication"
        android:usesCleartextTraffic="true"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
</manifest>

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

2.7 打包项目(debug 包)

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

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

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/76838.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java 8 Stream 之 collect() 的奇技淫巧!

前言 本身我是一个比较偏向少使用Stream的人&#xff0c;因为调试比较不方便。 但是, 不得不说&#xff0c;stream确实会给我们编码带来便捷。 所以还是忍不住想分享一些奇技淫巧。 正文 Stream流 其实操作分三大块 &#xff1a; 创建 处理 收集 我今天想分享的是 收集…

核心内参:S参数的三个重要特性——因果性、无源性与互异性

1 从一个报错开始 S参数在射频、高速领域的应用非常广泛&#xff0c;相关知识点也非常多。最近浏览了一本2020年新出版的书《S Parameter for Signal Integrity》&#xff0c;作者是IEEE Fellow、业界大牛Peter J. Pupalaikis&#xff0c;现任职于Teledyne LeCroy。该书写的非…

《Linux运维实战:使用Percona Backup for MongoDB备份与恢复Mongodb数据》

一、备份与恢复方案 Percona Backup for MongoDB 是一个开源、分布式和低影响的解决方案&#xff0c;用于MongoDB分片集群和副本集的一致备份。从版本1.7.0开始&#xff0c;Percona Backup for MongoDB支持物理和逻辑备份和恢复&#xff0c;仅支持对逻辑备份进行时间点恢复。 …

linux支持ipv6

1. kernel config [*] Networking support ---> Networking options ---> <*> The IPv6 protocol ---> 2. test 2.1 /proc/net/if_inet6 查看/proc/net/if_inet6文件是否存在以确定你的系统是否支持IPv6。 如果没有&#xff0c;可尝试如下命令加载IPv6模…

磺化氰化物7酪胺Sulfo-Cy7 TSA,Sulfo-Cyanine7 TSA,Sulfo-Cyanine7 Tyramide

Sulfo-Cyanine7 Tyramide&#xff0c;Sulfo-Cy7 TSA&#xff0c;Sulfo-Cyanine7 TSA&#xff0c;磺酸基-花青素Cy7 酪酰胺产品结构&#xff1a; 产品规格&#xff1a; 1.Packaging specification&#xff1a;5mg, 10mg, 25mg, flexible packaging, including 100mg packaging a…

11.AOP之注解配置

1.使用IDEA创建工程 2.引入项目使用的依赖 <dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.2.RELEASE</version></dependency><depend…

一、计算机网络体系结构(一)计算机网络概述

目录 1.1计算机网络的概念、组成与功能 1.2计算机网络的分类 1.2.1按分布范围分类 1.2.2按传输技术分类 1.2.3按拓扑结构分类 1.2.4按使用者分类 1.2.5按交换技术分类 1.2.6按传输介质分类 1.3计算机网络的主要性能指标 1.1计算机网络的概念、组成与功能 计算机网络的…

PHP单商户视频号对接流程

一、序关联至对应视频号&#xff0c;并在视频号带货直播中使用。 首先&#xff0c;商家需要在微信后台申请自定义版交易组件权限&#xff0c;申请成功后&#xff0c;可以将小程 二、申请开通商户号 等商户号审核之后在操作一下步骤接口调用&#xff08;pro为例&#xff09; 实…

k8s ~ 数据存储、安全认证、DashBoard。

k8s ~ 数据存储。 文章目录k8s ~ 数据存储。8.1 基本存储。8.1.1 EmptyDir。8.1.2 HostPath。8.1.3 NFS。8.2 高级存储。8.2.1 PV。8.2.2 PVC。8.2.3 生命周期。8.3 配置存储。8.3.1 ConfigMap。8.3.2 Secret。9. 安全认证。9.1 访问控制概述。9.2 认证管理9.3 授权管理。9.4 准…

Flink窗口(Flink Window)

上一篇flink watermark讲到Flink 中事件时间和水位线的概念&#xff0c;那它们有什么具体应用呢&#xff1f;当然是做基于时间的处理计算了。其中最常见的场景&#xff0c;就是窗口聚合计算。 之前我们已经了解了 Flink 中基本的聚合操作。在流处理中&#xff0c;我们往…

Neo4j的Java API操作

Neo4j的Java API操作 文章目录Neo4j的Java API操作0. 写在前面1、前置芝士2. 准备工作2.1 为项目引入Neo4j依赖2.2 启动和停止3、Java操作Neo4j4、参考资料0. 写在前面 Linux版本&#xff1a;Ubuntu Kylin 16.04Neo4j版本&#xff1a;Neo4j-3.2.7 CommunityProject Build Tool…

微服务链路追踪SkyWalking(9.2.0)

微服务链路追踪SkyWalking(9.2.0) 链路追踪介绍 对于一个大型的几十个、几百个微服务构成的微服务架构系统&#xff0c;通常会遇到下面一些问题&#xff0c;比如&#xff1a; 如何串联整个调用链路&#xff0c;快速定位问题&#xff1f;如何缕清各个微服务之间的依赖关系&am…

m基于FPGA的GPS收发系统开发,包括码同步,载波同步,早迟门跟踪环,其中L1采用QPSK,L2采用BPSK

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 最早的GPS包含L1和L2两个频段&#xff0c;其中L1上调制CA码&#xff0c;P码以及导航电文&#xff0c;L2上调制P码和导航电文。在实际接收到的GPS信号中&#xff0c;我们除了能够接受到CA码和P码外…

语雀模板测试

Markdown 和快捷键全覆盖 &#x1f4a1; Tips&#xff1a;语雀支持全功能 markdown 语法&#xff0c;可以点击文档编辑页右下角小键盘查看全部支持的语法和快捷键。 支持导入导出 markdown 文件。支持自动识别粘贴的 markdown 格式内容转换为富文本。 行内代码 &#x1f4a1; …

Apache HTTPD 多后缀解析漏洞

Apache HTTPD 支持一个文件拥有多个后缀&#xff0c;并为不同后缀执行不同的指令。比如&#xff0c;如下配置文件&#xff1a; AddType text/html .html AddLanguage zh-CN .cn 其给.html后缀增加了media-type&#xff0c;值为text/html&#xff1b;给.cn后缀增加了语言&…

DBCO四嗪试剂特点整理:Me-Tetrazine-DBCO,甲基-四嗪-二苯并环辛炔

【中文名称】甲基-四嗪-二苯并环辛炔 【英文名称】 Me-Tetrazine-DBCO 【CAS号】N/A 【分子式】C29H24N6O2 【分子量】488.55 【基团】DBCO基团 【纯度】95% 【规格标准】1g&#xff0c;5g&#xff0c;10g&#xff0c;包装灵活&#xff0c;可进行相应的封装。 【是否接受定制…

Linux进程的数据结构

在Linux里面&#xff0c;无论是进程还是线程&#xff0c;到了内核里面统一叫任务&#xff08;task&#xff09;&#xff0c;有一个统一的结构task_struct进行管理。 在程序执行过程中&#xff0c;一旦调用到系统调用&#xff0c;就需要进入内核继续执行&#xff0c;那么讲用户…

5.DI之注解配置

1.编写Spring框架核心配置文件applicationContext.xml 在项目目录“/src/main/resources”下新建applicationContext.xml文件&#xff0c;具体代码如下。 <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework…

HashMap1.8也会发生死循环—记录

目录 代码 jstack 分析 什么是哈希表 在讨论哈希表之前&#xff0c;我们先大概了解下其他数据结构在新增&#xff0c;查找等基础操作执行性能 数组&#xff1a;采用一段连续的存储单元来存储数据。对于指定下标的查找&#xff0c;时间复杂度为O(1)&#xff1b;通过给定值进…

web课程设计网页规划与设计:HTML+CSS美妆设计题材——雅诗兰黛(5页)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…