• uni-app多端开发


    开场白: 要是在 vscode 书写代码, 需要添加 几个插件来支持 uni-app
    在这里插入图片描述
    到此 js 的 项目就可以了

    但是 ts 的项目需要类型检查

    下载两个 pnpm i -D @types/wechat-miniprogram @uni-helper/uni-app-types (这两个是用来检查 ts 的uni-app项目
    然后再tsconfig.json 配置文件中 types 数组追加
    “types”: [“@dcloudio/types”, “@types/wechat-miniprogram”, “@uni-helper/uni-app-types”]

    // tsconfig.json 此时的完整配置
    {
      "extends": "@vue/tsconfig/tsconfig.json",
      "compilerOptions": {
        "sourceMap": true,
        "baseUrl": ".",
        "paths": {
          "@/*": ["./src/*"]
        },
        "lib": ["esnext", "dom"],
        "types": [
        	"@dcloudio/types", 
        	"@types/wechat-miniprogram",   // 新加
        	"@uni-helper/uni-app-types"    // 新加
       	]
      },
      // 新加
      "vueCompilerOptions": {
        // "experimentalRuntimeMode": "runtime-uni-app"  // 已经弃用
        "nativeTags": ["block", "component", "template", "slot"]
      },
      "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    json 文件不能添加注释
    在这里插入图片描述
    解决
    vscode 设置
    搜索 Associations 关键字
    在这里插入图片描述
    将 pages.json 和 manifest.json 文件配置进去即可

    一、命令创建uni-app 项目 官网地址

    npx degit dcloudio/uni-preset-vue#vite-ts my-vue3-project

    二、在微信小程序后台找到 appId 填写 appId

    三、运行项目

    运行命令: pnpm dev:mp-weixin,会生成dist 文件目录,导入到微信开发者工具查看

    四、使用 uni-ui

    官网地址:uni-app 官网 使用uni-ui

    4-1、下载

    npm i @dcloudio/uni-ui   或   yarn add @dcloudio/uni-ui
    
    • 1

    4-2、自动导入

    // pages.json
    {
    	// 自动导包配置
    	"easycom": {
    		"autoscan": true,
    		"custom": {
    			// uni-ui 规则如下配置
    			"^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
    		}
    	},
    	
    	// 其他内容
    	pages:[
    		// ...
    	]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    4-3、ts项目下载类型校验 (uni-ui 组件库)

    uni-helper/uni-ui-types
    后面的所有的点击事件对象都可以用 UniHelper 提供的类型

    <swiper @change="onChange">
    	<swiper-item>...</swiper-item>
    	<swiper-item>...</swiper-item>
    </swiper>
    
    // js
    const onChange: UniHelper.SwiperOnChange = (event) => {
    	//  UniHelper.SwiperOnChange  这样 event 里面的所有的类型都有了
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    4-3-1、下载

    pnpm i -D uni-helper/uni-ui-types

    4-3-2、配置

    在 tsconfig.json 文件中 compilerOptions 配置上

    "compilerOptions": {
       "allowJs": true,
        "sourceMap": true,
        "baseUrl": ".",
        "paths": {
            "@/*": ["./src/*"]
        },
        "lib": ["esnext", "dom"],
        "types": [
            "@dcloudio/types",
            "miniprogram-api-typings",
            "@uni-helper/uni-app-types",
            "@uni-helper/uni-ui-types"   // 配置的uni-ui类型,书写标签时,鼠标划上之后有代码提示
        ]
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    五、持久化 pinia

    pinia 的使用和 vue3 一样 pinia配置,只是持久化的时候需要改一下

    // TODO: 持久化
    {
         persist: {
             storage: {
                 getItem(key) {
                     return uni.getStorageSync(key)
                 },
                 setItem(key, value) {
                     uni.setStorageSync(key, value)
                 },
             },
         },
     },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    六、数据请求封装

    utils包里面创建 http.ts 文件

    // http.ts
    
    import { useMemberStore } from '@/stores'  // store 取 token
    
    const baseUrl = 'https://pcapi-xiaotuxian-front-devtest.itheima.net'
    
    // 拦截器
    const httpInterceptor = {
        // 拦截前触发
        invoke(options: UniApp.RequestOptions) {
            options.url = baseUrl + options.url
            options.timeout = 10000
            options.header = {
                ...options.header,
                'source-client': 'miniapp',
            }
            const memStore = useMemberStore()
            const token = memStore.profile?.token
            if (token) {
                options.header.Authorization = token
            }
        },
    }
    // 添加 request 请求拦截 和 文件上传拦截
    uni.addInterceptor('request', httpInterceptor)
    uni.addInterceptor('uploadFile', httpInterceptor)
    
    // 封装响应
    interface Data<T> {
        code: string
        message: string
        result: T
    }
    export const http = <T>(options: UniApp.RequestOptions) => {  // http 函数接受 泛型,由调用 http 函数地方传进来
        return new Promise<Data<T>>((resolve, reject) => {  // Promise 响应数据进行泛型约束,Data 在上面定义好了,只有 result 类型会变化,所以从 http 函数调用者传进来
            uni.request({
                ...options,
                success(response) {
                    if (response.statusCode >= 200 && response.statusCode < 300) {
                        resolve(response.data as Data<T>)
                    } else {
                        uni.showToast({ icon: 'none', title: '请求错误' })
                        reject(response)
                    }
                },
                fail(err) {
                    uni.showToast({ icon: 'none', title: '服务器异常' })
                    reject(err)
                },
            })
        })
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    在 api / index.ts 目录下

    import { http } from '@/utils/http'
    
    /**
     * 首页轮播图
     * @param distributionSite 区分首页还是分类页面
     * @returns promise
     */
    export const getHomeBannerAPI = (data: Banner ) => {
        return http<BannerItem[]>({
            url: '/home/banner',
            method: 'GET',
            data
        })
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在组件中正常使用就好了

    七、获取组件的实例类型

    <Son ref='sonComponent' />
    
    const sonComponent = ref<InstanceType<typeof Son>>()  // typeof xxx 组件类型  InstanceType 获取的是实例类型
    
    sonComponent.value.getMore  // 父组件拿到子组件的属性和方法
    
    • 1
    • 2
    • 3
    • 4
    • 5

    子组件需要暴露出来(vue3中)

    defineExpose({
        getMore: getGuessData   // 前面定义的名字,让父组件拿到, 后面是子组件中的属性和方法
    })
    
    • 1
    • 2
    • 3

    八、上拉加载更多

    // 分页参数
    const params = {
    	currrentPage: 1,
    	pageSize: 10
    }
    // 定义的数组
    const tableDataList = ref([])
    // 是否加载完数据
    const isFinish = ref(false)
    // 加载中状态
    let isLoading = false
    // 页面和加载更多方法
    const getDataList = async (params) => {
    	if(isLoading || isFinish.value) return   // 加载中或者数据没有加载完, 都不进行请求数据
    	isLoading = true   // 请求数据制成 true
    	const res = await API(params)
    	tableDataList.value = [...tableDataList.value, res.result.list]   // 数据拼接
    	isLoading = false   // 数据回来,加载中的状态制成 false
    
    	// 判断要是当前的页码大于等于列表数据的总页码,停止加载(数据加载完了)
    	if(params.currentPage >= res.result.pages) {
    		isFinish.value = true  // 数据加载完了
    		return uni.showToast({title: "数据加载完了", icon: "none"})
    	}
    
    	params.currentPage++  // 加载下一页的数据
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    九、TS 类型

    1、检出一个类型中的某几个字段

    type baseItem = {
    	name: string
    	age: number
    	job: string
    	address: string
    }
    
    // 这个类型有上面的 baseItem 类型的某几个类型, 同时又有新的类型
    type userInfoItem = Pick<baseItem, "name" | "age" > & {
    	sex: "男" | "女"
    	like: string
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2、将类型变成可选参数( partial )

    type test1 = {
        name: string
        age: number
        sex: Date
    }
    
    type test2 = Partial<test1>
    
    test2 类型就变成了可选字段了
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3、将可选类型变成必选类型( Required )

    type test1 = {
        name?: string
        age?: number
        sex?: Date
    }
    
    type test3 = Required<test1>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    十、页面滚动动画 animate 使用

    类似于这种效果
    在这里插入图片描述

    微信小程序官网地址

    this.animate("需要动画的选择器", [{opacity: 1}, {opacity: 0}], 1000, {scrollSource: '', ....})
    
    • 1

    注: 在 vue3 模板语法中获取this(当前页面实例)
    const pageList = getCurrentPages()
    const currentPageInstance = pageList[pageList .length - 1]
    currentPageInstance 就相当于 this

    十一、不同平台间条件渲染

    <!-- #ifdef APP-PLUS -->
       app 语法 
    <!-- #endif -->
    
    <!-- #ifdef H5 -->
       h5 网页
    <!-- #endif -->
    
    <!-- #ifdef MP-WEIXIN -->
       微信小程序语法
    <!-- #endif -->
    
    <!-- #ifdef MP-WEIXIN || H5 -->
       微信小程序语法和 H5
    <!-- #endif -->
    
    // 以上 js  ts  html  css  json  scss 都支持
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    十二、uni-app在 安卓 手机上预览

    在这里插入图片描述

    注: adb 问题需要找到 HBuildx 安装目录
    D:\selfSoft\software\HBuilderX.3.3.13.20220314\HBuilderX\plugins\launcher-tools\tools\adbs 我的安装目录谁这样的
    将文件夹(1.0.31)里面的三个文件复制到外面
    还是报错 就将(1.0.36)文件夹里面的三个文件复制到外面

    如果出现上图最右面的 HTML5+ Runtime 黑框 就是 package.json里面的依赖版本和 HBuildx 版本不一致导致的
    查看 HBuildx官网 升级项目依赖就可以了 npx @dcloudio/uvm@latest 3.2.0

    十三、uni-app打包 apk 安装包

    配置manifest.json
    在这里插入图片描述
    在这里插入图片描述
    配置好 appid 和 app 的图标,应用名称之后开始下面的步骤

    进入 HBuildx 发行 原生APP云打包
    在这里插入图片描述
    在这里插入图片描述
    使用云端证书,点击后面的详情按钮会跳转到一个网页上面 (https://ask.dcloud.net.cn/article/35985#server)

    点击DCloud 开发着中心 按钮
    在这里插入图片描述
    然后点击应用名称
    在这里插入图片描述
    点击安卓云端证书
    在这里插入图片描述
    点击生成证书等待就 可以了
    证书生成之后就点击Hbuildx 上的打包按钮等待即可

    十四、uni-app 在 ios 上运行和打包

    在 mac 本上操作

    首先安装 Xcode 软件,Xcode就是一个模拟器,可以模拟 iPhone 任何版本的手机
    在这里插入图片描述
    点击运行
    在这里插入图片描述
    在这里插入图片描述
    点击运行就可以在ios模拟器上运行项目了

    十五、uni-app 在 ios 打包

    在这里插入图片描述
    ios 打包 在申请证书的时候需要钱,其它的步骤和安卓一样

    十六、uni-app 跨端兼容(css)

    在这里插入图片描述
    1、上图 APP 和 小程序 的可视窗口是有颜色的部分(去掉 tabbar 和 navigateBar),H5页面是整个手机的高度
    所以在每个页面中尽量

    page{
    	height: 100%;
    }
    
    • 1
    • 2
    • 3

    2、定位的时候需要注意:
    直接写 bottom: 0; 在H5端不行的,
    使用uni-app 提供的css 内置的变量 --window-bottom
    官方链接
    3、uni-app 在 H5端和APP端默认 scoped是打开的,这就造成了用微信小程序生成的骨架屏样式问题
    需要将样式抽离出去
    @import “./style/xxx.scss” 引进来
    4、vue3 语法尽量还是将模板放到一个根标签中,避免不必要的样式错乱问题

    十七、uni-app 跨端兼容(组件)

    wx.login()
    wx.requestPayment()
    button 按钮中 open-type
    等等都是微信小程序中特有的, 放在 H5 端 和 APP 端没有效果

    十八、uni-app(vue3语法)配置eslint + prettier

    安装依赖

    pnpm i -D eslint prettier eslint-plugin-vue @vue/eslint-config-prettier @vue/eslint-config-typescript @rushstack/eslint-patch @vue/tsconfig

    项目根目录创建 .eslintrc.js 和 .prettierrc.json 文件

    // eslintrc.js 文件
    
    /* eslint-env node */
    require("@rushstack/eslint-patch/modern-module-resolution")
    
    module.exports = {
        root: true,
        extends: [
            "plugin:vue/vue3-essential",
            "eslint:recommended",
            "@vue/eslint-config-typescript",
            "@vue/eslint-config-prettier",
        ],
        // 小程序全局变量
        globals: {
            uni: true,
            wx: true,
            WechatMiniprogram: true,
            getCurrentPages: true,
            getApp: true,
            UniApp: true,
            UniHelper: true,
            App: true,
            Page: true,
            Component: true,
            AnyObject: true,
        },
        parserOptions: {
            ecmaVersion: "latest",
        },
        rules: {
            "prettier/prettier": [
                "warn",
                {
                    singleQuote: false,
                    semi: false,
                    printWidth: 100,
                    trailingComma: "all",
                    endOfLine: "auto",
                },
            ],
            "vue/multi-word-component-names": ["off"],
            "vue/no-setup-props-destructure": ["off"],
            "vue/no-deprecated-html-element-is": ["off"],
            "@typescript-eslint/no-unused-vars": ["off"],
        },
    }
    
    
    // .prettierrc.json 文件
    {
        "singleQuote": false,
        "semi": false,
        "printWidth": 400,
        "trailingComma": "all",
        "endOfLine": "auto"
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    在 package.json 文件的 scripts 脚本中添加

    "dev": "xxxx",
    "lint": "eslint . --ext .vue,.js,.ts --fix --ignore-path .gitignore"
    
    • 1
    • 2

    到此就配置好了
    vscode 编辑器安装 eslint 和 Prettier - Code formatter 插件

    安装好了之后在项目根目录下创建 .editorconfig 文件

    // .editorconfig 文件是 自己项目里面的配置,权重大于 vscode 设置里面的配置
    
    # editorconfig.org
    root = true
    
    [*]
    indent_style = space
    indent_size = 4
    end_of_line = lf
    charset = utf-8
    trim_trailing_whitespace = true
    insert_final_newline = true
    
    [*.md]
    trim_trailing_whitespace = false
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    项目根目录下创建 .vscode/extensions.json 、 .vscode/launch.json 、 .vscode/settings.json 三个文件

    // extensions.json 文件
    {
        // 推荐的扩展插件
        "recommendations": [
            "mrmaoddxxaa.create-uniapp-view", // 创建 uni-app 页面
            "uni-helper.uni-helper-vscode", // uni-app 代码提示
            "evils.uniapp-vscode", // uni-app 文档
            "vue.volar", // vue3 语法支持
            "vue.vscode-typescript-vue-plugin", // vue3 ts 插件
            "editorconfig.editorconfig", // editorconfig
            "dbaeumer.vscode-eslint", // eslint
            "esbenp.prettier-vscode" // prettier
        ]
    }
    
    
    
    // launch.json 文件
    {
        // 使用 IntelliSense 了解相关属性。 
        // 悬停以查看现有属性的描述。
        // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
        "version": "0.2.0",
        "configurations": [
            {
                "type": "chrome",
                "request": "launch",
                "name": "针对 localhost 启动 Chrome",
                "url": "http://localhost:8080",
                "webRoot": "${workspaceFolder}"
            }
        ]
    }
    
    
    
    // settings.json 文件
    {
        // 在保存时格式化文件
        "editor.formatOnSave": true,
        // 文件格式化配置
        "[json]": {
            "editor.defaultFormatter": "esbenp.prettier-vscode"
        },
        // 配置语言的文件关联
        "files.associations": {
            "pages.json": "jsonc", // pages.json 可以写注释
            "manifest.json": "jsonc" // manifest.json 可以写注释
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    到此vscode编辑器就可以正常检测文件了 保存也自动格式化代码了

    十九、uni-app(vue3语法)配置 husky

    kusky 是验证提交代码的时候不符合eslint 规范不让提交

    1、下载husky

    pnpm i -D husky

    2、项目根目录创建 .husky 目录

    3、 初始化 husky

    pnpm dlx husky-init 或者 npx husky-init

    4、修改package.json 文件

    在 scripts 脚本中添加

    "dev": "xxx",
    "lint-staged": "lint-staged"
    
    • 1
    • 2

    与scripts 平级添加

    "lint-staged": {
        "*.{vue,ts,js}": [
             "eslint --fix"
        ]
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5

    5、下载 lint-staged

    pnpm i -D lint-staged

    6、修改文件 .husky/pre-commit ( 初始化husky 生成的)

    npm run lint-staged    // 增加
    npm test               // 删掉  
    
    • 1
    • 2

    到此 husky 配置完成, 提交试试,不符合 eslint 规范的代码直接报错,不让提交

  • 相关阅读:
    Ai-WB2模组HTTP 客户端 POST请求方法
    Elasticsearch 重点介绍
    深入解析:如何在遍历List时安全地删除元素
    【运维日常】mongodb 集群生产实践
    八大排序之交换排序
    Linux搭建我的世界MC服务器 【Minecraft外网联机教程】
    CSDN竞赛第六期第二题(C++)
    二叉树 | 所有路径 | 迭代&回溯 | leecode刷题笔记
    SpringBean生命周期
    PaddleSeg数据集的准备
  • 原文地址:https://blog.csdn.net/weixin_43993776/article/details/134260744