• 小满Vue3第三十六章(Vue如何开发移动端)


    开发移动端最主要的就是适配各种手机,为此我研究了一套解决方案

    在之前我们用的是rem 根据HTML font-size 去做缩放

    现在有了更好用的vw vh

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

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

    1.安装依赖

    1. npm install postcss-px-to-viewport -D

    因为vite中已经内联了postcss,所以并不需要额外的创建 postcss.config.js文件

    vite.config.ts

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

    如果你用的vite 是 ts 他这个插件并没有提供声明文件我已经帮大家写好了声明文件(良心)

    1. declare module 'postcss-px-to-viewport' {
    2. type Options = {
    3. unitToConvert: 'px' | 'rem' | 'cm' | 'em',
    4. viewportWidth: number,
    5. viewportHeight: number, // not now used; TODO: need for different units and math for different properties
    6. unitPrecision: number,
    7. viewportUnit: string,
    8. fontViewportUnit: string, // vmin is more suitable.
    9. selectorBlackList: string[],
    10. propList: string[],
    11. minPixelValue: number,
    12. mediaQuery: boolean,
    13. replace: boolean,
    14. landscape: boolean,
    15. landscapeUnit: string,
    16. landscapeWidth: number
    17. }
    18. export default (options: Partial<Options>) => any
    19. }

    引入声明文件 tsconfig.app postcss-px-to-viewport.d.ts跟vite.ts同级

    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. }

    代码案例

    1. <template>
    2. <div class="wraps">
    3. <header class="header">
    4. <div>left</div>
    5. <div>中间</div>
    6. <div>right</div>
    7. </header>
    8. <main class="main">
    9. <div class="main-items" v-for="item in 100">
    10. <div class="main-port">头像</div>
    11. <div class="main-desc">
    12. <div>小满{{item}}</div>
    13. <div>你妈妈喊你回家穿丝袜啦</div>
    14. </div>
    15. </div>
    16. </main>
    17. <footer class="footer">
    18. <div class="footer-items" v-for="item in footer">
    19. <div>{{ item.icon }}</div>
    20. <div>{{ item.text }}</div>
    21. </div>
    22. </footer>
    23. </div>
    24. </template>
    25. <script setup lang='ts'>
    26. import { reactive } from 'vue';
    27. type Footer<T> = {
    28. icon: T,
    29. text: T
    30. }
    31. const footer = reactive<Footer<string>[]>([
    32. {
    33. icon: "1",
    34. text: "首页"
    35. },
    36. {
    37. icon: "2",
    38. text: "商品"
    39. },
    40. {
    41. icon: "3",
    42. text: "信息"
    43. },
    44. {
    45. icon: "4",
    46. text: "我的"
    47. }
    48. ])
    49. </script>
    50. <style lang="less">
    51. @import url('@/assets/base.css');
    52. html,
    53. body,
    54. #app {
    55. height: 100%;
    56. overflow: hidden;
    57. font-size: 14px;
    58. }
    59. .wraps {
    60. height: inherit;
    61. overflow: hidden;
    62. display: flex;
    63. flex-direction: column;
    64. }
    65. .header {
    66. background-color: pink;
    67. display: flex;
    68. height: 30px;
    69. align-items: center;
    70. justify-content: space-around;
    71. div:nth-child(1) {
    72. width: 40px;
    73. }
    74. div:nth-child(2) {
    75. text-align: center;
    76. }
    77. div:nth-child(3) {
    78. width: 40px;
    79. text-align: right;
    80. }
    81. }
    82. .main {
    83. flex: 1;
    84. overflow: auto;
    85. &-items {
    86. display: flex;
    87. border-bottom: 1px solid #ccc;
    88. box-sizing: border-box;
    89. padding: 5px;
    90. }
    91. &-port {
    92. background: black;
    93. width: 30px;
    94. height: 30px;
    95. border-radius: 200px;
    96. }
    97. &-desc{
    98. margin-left:10px;
    99. div:last-child{
    100. font-size: 10px;
    101. color:#333;
    102. margin-top: 5px;
    103. }
    104. }
    105. }
    106. .footer {
    107. border-top: 1px solid #ccc;
    108. display: grid;
    109. grid-template-columns: 1fr 1fr 1fr 1fr;
    110. &-items {
    111. display: flex;
    112. flex-direction: column;
    113. justify-content: center;
    114. align-items: center;
    115. padding: 5px;
    116. }
    117. }
    118. </style>

     基本适配百分之99的屏幕

    如何将我们的Vue 项目打包成App(会安卓的可以跳过

    安卓编辑器下载地址(建议科学上网不然很慢)https://developer.android.com/

    一直next 就行了 然后磁盘选一下 安装就可以了 

    装完启动需要还需要安装sdk 然后就可以打开了

    新建一个空项目选这个就可以了

     语言会java选java 会别的就选别的

     等待加载完成

    打开之后可以创建一个虚拟机 

     创建完成之后就可以运行安卓项目

     其实就是一个虚拟手机

    切换成代码模式

     

     修改成以下代码

    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 >

     其实就是类似于我们前端的display felx 

     webView 就和小程序的webView 基本一样 套网页的

    match_parent表示让当前控件的大小和父布局的大小一样,也就是让父布局来决定当前控件的大小

    java 代码逻辑

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

     

    加载需要显示的网页 不能使用局域网地址 只能虚拟机专属地址 http://10.0.2.2 端口是我们vue 项目端口

     配置权限

    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>

     

     你就可以看到我们的项目了

    最后打包

    打包的时候路径记得换成线上的服务器地址

     

     安卓手机实测

  • 相关阅读:
    chrome历史版本下载
    图解LeetCode——768. 最多能完成排序的块 II(难度:困难)
    EPLAN_006#部件库快速导入、树结构、部件导航器、材料表导航器
    【wpa_supplicant】从 assoc 动作窥伺supplicant与driver的交互(二)
    网络安全(黑客)自学笔记
    基于深度卷积集成网络的视网膜多种疾病筛查和识别方法
    网络基础(传输层UDP协议&TCP协议)
    android WebRtc 视频通话(P2P)
    新型高强度铝合金焊条
    如何排查SQL慢查询?
  • 原文地址:https://blog.csdn.net/qq1195566313/article/details/125490078