uniapp中的持久化
使用Vuex来进行全局状态管理。Vuex是一个专为Vue.js应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
创建一个Vuex store:
// store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
}
})
export default store
注册挂载:
// main.js
import Vue from 'vue'
import store from './store'
new Vue({
store
}).$mount('#app')
this.$store.commit('increment')
console.log(this.$store.state.count) //
用于将指定的 mutations 映射到组件的计算属性或方法中。
在 Vue.js 中,mutations 是用于修改 Vuex store 中状态的函数。mapMutations 是一个辅助函数,它可以将指定的 mutations 映射到组件中,使得组件可以直接调用这些 mutations 来修改 store 中的状态,而无需手动触发 mutations。
具体来说,mapMutations 接收两个参数:
- 第一个参数是命名空间(可选),用于指定要映射的 mutations 所属的模块命名空间。
- 第二个参数是一个数组,包含要映射的 mutations 的名称。
在你提供的代码中,...mapMutations('video', ['setVideoData']) 将名为 setVideoData 的 mutations 映射到组件中。这意味着你可以在组件中直接调用 this.setVideoData() 来触发 setVideoData mutations,从而修改 Vuex store 中的状态。
需要注意的是,mapMutations 只能映射 mutations,而不能映射 actions 或 getters。如果你需要映射 actions 或 getters,可以使用 mapActions 或 mapGetters 辅助函数。
...mapMutations('video', ['setVideoData'])
过滤器
在uni-app中,过滤器(Filter)是一种用于对数据进行格式化和处理的函数。它可以在模板中使用,将数据经过过滤器处理后再展示给用户。过滤器可以用于格式化日期、数字、字符串等数据,以及进行一些常见的数据处理操作。
过滤器的作用和使用场景:
- 数据格式化:过滤器可以用于格式化日期、时间、货币等数据,使其符合特定的展示需求。
- 数据处理:过滤器可以对数据进行一些常见的处理操作,如截取字符串、转换大小写、计算长度等。
过滤器的使用方法:
1. 定义过滤器:在uni-app的项目中,你可以在common/filters目录下创建一个过滤器文件,例如formatDate.js。在该文件中,定义一个函数作为过滤器的实现,接收一个参数(待处理的数据),并返回处理后的结果。例如:
// common/filters/formatDate.js
export function formatDate(value) {
// 处理逻辑
return processedValue;
}
注册过滤器:
// main.js
import Vue from 'vue';
import { formatDate } from './common/filters/formatDate';
Vue.filter('formatDate', formatDate);
在模板中使用过滤器:在模板中,使用|符号将过滤器应用到数据上。例如:
<template>
<div>
<p>{{ date | formatDate }}</p>
</div>
</template>
mescroll使用
Mescroll是一个优秀的下拉刷新和上拉加载的JS插件。它不仅支持PC和移动端的滚动条,还支持Vue, React, Angular, Uni-app等框架。
mescroll-uni
的实现借助了 微信小程序 中的 onPullDownRefresh 和 onReachBottom 这两个 页面 事件。因为 微信小程序组件中没有这两个事件,所以 mescroll-uni
在 页面 和 组件 中的使用方式 不同
以下是在uni-app中使用Mescroll的基本步骤:
-
安装:你可以通过npm来安装Mescroll:npm install mescroll.js --save
-
引入:在你的代码中,你可以使用import来引入Mescroll:import MescrollUni from ‘mescroll.js/mescroll-uni’
-
使用:在你的组件中,你可以创建一个Mescroll实例,并配置下拉刷新和上拉加载的回调函数。例如:
export default {
data() {
return {
mescroll: null
}
},
mounted() {
this.mescroll = new MescrollUni("#mescroll", {
down: {
callback: this.downCallback //下拉刷新的回调
},
up: {
callback: this.upCallback //上拉加载的回调
}
});
},
methods: {
downCallback(mescroll) {
//在这里加载数据
//加载完毕后,调用mescroll.endSuccess()方法结束下拉刷新
},
upCallback(mescroll) {
//在这里加载数据
//加载完毕后,调用mescroll.endSuccess()方法结束上拉加载
}
}
}
在组件和在页面中使用方法不同,在组件中使用要在所在页面中添加相关代码。
软件盘的适配
监听高度,设置底部边距距离
uni.onKeyboardHeightChange(({ height }) => {
this.bottom = height;
});
关于v-if
区别于移动端的显示和隐藏,这里指的是移除和插入元素;
这里举一个uni-popup底部弹框每次弹出时上次内容依然显示的问题,这里就是直接用if标记,在消失的时候移除这个文本组件,而不是隐藏。
<uni-popup ref="popup" type="bottom" @change="onCommitPopupChange">
<article-comment-commit
v-if="isShowCommit"
:articleId="articleId"
@success="onSendSuccess"
/>
</uni-popup>
关于动态参数
这是一个常规的属性参数的定义格式:
<a v-bind:href="url"> ... </a>
<!-- 简写 -->
<a :href="url"> ... </a>
动态参数的意思是前面的属性名称是不确定可变换的,声明方式如下:
<a v-bind:[attributeName]="url"> ... </a>
<!-- 简写 -->
<a :[attributeName]="url"> ... </a>
attributeName可能有很多情况,如果它的值为“href”,那么他就等价于:
<a v-bind:href="url"> ... </a>
<!-- 简写 -->
<a :href="url"> ... </a>
另外,可以将函数绑定到对应的事件名称上
<a v-on:[eventName]="doSomething"> ... </a>
<!-- 简写 -->
<a @[eventName]="doSomething">
动态参数中表达式的值应当是一个字符串,或者是 null。特殊值 null 意为显式移除该绑定。其他非字符串的值会触发警告。
感觉很少用到。
关于响应式DOM的刷新
参考文档上说的,当响应式状态发生变化的时候,DOM的刷新操作会被触发,但是不是同步的。
Vue 会在“next tick”更新周期中缓冲所有状态的修改,以确保不管你进行了多少次状态修改,每个组件都只会被更新一次。
要等待 DOM 更新完成后再执行额外的代码,可以使用 nextTick() 全局 API:
import { nextTick } from 'vue'
async function increment() {
count.value++
await nextTick()
// 现在 DOM 已经更新了
}
那这个方法就返回一个promise喽。
关于mounted这个函数
mounted 方法是一个生命周期钩子函数,用于表示组件已经被挂载到页面上并且可以进行交互了。当组件被创建并插入到页面中时,mounted 方法会被调用。
在 mounted 方法中,你可以执行一些初始化操作,绑定事件监听器,请求数据,或者执行其他需要在组件挂载后进行的操作。
生命周期函数
- onLoad:在页面加载时触发,可以在这个钩子函数中进行页面初始化的操作。在 UniApp 中,onLoad 函数接收一个 options 参数,包含了页面跳转时传递的参数。
- onShow:在页面显示时触发,可以在这个钩子函数中执行一些需要在页面显示时更新的操作。在 UniApp 中,onShow 函数没有参数。
- onReady:在页面初次渲染完成时触发,可以在这个钩子函数中执行一些需要在页面渲染完成后进行的操作。
- onHide:在页面隐藏时触发,可以在这个钩子函数中执行一些需要在页面隐藏时处理的操作。
- onUnload:在页面卸载时触发,可以在这个钩子函数中执行一些页面卸载前的清理操作。
- onPullDownRefresh:在页面下拉刷新时触发,可以在这个钩子函数中执行一些下拉刷新的操作。
- onReachBottom:在页面触底时触发,可以在这个钩子函数中执行一些触底加载更多的操作。
- onShareAppMessage:在用户点击分享按钮或右上角菜单分享时触发,可以在这个钩子函数中自定义分享的内容。
导航传参
页面跳转如何传递参数
1.普通参数,通过get请求式的参数拼接
uni.navigateTo({
url: `/subpkg/pages/blog-detail/blog-detail?author=${item.user_name}&articleId=${item.id}`
});
对应页面获取参数
onLoad(options) {
this.author = options.author;
this.articleId = options.articleId;
this.loadArticleDetail();
}
页面的生命周期钩子函数包括 onLoad、onShow、onReady、onHide、onUnload 等。这里的onLoad 是在页面加载时触发的钩子函数。
2.传递一个对象
navigateTo似乎不支持传递复杂的对象,相比原生的话难得的不便捷的地方。
第一种考虑使用序列化,这种方式不知道推不推荐,没有尝试过;
uni.navigateTo({
url: '/pages/detail/detail?data=' + encodeURIComponent(JSON.stringify(obj))
});
对应页面反序列化获取数据:
onLoad: function(options) {
var data = JSON.parse(decodeURIComponent(options.data));
// 使用传递的对象参数
}
第二种就是用vuex进行存储了,跳转页面之前修改数据,跳转之后取数据使用;
为什么js中的函数、类等需要导出
相比java发现js的函数和类都要有export操作,为什么不能像java一样?
下面是chat-gpt给出的答案:
在 JavaScript 中,使用 export 关键字将变量、函数、类或对象导出是为了使其可以在其他文件中被引用和使用。JavaScript 是一种脚本语言,它的模块化系统是基于文件的,每个文件都可以被视为一个模块。通过导出和引入模块,可以实现代码的组织和复用。
****相比之下,Java 是一种编译型语言,它的模块化系统是基于类和包的。在 Java 中,类和包是代码组织的基本单位,可以通过类的访问修饰符(如 public、private)来控制类的可见性。在同一个包中的类可以直接访问彼此,而不需要显式地导出和引入。
****Java 的模块化系统更加严格和静态,需要在编译时确定类的可见性和访问权限。相比之下,JavaScript 的模块化系统更加灵活和动态,可以在运行时动态地导入和导出模块。
****需要注意的是,Java 中的类和方法可以通过访问修饰符来控制其可见性,但是如果要在其他包中使用某个类或方法,仍然需要通过 import 关键字进行引入。
****总结起来,JavaScript 中使用 export 关键字是为了实现模块化和代码复用,而 Java 中通过类和包的可见性和访问修饰符来控制代码的可见性和访问权限。
JavaScript 中的模块化系统(如 ES6 的模块化)可以提供更好的封装和访问控制,可以使用 export 和 import 关键字来导出和引入模块中的变量、函数和类
uniapp、vue、js的联系
JavaScript
- JavaScript(JS) 是一种广泛应用于网页开发的脚本语言,用于实现网页的交互功能和动态效果。
- 特点:JavaScript 是一种动态类型、弱类型的脚本语言,适用于前端和后端开发。
- 用途:用于编写网页交互逻辑、服务器端应用、移动应用等。
Vue
- Vue.js 是一种流行的 JavaScript 框架,用于构建用户界面和单页面应用。
- 特点:Vue 是一种渐进式框架,易于学习和使用,提供了响应式数据绑定和组件化开发的特性。
- 用途:用于构建交互式的前端应用,提供了丰富的工具和生态系统。
uni-app
- uni-app 是一个基于 Vue.js 的跨平台应用开发框架,可以同时开发多个平台的应用,如小程序、H5、App 等。
- 特点:uni-app 提供了一套统一的开发语法和组件库,使得开发者可以使用 Vue.js 的语法来开发多个平台的应用。
- 用途:用于快速开发跨平台应用,提高开发效率和代码复用性。
联系
- Vue 和 JavaScript:Vue.js 是基于 JavaScript 的框架,使用 JavaScript 来编写 Vue 组件和应用逻辑。
- uni-app 和 Vue:uni-app 基于 Vue.js,开发者可以使用 Vue 的语法和特性来开发跨平台应用。
- uni-app 和 JavaScript:uni-app 应用的底层仍然是 JavaScript,开发者可以在 uni-app 中直接编写 JavaScript 代码。
条件编译
两种语法
/* #ifdef H5 */
console.log('当前处于 H5 编译平台');
/* #endif */
/* #ifndef H5 */
console.log('当前处于非 H5 编译平台');
/* #endif */
uni-modules和组件
uni-app的插件模块化规范(HBuilderX 3.1.0+支持),通常是对一组js sdk、组件、页面、uniCloud云函数、公共模块等的封装,用于嵌入到uni-app项目中使用,也支持直接封装为项目模板。
特点:
- 封装性:uni-modules可以包含多个组件、JS库、页面等,它们共同实现特定的功能。
- 独立性:每个uni-module在项目中作为一个独立的模块存在,可以轻松添加到任何uni-app项目中。
- 复用性:uni-modules的设计使得它们可以在不同的项目之间复用,便于开发者分享和使用通用功能。
组件是uni-app中用于构建用户界面的基本单元。一个组件通常封装了一部分HTML结构、样式和一些基本行为,它可以被重复使用在多个页面或其他组件中。
特点:
- 封装性:组件封装了视图和逻辑,使得开发更加模块化。
- 重用性:组件可以被多次重用,无需重复编写相同的代码。
- 独立性:组件应设计为低耦合,高内聚,使其在不同的环境下都能正常工作。
区别
- 范围和复杂性:uni-modules通常比单个组件更复杂,可以包含多个组件、工具函数、页面等,而组件通常是单一的,专注于实现一个具体的UI功能。
- 用途:uni-modules用于封装和分发一组功能,可以看作是一个小的功能库或插件,而组件是构建这些功能的基本构建块。
- 管理方式:在uni-app项目中,uni-modules通常放在项目的uni_modules目录下,每个模块作为一个子目录存在,而组件可以存放在项目的components目录或者直接在页面目录下。
node版本命令
sudo npm cache clean -f //清除nodejs的cache:
sudo npm install -g n //使用npm安装n模块
npm view node versions // node所有版本
sudo n latest // 升级到最新版本
sudo n stable // 升级到稳定版本
sudo n xx.xx // 升级到具体版本号
插件
- uts插件
- APP原生插件
APP原生插件
非内置原生插件分为
- 本地插件
- 云端插件;
尝试插件使用
项目目录新建,nativeplugins目录,如果是cli创建的项目应该是在src下面;
1.从原生插件市场下载插件使用
以原生增强提示框插件 - DCloud 插件市场为例:
2.下载解压到nativeplugins中
3.在manifest.json中勾选这个原生插件
4.制作自定义基座
4.运行自定义基座
会出现一直卡死在 正在建立手机连接…这一步,尝试重启编译器,重新连接手机解决;
5.运行APP,点击弹出弹框
至此一个本地的原生插件就可以正常使用了。
尝试开发一个原生插件
开发者须知 | uni小程序SDK
打开离线SDK中的插件项目
注意gradle的版本会出现编译的问题;
一:扩展module插件
非UI插件,实现特定的功能;
创建一个新的module lib, 添加build.gradle中的必须依赖项
//必须添加的依赖
implementation 'com.github.bumptech.glide:glide:4.9.0'
implementation 'com.alibaba:fastjson:1.2.83'
implementation 'androidx.webkit:webkit:1.3.0'
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
implementation 'androidx.core:core:1.1.0'
implementation "androidx.fragment:fragment:1.1.0"
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
compileOnly fileTree(include: ['uniapp-v8-release.aar'], dir: '../app/libs')
创建module类
public class TestModule extends UniModule {
private static final String TAG = "TestModule";
@UniJSMethod(uiThread = true)
public void testAsyncFunc(JSONObject options, UniJSCallback callback) {
Log.e(TAG, "testAsyncFunc--"+options);
if(callback != null) {
JSONObject data = new JSONObject();
data.put("code", "success");
callback.invoke(data);
}
}
//run JS thread
@UniJSMethod (uiThread = false)
public JSONObject testSyncFunc(){
JSONObject data = new JSONObject();
data.put("code", "success");
return data;
}
}
禁止混淆
-keep public class * extends io.dcloud.feature.uniapp.common.UniModule{*;}
打包ARR,创建插件目录
配置json文件信息:
{
"name": "RichAlert",
"id": "DCloud-RichAlert",
"version": "0.1.3",
"description": "示例插件",
"_dp_type":"nativeplugin",
"_dp_nativeplugin":{
"ios": {
"plugins": [
{
"type": "module",
"name": "DCloud-RichAlert",
"class": "DCRichAlertModule"
}
],
"integrateType": "library",
"deploymentTarget": "8.0"
},
"android": {
"plugins": [
{
"type": "module",
"name": "DCloud-RichAlert",
"class": "uni.dcloud.io.uniplugin_richalert.RichAlertWXModule"
}
],
"integrateType": "aar",
"minSdkVersion" : 16
}
}
}
二:扩展component
UI组件比如官方的UniComponent,实现原生组件;
同上,官方的文档中有详细步骤;
三:插件的集成测试
1.注册插件
2.测试是相对于对应的平台项目的,所以像android端的话要运行uniapp的打包资源,再复制到项目目录下
在相关页面中增加使用插件的逻辑代码,打包资源再复制,运行Android项目进行测试。
注意事项
- Activity的获取方式。通过mUniSDKInstance.getContext()强转Activity。建议先instanceof Activity判断一下再强转
- .vue暂时只能使用module形式。component还不支持在.vue下使用
- component、module的生命周回调,暂时只支持onActivityDestroy 、onActivityPause、onActivityResult其他暂时不支持
Tips onActivityResume事件存在缺陷。应用第一次启动无法正常收到onActivityResume事件,后台切换到前台是可以收到的。
uts插件
uts插件分api和组件。这和uni-app的组件、api的概念是一样的。
- api插件:uts插件扩展了api能力,在script里调用
- 组件插件:uts插件扩展了界面组件,在template里调用。它是要内嵌在页面中