# uniapp

# 小程序的打包上线流程

在HBuilder中进入manifes.json文件夹中,选择‘微信小程序配置’,在该配置下输入appid,勾选所有配置项以及“微信小程序权限配置”,点击“发行”,选择“小程序-微信(仅适用于uni-app)(w)”,弹出“微信小程序发行”模态框,默认项目项目名称和appid,点击发行,登录邮箱,随后跳转至微信开发者工具,设置域名验证等, 输入版本号和备注后点击上传。在微信小程序官网中点击“版本管理”,下面有个刚刚的开发版本,点击提交审核。

# uniapp使用过程中有哪些问题?

开发环境配置问题:uni-app需要安装Node.js和HBuilderX开发工具。如果开发环境没有正确配置,可能会导致项目无法正常运行。

兼容性问题:由于uni-app是一种跨平台框架,开发过程中需要考虑不同平台的兼容性。有些特定的API、样式或功能在某些平台上可能无法完全实现或存在差异。

调试问题:在uni-app开发中,经常需要进行调试来定位和解决问题。如果对调试工具和方法不熟悉,可能会浪费时间和精力。

性能问题:由于uni-app需要适配多个平台,性能方面可能会受到一些限制。在开发过程中,需要注意优化代码和资源,以提高应用的性能和响应速度。

社区支持问题:相比其他流行的框架,uni-app的社区规模相对较小。因此,在解决问题时,可能需要更多自主研究和探索,或者通过官方文档和论坛寻求帮助。

# 微信小程序登录流程

授权登录

  • 授权获取用户信息

    使用wx.getUserProfile()方法 弹出授权窗口,获取用户信息

    Page({
        getUserProfile() {
            wx.getUserProfile({
                desc: '用于完善个人资料',
                success: (res) => {
                    console.log(res.userInfo)
                },
                fail: (err) => {
                }
            })
        },
    })
    
  • 小程序登录

    • 使用wx.login()方法获取code

      Page({
          getCode() {
              wx.login({
                  success: (res) => {
                      console.log(res.code)
                  }
              })
          }
      })
      
    • 获取token

      先将code发送给后端,用来获取token,获取成功后并将其保存到本地

      Page({
          getToken() {
              wx.request({
                  url: 'http://47.98.128.191:3001/users/wxLogin',
                  method: 'POST',
                  data: {
                      code,
                      appId: 'wxded7871137340bad',
                      appSecret: '5e86d485eac69fe0e237331a6d2892e1',
                      userInfo: this.data.userInfo
                  },
                  success: ({ data }) => {
                      if(data.code) {
                          wx.setStorage({
                              key: 'token',
                              data: data.token
                          })
                      }
                  }
              })
          }
      })
      

      注意:

      • code:是必须的;
      • appId 和 appSecret:实际开发中,不需要传递,这里练习时我们传递自己的 appId 和 appSecret;
      • userInfo:是当前项目的服务器中需要该数据

# uniapp优缺点

优点: a. 一套代码可以生成多端 b. 学习成本低,语法是vue的,组件是小程序的 c. 拓展能力强 d. 使用HBuilderX开发,支持vue语法 e. 突破了系统对H5调用原生能力的限制 缺点: a. 问世时间短,很多地方不完善 b. 社区不大 c. 官方对问题的反馈不及时 d. 在Android平台上比微信小程序和iOS差 e. 文件命名受限

# uniapp的配置文件、入口文件、主组件、页面管理部分

695502e187b64123b7bf76724d9ae78b

pages.json 配置文件,全局页面路径配置,应用的状态栏、导航条、标题、窗口背景色设置等 main.js 入口文件,主要作用是初始化vue实例、定义全局组件、使用需要的插件如 vuex,注意uniapp无法使用vue-router,路由须在pages.json中进行配置。如果开发者坚持使用vue-router,可以在插件市场找到转换插件。 App.vue 是uni-app的主组件,所有页面都是在App.vue下进行切换的,是页面入口文件。但App.vue本身不是页面,这里不能编写视图元素。除此之外,应用生命周期仅可在App.vue中监听,在页面监听无效。 pages 页面管理部分用于存放页面或者组件 manifest.json 文件是应用的配置文件,用于指定应用的名称、图标、权限等。HBuilderX 创建的工程此文件在根目录,CLI 创建的工程此文件在 src 目录。 package.json 配置扩展,详情内容请见官网描述package.json概述

# jQuery、vue、小程序、uni-app中的本地数据存储和接收

	jQuery:
	存:$.cookie('key','value')
	取:$.cookie('key')
 
	vue:
	存储:localstorage.setItem(‘key’,‘value’)
	接收:localstorage.getItem(‘key’)
 
	微信小程序:
	存储:通过wx.setStorage/wx.setStorageSync写数据到缓存
	接收:通过wx.getStorage/wx.getStorageSync读取本地缓存,
 
	uni-app:
	存储:uni.setStorage({key:“属性名”,data:“值”}) //异步 
		uni.setStorageSync(KEY,DATA) //同步
	接收:uni.getStorage({key:“属性名”,success(res){res.data}}) //异步
		uni.getStorageSync(KEY) //同步
	移除:uni.removeStorage(OBJECT) //从本地缓存中异步移除指定 key。
		uni.removeStorageSync(KEY) //从本地缓存中同步移除指定 key。
	清除:uni.clearStorage() //清理本地数据缓存。
		uni.clearStorageSync() //同步清理本地数据缓存。

# 全局变量globalData

// app.vue
<script>  
    export default {  
        globalData: {  
            msg: 'hello world'  
        }
    }  
</script>
//在其他页面调用/修改全局变量 getApp().globalData.msg= 'hello world'

# 微信小程序生命周期

应用生命周期:

  • onLaunch: 初始化小程序时触发,全局只触发一次
  • onShow: 小程序初始化完成或用户从后台切换到前台显示时触发
  • onHide: 用户从前台切换到后台隐藏时触发
  • onError: 小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息

页面生命周期:

  • onLoad:首次进入页面加载时触发,可以在 onLoad 的参数中获取打开当前页面路径中的参数。
  • onShow:加载完成后、后台切到前台或重新进入页面时触发
  • onReady:页面首次渲染完成时触发
  • onHide:从前台切到后台或进入其他页面触发
  • onUnload:页面卸载时触发

用户行为:

  • onPullDownRefresh:监听用户下拉动作

  • onReachBottom:页面上拉触底事件的处理函数

  • onShareAppMessage:用户点击右上角转发

  • onPageScroll:页面滚动触发事件的处理函数

# uniapp生命周期

应用生命周期:

周期函数
onLaunch 当uni-app 初始化完成时触发(全局只触发一次)
onShow 当 uni-app 启动,或从后台进入前台显示(显示页面的时候触发)
onHide 当 uni-app 从前台进入后台(隐藏/退出页面的时候触发)
onError 当 uni-app 报错时触发
onUniNViewMessage 对 nvue 页面发送的数据进行监听
onUnhandledRejection 对未处理的 Promise 拒绝事件监听函数
onPageNotFound 页面不存在监听函数
onThemeChange 监听系统主题变化

页面生命周期:

周期函数
onInit 监听页面初始化,其参数同 onLoad 参数,触发时机早于 onLoad
onLoad 监听页面加载,其参数为上个页面传递的数据,参数类型为 Object(用于页面传参)
onShow 监听页面显示。页面每次出现在屏幕上都触发,包括从下级页面点返回当前页面
onReady 监听页面初次渲染完成。注意如果渲染速度快,会在页面进入动画完成前触发
onHide 监听页面隐藏
onUnload 监听页面卸载
onResize 监听窗口尺寸变化
onPullDownRefresh 监听用户下拉动作,一般用于下拉刷新
onReachBottom 页面滚动到底部的事件(不是scroll-view滚到底),常用于下拉下一页数据
onTabItemTap 点击 tab 时触发,参数为Object
onShareAppMessage 用户点击右上角分享
onPageScroll 监听页面滚动,参数为Object
onNavigationBarButtonTap 监听原生标题栏按钮点击事件,参数为Object
onBackPress 监听页面返回
onNavigationBarSearchInputChanged 监听原生标题栏搜索输入框输入内容变化事件
onNavigationBarSearchInputConfirmed 监听原生标题栏搜索输入框搜索事件,用户点击软键盘上的“搜索”按钮时触发
onNavigationBarSearchInputClicked 监听原生标题栏搜索输入框点击事件(pages.json 中的 searchInput 配置 disabled 为 true 时才会触发)
onShareTimeline 监听用户点击右上角转发到朋友圈
onAddToFavorites 监听用户点击右上角收藏

组件生命周期:同vue2生命周期

# 路由与页面跳转

uniapp的页面跳转和小程序是一样的,都是跳转配置好的页面路径, 并且tab页面也是需要使用switchTab才能实现跳转,总体上和小程序保持一致,对于熟练小程序的朋友上手没有难度,反之,当你习惯了uniapp的页面切换组件后上手小程序也很快。

微信小程序 uniapp
wx.navigateTo<navigator> uni.navigateTo 保留当前页面,跳转到应用内的某个页面(非 tabBar)
wx.redirectTo uni.redirectTo 关闭当前页面,跳转到应用内的某个页面(非 tabBar)
wx.switchTab uni.switchTab 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
wx.reLaunch uni.reLaunch 关闭所有页面,打开到应用内的某个页面
wx.navigateBack uni.navigateBack 关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages() 获取当前的页面栈,决定需要返回几层

# 跨端适配—条件编译

开发者按照 uni-app 规范开发即可保证多平台兼容,大部分业务均可直接满足。但每个平台有自己的一些特性,因此会存在一些无法跨平台的情况。因此就有了条件编译这个模式,不仅是js逻辑代码,template和css样式都可以设置成在某个环境中生效,在其他环境不生效

//template
<!--  #ifdef  MP-WEIXIN -->
<!--  只在小程序中生效 -->
<view>我是微信小程序</view>
<!--  #endif -->
 
<!--  #ifdef  APP-PLUS -->
<!--  只在 app 中生效 -->
<view>我是 app </view>
<!--  #endif -->
 
//js
// #ifndef H5
// 表示只有 h5 不使用这个 api
uni.createAnimation(OBJECT)
// #endif

//css
/* #ifdef  MP-WEIXIN */
/*  只在小程序中生效  */
.header {
	color:red
}
/*  #endif  */

# uniapp上传文件时使用的api

//选择文件
uni.chooseFile({
  count: 6, //默认100
  extension:['.zip','.doc'],
    success: function (res) {
        console.log(JSON.stringify(res.tempFilePaths));
    }
});
 
// 选择图片文件
uni.chooseImage({})

# 简述 rpx、px、em、rem、%、vh、vw的区别

  • rpx:相当于把屏幕宽度分为750份,1份就是1rpx

  • px:绝对单位,页面按精确像素展示

  • em:相对单位,相对于它的父节点字体进行计算

  • rem:相对单位,相对根节点html的字体大小来计算

  • %:一般来说就是相对于父元素

  • vh:视窗高度,1vh等于视窗高度的1%

  • vw:视窗宽度,1vw等于视窗宽度的1%

# jq、vue、uni-app、小程序的页面传参方式区别

  • jq传参 通过url拼接参数进行传参。

  • vue传参 一、 vue可以通过标签router-link跳转传参,通过path+路径,query+参数 二、 也可以通过事件里的this.$router.push({})跳转传参

  • 小程序/uniapp传参 通过跳转路径后面拼接参数来进行跳转传参

    //示例
    // navigate.vue页面接受参数
    onLoad: function (option) {
    	const item = JSON.parse(decodeURIComponent(option.item));
    }
    

# uniapp实现下拉刷新

实现下拉刷新需要用到uni.onPullDownRefresh和uni.stopPullDownRefresh这个两个函数,函数与生命周期同等级可以监听页面下拉动作

//1.在pages.json文件里找到需要下拉刷新的页面pages节点,并在 style 选项中开启enablePullDownRefresh。
{
	"path": "pages/index/index",
	"style": {
		"navigationBarTitleText": "首页",
		"enablePullDownRefresh": true
	}
},
//2.在页面中调用监听下拉事件函数
onPullDownRefresh() {
	//do some
	this.Fn()
}
//3.获取数据完毕后调用停止下拉刷新动画
Fn(){
//可以在调用的函数中获取接口数据或则操作其他事项
//调取完毕后停止下拉刷新动画
	uni.stopPullDownRefresh();
}

# uniapp实现上拉加载

uniapp中的上拉加载是通过onReachBottom()这个生命周期函数实现,当下拉触底时就会触发。我们可以在此函数内调用分页接口请求数据,用以获取更多的数据

onReachBottom() {
        let data = this.data;
        let pageNum = data.pageNum;
        let pageStatus = 'loadmore';
        if (data.pageNum * data.pageSize >= data.pageTotal) {
            pageStatus = 'nomore';
        }
        if (pageStatus === 'loadmore') {
            pageNum++;
            pageStatus = 'loading';
            this.setData({
                pageNum: pageNum
            }, () => {
                this.getDataList();
            })
        }
        this.setData({pageStatus})
    },
/*我司的做法是用total来判断是否还有数据可以请求,还有的话就继续请求接口数据,并更新状态及分页数据;

# scroll-view吸顶问题-*

问题: scroll-view 是常会用到的一个标签,我们可以使用 position:sticky 加一个边界条件例如top:0 属性实现一个粘性布局,在容器滚动的时候,如果我们的顶部标签栏触碰到了顶部就不会再滚动了,而是固定在顶部。但是在小程序中如果你在scroll-view元素中直接为子元素使用sticky属性,你给予sticky的元素在到达父元素的底部时会失效。

解决: 在scroll-view元素中,再增加一层view元素,然后在再将使用了sticky属性的子元素放入view中,就可以实现粘贴在某个位置的效果了

# 关于uniapp项目中页面之间传递数据的三种方式

第一种(在跳转页面时使用URL编程式传参)

单向传递:只能上级页面传递到下级页面

双向传递:上级页面可以传递给下级页面,下级页面也可以传递给上级页面

上级页面(使用events,利用下级页面向上级页面传递数据的变量名获取传递的参数)

preserveRevise(){
	uni.navigateTo({
		url:'/pages/addressMange/addressMange?id=1',
		events:{
			//获取下级页面传递回来的参数
			sonPageData:data=>{
				console.log(data);
			}
		}
	})
}

下级页面(利用this.getOpenerEventChannel().emit向上级页面传递参数的变量名和变量值)

onLoad(e){
	console.log(e.id);
	this.getOpenerEventChannel().emit('sonPageData',"我是第二个页面传递回来的数据")
}

第二种

利用uni.setStorageSync和uni.getStorageSync进行数据的缓存和取出以及最后对缓存数据的销毁

上级页面(对需要传递的数据进行数据缓存)

注意:缓存的数据必须为字符串形式,对象或数组需要先进行转换

let item = JSON.stringify(this.userInfo[e])
uni.setStorageSync('userInfo',item)

下级页面(对缓存的数据进行取出并且进行销毁)

onLoad() {
	console.log("进入了编辑地址页面");
	var data = uni.getStorageSync('userInfo')//取出缓存数据
	var res = JSON.parse(data)
	this.userInfo = res
	uni.removeStorageSync('userInfo')
	var data = uni.getStorageSync('userInfo')//销毁缓存数据
	console.log(data);
}

第三种

利用uni.$emit 和 uni.$on进行跨页面传值

传递值页面(使用uni.$emit传递值的变量名和变量值)

uni.$emit('addUserInfo',this.userInfo)

接收值页面(在onload周期中使用uni.$on接收已经传递的参数)

uni.$on('addUserInfo',res=>{
	console.log(res);
})

注意:uni.$emit 和 uni.$on属于全局跨页面传参,在接收值页面要在onUnload周期添加移除监听时间。

onUnload() {
	uni.$off('addUserInfo')
}

# uniapp项目页面之间传值

一、传单个或多个参数

方法:直接在地址后面拼接

1、在将要跳转的页面上地址后面拼接要传递的参数,传递多个时用&符拼接

//任务列表页传递id  跳转到相应的任务详情页
gettaskList(id){
    //传递多个参数时直接用&符拼接
	uni.navigateTo({
		url:'gettaskList?id=${id}'
	})
}

2、接收时,在页面的onload函数中接收传递过来的参数

// 任务详情页通过 onLoad 生命周期中接传递过来的参数 id
onLoad(option){
   console.log('上一个页面传递过来的参数', option)
   console.log('id', option.id)
   console.log('item', option.item)
   // 接下来就是你需要该id做些什么,比如通过id查询到该详情等
}

二、传递对象

如需要传递的参数有很多时,由于uniapp跳转页面api 的 url 有长度限制,使用以下数据传递:

// item 为该列表的每一项的数据对象;encodeURIComponent 为uniapp 提供的api
getTaskList(item) {
	uni.navigateTo({
		 url: `getTaskList?item=${encodeURIComponent(JSON.stringify(item))}`,
	});
}

接收时

// 同样onLoad 生命周期中进行接收, decodeURIComponent 为uniapp 提供的api
onLoad(option) {
	const item = JSON.parse(decodeURIComponent(option.item));
	console.log('上一个页面传递过来的参数对象',item );
	// 接下来就是你需要该对象数据做些什么,当然这里你可以直接赋值给data绑定的数据
	this.objData = item;
}

注意:传递数据的时候必须使用 JSON.stringify 将其转为 JSON 字符串,然后接收的时候也必须使用 JSON.parse 来进行解析! 操作数组也是一样的,因为数组也是对象

# uniapp中封装接口请求相较于微信小程序有什么要注意的

uniapp和微信小程序都提供了网络请求API(uni.request(object) 和 wx.request(object)),但 uniapp 为了实现跨端兼容,需要注意网络请求跨域问题,微信小程序不用考虑多端兼容 ,也不会出现跨域问题。

简单讲: 如果uniapp要在web端进行适配,要注意请求跨域问题—需要配置代理

uniapp中的跨域问题依然可以通过在 vue.config.js 中配置Proxy代理解决;

封装的目的

发送请求的时候调用更简洁 添加一些通用的配置(超时时间,请求头)。 调用者没有传入配置的时候用默认的,调用者传入了相同 优先使用调用者 改成使用promise解决异步问题 统一维护域名 添加请求拦截器,在所有请求之前加一些通用的操作 代码响应之前,进行一些通用的操作 封装统一的http请求 针对于uni.request我们可以沿用之前我们在小程序中的封装思路,封装http请求

// vue.config.js for less-loader@6.0.0
module.exports = {
    devServer: {
        proxy: {
        	// 代理的名称,一般以这种格式命名,当然你也可以随便起
            '/xxx-api': {
                target: 'http://1.111.xx.123:3000',  // 后台接口的协议、域名、端口号
                changeOrigin: true,  //是否跨域
                pathRewrite: {
                    '^/xxx-api': ''//路径重写
                    //如果不重写,则请求时的路径中会带有这个/xxx-api
                }
            },
        }
    }
};


# 提高微信小程序速度的方法✈️

控制代码包的大小:

(1)代码包的体积压缩可以通过勾选开发者工具中“上传代码时,压缩代码”选项

(2)及时清理无用的代码和资源文件

(3)减少资源包中的图片等资源的数量和大小

分包加载,预加载

将用户访问率高的页面放在主包里,将访问率低的页面放入子包里,按需加载;采用子包预加载技术,并不需要等到用户点击到子包页面后在下载子包

预请求

请求可以在页面onLoad就加载,不需要等页面ready后在异步请求数据;尽量减少不必要的https请求,可使用 getStorageSync() 及 setStorageSync() 方法将数据存储在本地 避免不当的使用setData: 不要过于频繁调用setData,应考虑将多次setData合并成一次setData调用

使用自定义组件: 对于一些独立的模块我们尽可能抽离出来,这是因为自定义组件的更新并不会影响页面上其他元素的更新;各个组件也将具有各自独立的逻辑空间。每个组件都分别拥有自己的独立的数据、setData调用

# 我司目前官网加载过慢,如果请你优化,请简述优化思路?

css放顶部,js放底部 精灵图,字体图标 压缩代码 前端你的优化在于减少DOM的操作和减少页面的重排重绘

# 描述一下在Uniapp中,组件和页面的区别。

在Uniapp中,页面和组件的区别在于,页面是一个具体的应用页面,拥有独立的路由地址和生命周期函数,而组件是应用页面中的局部组件,包含在页面中,没有独立的路由地址和生命周期函数。

本章目录