美文网首页
uniapp基础教程

uniapp基础教程

作者: 橙子只过今天 | 来源:发表于2022-03-25 17:46 被阅读0次

    1. 介绍

    uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝)、快应用等多个平台。

    uni-app在手,做啥都不愁。即使不跨端,uni-app也是更好的小程序开发框架(详见)、更好的App跨平台框架、更方便的H5开发框架。不管领导安排什么样的项目,你都可以快速交付,不需要转换开发思维、不需要更改开发习惯。

    2. 环境搭建

    2.1 安装编辑器HBuilder X (APP开发版)

    下载地址 通用前端开发工具,为uniapp做了特别强化

    插件安装(工具 -> 插件安装 -> 选择插件下载

    • sass

    • git

    • npm

      image.png

    2.2 安装微信开发者工具

    下载地址

    image.png

    3. 使用HBuilderX初始化项目

    文件 -> 新建 -> uniapp项目

    image.png

    微信开发者工具端口开放 设置 -> 安全设置 -> 端口开启

    image.png

    4. 项目目录及作用

    image.png

    ┌─components 符合vue组件规范的uni-app组件目录

    │ └─comp-a.vue 可复用的组件

    ├─pages 业务页面文件存放的目录

    │ ├─index

    │ │ └─index.vue index页面

    │ └─list

    │ └─list.vue list页面

    ├─static 存放应用引用的本地静态资源(如图片、视频等)的目录,注意: 静态资源只能存放于此

    ├─uni_modules 存放uni_module规范的插件

    ├─wxcomponents 存放小程序组件的目录

    ├─main.js Vue初始化入口文件

    ├─App.vue 应用配置,用来配置App全局样式以及监听 应用生命周期

    ├─manifest.json 配置应用名称、appid、logo、版本等打包信息

    └─pages.json 配置页面路由、导航条、选项卡等页面类信息

    • pages: 页面存放目录

    • static: 静态资源目录

    • unpackage: 打包输出目录

    • components: 组件存放目录

    • App.vue: 根组件,所有页面都在App.vue下进行切换,是页面入口文件,可以调用应用的生命周期函数。

    • main.js: 项目入口文件,初始化vue实例并使用需要的插件。

    • manifest.json: 应用的配置文件,用于指定应用的名称、图标、权限等。

    • pages.json: 对uni-app进行全局配置,决定页面文件的路径、窗口样式、原生的导航栏以及底部tabbar等。

    • uni.scss: 预置了scss变量预置,方便整体控制应用的风格,比如按钮颜色、边框风格

    开发规范:

    • 页面文件遵循Vue单文件组件(SFC)规范

    • 组件标签靠近小程序规范

    • 接口能力靠近小程序规范

    • 数据绑定及事件处理同Vue.js规范,同时补充了APP及页面规范生命周期

    • 为兼容多端运行,建议使用flex布局进行开发

    5. 全局配置和页面配置

    pages.json 配置手册

    globelStyle: 全局配置

    image.png

    pages: 页面配置 通过 pages 节点配置应用由哪些页面组成,pages 节点接收一个数组,数组每个项都是一个对象,其属性值如下:

    image.png image.png

    tabbar: 导航栏配置 在App和小程序端提升性能。在这两个平台,底层原生引擎在启动时无需等待js引擎初始化,即可直接读取 pages.json 中配置的 tabBar 信息,渲染原生tab。

    image.png image.png

    6. condition

    启动模式配置,仅开发期间生效,用于模拟直达页面的场景,如:用户点击所打开的页面 image.png

    7. uni-app组件

    搭建页面基础结构

    • 视图组件 view

      image.png
    • 基础组件 text

      image.png
    • 表单组件 button

      image.png
    • 媒体组件 image

      image.png

    8. 样式设置

    image.png

    9. 数据绑定和事件绑定

    同vue: v-bind\v-on

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n99" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); --select-text-bg-color: #36284e; --select-text-font-color: #fff; font-size: 0.9rem; line-height: 1.71429em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(218, 218, 218); position: relative !important; margin-bottom: 3em; margin-left: 2em; padding-left: 1ch; padding-right: 1ch; width: inherit; color: rgb(31, 9, 9); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><template>
    <view class="content">
    <image class="logo" src="/static/logo.png"></image>
    <view class="text-area">
    <text class="title">{{title}}</text>
    <input v-model="inputValue" @input="onChangeInput" />
    </view>
    <button @click="onClick"></button>
    </view>
    </template>

    <script>
    export default {
    data() {
    return {
    title: 'Hi',
    inputValue: '。。'
    }
    },
    onLoad() {

    },
    methods: {
    onClick(){
    console.log('click')
    },
    onChangeInput(){
    console.log(this.inputValue)
    }
    }
    }
    </script></pre>

    10. 生命周期

    • 应用生命周期 仅可在App.vue中监听,在页面监听无效。

      image.png
    • 页面生命周期 image.png

    11. 下拉刷新

    11.1 开启下拉刷新

    pages.json中加入下拉刷新属性,globalStyle为全局添加,page中为单页面添加

    image.png

    11.2 在页面中进行uni.startPullDownRefresh(OBJECT)调用

    官方文档查看 开始下拉刷新,调用后触发下拉刷新动画,效果与用户手动下拉刷新一致。

    image.png

    11.3 监听下拉刷新

    在页面生命周期中加入监听事件。当处理完数据刷新后,uni.stopPullDownRefresh可以停止当前页面的下拉刷新。

    image.png

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n114" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); --select-text-bg-color: #36284e; --select-text-font-color: #fff; font-size: 0.9rem; line-height: 1.71429em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(218, 218, 218); position: relative !important; margin-bottom: 3em; margin-left: 2em; padding-left: 1ch; padding-right: 1ch; width: inherit; color: rgb(31, 9, 9); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">onPullDownRefresh() {
    console.log('刷新了');
    uni.stopPullDownRefresh();
    }</pre>

    12. 网络请求

    uni.request(Object)

    image.png

    13. 数据存储

    • 异步存储 uni.setStorage(OBJECT) 将数据存储在本地缓存中指定的 key 中,会覆盖掉原来该 key 对应的内容

      image.png

      uni.getStorage(OBJECT) uni.removeStorage(OBJECT)

    • 同步存储 uni.setStorageSync(KEY, DATA) 将 data 存储在本地缓存中指定的 key 中,会覆盖掉原来该 key 对应的内容

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n124" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); --select-text-bg-color: #36284e; --select-text-font-color: #fff; font-size: 0.9rem; line-height: 1.71429em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(218, 218, 218); position: relative !important; margin-bottom: 3em; margin-left: 2em; padding-left: 1ch; padding-right: 1ch; width: inherit; color: rgb(31, 9, 9); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">try {
    uni.removeStorageSync('storage_key');
    } catch (e) {
    // error
    }</pre>

    uni.getStorageSync(KEY) uni.removeStorageSync(KEY)

    14. 图片上传预览

    uni.chooseImage(OBJECT) 从本地相册选择图片或使用相机拍照。

    image.png

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n128" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); --select-text-bg-color: #36284e; --select-text-font-color: #fff; font-size: 0.9rem; line-height: 1.71429em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(218, 218, 218); position: relative !important; margin-bottom: 3em; margin-left: 2em; padding-left: 1ch; padding-right: 1ch; width: inherit; color: rgb(31, 9, 9); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">uni.chooseImage({
    count: 6, //默认9
    sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
    sourceType: ['album'], //从相册选择
    success: function (res) {
    console.log(JSON.stringify(res.tempFilePaths));
    }
    });</pre>

    uni.previewImage(OBJECT) 预览图片。

    image.png

    15. 条件编译跨端兼容

    注释: #ifdef <端名>... #endif image.png

    16. 导航跳转和传参

    在起始页面跳转到test.vue页面并传递参数

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n135" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); --select-text-bg-color: #36284e; --select-text-font-color: #fff; font-size: 0.9rem; line-height: 1.71429em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(218, 218, 218); position: relative !important; margin-bottom: 3em; margin-left: 2em; padding-left: 1ch; padding-right: 1ch; width: inherit; color: rgb(31, 9, 9); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">uni.navigateTo({
    url: 'test?id=1&name=uniapp'
    });</pre>

    在页面接受参数

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n137" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); --select-text-bg-color: #36284e; --select-text-font-color: #fff; font-size: 0.9rem; line-height: 1.71429em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(218, 218, 218); position: relative !important; margin-bottom: 3em; margin-left: 2em; padding-left: 1ch; padding-right: 1ch; width: inherit; color: rgb(31, 9, 9); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">export default {
    onLoad: function (option) { //option为object类型,会序列化上个页面传递的参数
    console.log(option.id); //打印出上个页面传递的参数。
    console.log(option.name); //打印出上个页面传递的参数。
    }
    }</pre>

    17. 组件创建、生命周期与父子组件传值

    (同vue)


    1647498320670.png

    18. request封装(引用参考文章2)

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n142" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); --select-text-bg-color: #36284e; --select-text-font-color: #fff; font-size: 0.9rem; line-height: 1.71429em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(218, 218, 218); position: relative !important; margin-bottom: 3em; margin-left: 2em; padding-left: 1ch; padding-right: 1ch; width: inherit; color: rgb(31, 9, 9); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">var http = {
    post(path, params, contentType = 'form', otherUrl, ) {
    return new Promise((resolve, reject) => {
    var url = (otherUrl || config.baseUrl) + path
    if (!checkUrl(url)) {
    rej('请求失败')
    }
    uni.request({
    method: 'POST',
    url,
    header: {
    "Content-Type": contentType === 'json' ? "application/json" :
    "application/x-www-form-urlencoded"
    },
    data: params,
    success: (res) => {
    console.log('request:POST请求' + config.baseUrl + path + ' 成功', res.data)
    resolve(res.data)
    },
    fail: (err) => {
    message.toast('请求失败', 'err')
    console.error('request:请求' + config.baseUrl + path + ' 失败', err)
    reject('请求失败')
    }
    })
    })
    },
    put(path, params, contentType = 'form', otherUrl, ) {
    return new Promise((resolve, reject) => {
    var url = (otherUrl || config.baseUrl) + path
    if (!checkUrl(url)) {
    rej('请求失败')
    }
    uni.request({
    method: 'PUT',
    url,
    header: {
    "Content-Type": contentType === 'json' ? "application/json" :
    "application/x-www-form-urlencoded"
    },
    data: params,
    success: (res) => {
    console.log('request:PUT请求' + config.baseUrl + path + ' 成功', res.data)
    resolve(res.data)
    },
    fail: (err) => {
    message.toast('请求失败', 'err')
    console.error('request:PUT请求' + config.baseUrl + path + ' 失败', err)
    reject('请求失败')
    }
    })
    })
    },

    get(path, params, otherUrl) {
    return new Promise((resolve, reject) => {
    var url = (otherUrl || config.baseUrl) + path
    if (!checkUrl(url)) {
    return
    }
    uni.request({
    url,
    data: params,
    success: (res) => {
    console.log('request:GET请求' + config.baseUrl + path + ' 成功', res.data)
    resolve(res.data)
    },
    fail: (err) => {
    message.toast('请求失败', 'err')
    console.error('request:GET请求' + config.baseUrl + path + ' 失败', err)
    reject(err)
    }
    })

    })

    },
    delete(path, params, otherUrl) {
    return new Promise((resolve, reject) => {
    var url = (otherUrl || config.baseUrl) + path
    if (!checkUrl(url)) {
    return
    }
    uni.request({
    url,
    data: params,
    method: "DELETE",
    success: (res) => {
    console.log('request:DELETE请求' + config.baseUrl + path + ' 成功', res.data)
    resolve(res.data)
    },
    fail: (err) => {
    message.toast('请求失败', 'err')
    console.error('request:DELETE请求' + config.baseUrl + path + ' 失败', err)
    reject(err)
    }
    })

    })

    },

    async upload(path, fileArray, otherUrl) {

    if (typeof fileArray !== 'object') {
    console.error('request:参数错误,请传入文件数组')
    return
    }
    var url = (otherUrl || config.baseUrl) + path
    if (!checkUrl(url)) {
    return
    }
    var arr = []
    for (let i in fileArray) {
    const res = await uni.uploadFile({
    url: otherUrl || config.baseUrl + path,
    filePath: fileArray[i],
    name: 'file'
    })
    console.log(res)
    if (res[0]) {
    console.error('request:上传失败', res[0])
    return
    }
    arr.push(JSON.parse(res[1].data).data)
    }
    return arr
    },

    }

    function checkUrl(url) {
    var urlReg = /((ht|f)tps?)://[\w-]+(.[\w-]+)+([\w-.,@?=%&:/+#]*[\w-@?^=%&/+#])?$/;
    if (!urlReg.test(url)) {
    console.error('request:请求路径错误' + url)
    return false
    }
    return true
    }
    module.exports = http</pre>

    19. 小程序打包发布

    19.1 登录微信公众平台 -> 开发 -> 开发设置 -> 获取AppId放在manifest.json微信小程序配置的AppID中

    image.png

    19.2 Hbuilder中发行 -> 小程序-微信

    image.png

    19.3 微信开发者工具中点击上传 -> 上传

    image.png

    19.4 微信开发者平台 -> 版本管理 -> 选择提交的版本 -> 提交审核 -> 下一步填写信息 -> 提交审核 (-> 撤回审核)-> 审核成功 -> 上线

    image.png

    20. H5发布

    20.1 HBuilder中进入manifest.json H5页面 -> 设置标题

    image.png

    20.2 HBuilder中点击发行 -> 网站-H5手机版

    image.png

    参考文章:
    uniapp实现小程序微信登录
    uniapp小程序开发的超长实践总结

    相关文章

      网友评论

          本文标题:uniapp基础教程

          本文链接:https://www.haomeiwen.com/subject/mqphrrtx.html