uni-app笔记
快捷键
看文档 --光标放在组件代码上,按F1
引入iconfont
本地引用
如果有.css文件
- 直接将.css文件引用到页面中(仅此页面使用)或App.vue中(全局使用)
或 - 将.css文件内容复制到页面中(仅此页面使用)或App.vue中(全局使用)
文件类型分别是.eot .svg .ttf .woff
- 在App.vue中引入文件并设定样式
@font-face {
font-family: 'iconfont';
src: url('./static/font/iconfont.eot'); /* IE9*/
src: url('./static/font/iconfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('./static/font/iconfont.woff') format('woff'), /* chrome、firefox */
url('./static/font/iconfont.ttf') format('truetype'), /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/
url('./static/font/iconfont.svg#iconfont') format('svg'); /* iOS 4.1- */
}
.iconfont {
font-family: "iconfont" !important;
font-size: 18px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
-
不知道图标代码的话可以用iconfont Preview查看icon代码
-
在页面中使用
<i class="iconfont"></i>
- 就会显示出相应图标
远程引用
在iconfont网站找的话直接就有代码,复制到css中就好了
使用iconfont
动态使用iconfont
直接使用代码的话
找到iconfont的unicode
iconfont官网的可以这么找
在代码里引用 注意前面要加\u
html获取用户IP地址和所属国家信息
这个是在html项目用的,uniapp可以举一反三
淘宝IP地址库可以根据ip地址获取国家、省市、运营商信息。 (浏览器里会有跨域问题= =)
具体代码如下
获取accessKey
这个接口可以用 "http://ip-api.com/json/?fields=520191&lang=en"
<script src="http://pv.sohu.com/cityjson?ie=utf-8"></script> <!--获取ip地址和城市-->
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script> <!--引入jQuery-->
<script type="text/javascript">
// console.log(returnCitySN["cip"]+','+returnCitySN["cname"])
$(function () {
$.ajax({
//ip=myip直接就可以使用本机ip "https://ip.taobao.com/outGetIpInfo?ip=myip&accessKey=alibaba-inc"
url: "https://ip.taobao.com/outGetIpInfo?ip=" + returnCitySN["cip"],
type:"get",
dataType:"json",
success:function(obj){
console.log(obj)
let country = obj.data.country;
},
fail: function(err) {
console.log(err);
}
});
});
</script>
html获取浏览器语言
var type = navigator.appName;
if (type == "Netscape"){
var lang = navigator.language;//获取浏览器配置语言,支持非IE浏览器
}else{
var lang = navigator.userLanguage;//获取浏览器配置语言,支持IE5+ == navigator.systemLanguage
};
var lang = lang.substr(0, 2);//获取浏览器配置语言前两位
if (lang == "zh"){
langTp = "China";
}else if (lang == "ms"){
langTp = "Malay";
}else{//其他语言编码时打开以下链接
langTp = "English";
};
html动态改变显示
//改变属性 图片路径
document.getElementById("picture_1").src = imgFile[langTp] + '/1.jpg';
//改变title
document.getElementById("title").textContent = title[langTp];
uniapp获取html字符串并显示
获取到一段html的字符串"<div>html</div>"
,想要显示在uniapp里
可以使用richText,可以看官网介绍
<rich-text :nodes="htmlStr"></rich-text>
有时可能还需要修改修改
可以看replace文档
//替换图片域名
this.htmlStr = this.htmlStr.replace(/\.\/public/g,this.$util.GetHttpRequestURL("goodsDescriptionImg") + "public")
//替换无用\\符号
this.htmlStr = this.htmlStr.replace(/\\/g, "")
//修改图片样式
this.htmlStr = this.htmlStr.replace(/<img/g, "<img style=\'max-width:100%;\'");
添加crisp客服
可以看这篇文章免费的网站在线客服聊天系统
好像可以直接生成html代码
html:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;" name="viewport">
<meta content="black" name="apple-mobile-web-app-status-bar-style">
<meta content="false" name="twcClient" id="twcClient">
<meta content="no-cache,must-revalidate" http-equiv="Cache-Control">
<meta content="no-cache" http-equiv="pragma">
<meta content="0" http-equiv="expires">
<!--允许全屏模式-->
<meta content="yes" name="apple-mobile-web-app-capable" />
<!--指定sari的样式-->
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta content="telephone=no" name="format-detection" />
<script type="text/javascript">
var APP_ROOT = '{$APP_ROOT}';
var LOADER_IMG = '{$TMPL}/images/loader_img.gif';
var LOADING_IMG = '{$TMPL}/images/loading.gif';
var AJAX_URL = '{url x="index" r="ajax"}';
var PAGE_TYPE = '{$PAGE_TYPE}';
var HOME_COUNTING = '{$lang.HOME_COUNTING}';
</script>
<link rel="stylesheet" type="text/css" href="{function name="parse_css" v="$pagecss"}" />
<script type="text/javascript" src="{function name="parse_script" v="$pagejs" c="$cpagejs"}"></script>
<script>
/*app 请求时候用到*/
$(function(){
{if $PAGE_TYPE eq 'app'}
App.page_title('{$data.page_title}');
if($(".hide_list")){
$(".hide_list").addClass("page_type_app");
}
{/if}
//后退
$('#header_back_btn').click(function(){
var Expression=/http(s)?:\/\/?/;
var objExp=new RegExp(Expression);
var backurl = $(this).attr('backurl');
$(this).attr('backurl','-1');
if(objExp.test(backurl)==true){
location.href = backurl;
}else{
window.history.go(-1);
}
});
});
</script>
<script type="text/javascript">
window.$crisp = [];
window.CRISP_WEBSITE_ID = "f411e27d-4170-40e7-af77-f852bbf03ebe";
(function () {
d = document;
s = d.createElement("script");
s.src = "https://client.crisp.chat/l.js";
s.async = 1;
d.getElementsByTagName("head")[0].appendChild(s);
})();
$crisp.push(["do", "chat:hide"]);
$crisp.push(["safe", true]);
$crisp.push(["on", "chat:closed", function () {
$crisp.push(["do", "chat:hide"]);
}])
</script>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-133F9WYE3T"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-133F9WYE3T');
</script>
</head>
<body>
<div class="content" >
<div class="fixBottom">
<div class="service-btn" onclick="onTapService(event)">
Tap to open service
</div>
</div>
</div>
</body>
</html>
<script type="text/javascript">
function onTapService(event) {
event.stopPropagation(); //阻止点击穿透
$crisp.push(['do', 'chat:show']);
$crisp.push(['do', 'chat:open']);
}
</script>
<style>
.content {
width: 100%;
height: 100%;
position: relative;
display: flex;
-webkit-justify-content: center;
justify-content: center;
}
</style>
uniapp:
使用web-view 组件调用本地html
通过设置web-viwe样式适配手机顶部
web-view中内嵌html页面可以使用部分uniapp接口,如uni.navigateTo() url是相对于web-view所在vue的路径
可参考web-view文档
保存数据到本地
//保存、更新数据到本地
function saveDatToStorage(key,value,isSync) {
if (isSync) {
uni.setStorageSync({
key: key,
data: JSON.stringify(value)
});
}else {
uni.setStorage({
key: key,
data: JSON.stringify(value)
});
}
}
//获取存储在本地的数据
//key--键 isSync--是否是异步
function getDatFromStorage(key,isSync) {
if (isSync) {
let data = JSON.parse(uni.getStorageSync(key));
return data || false;
}else {
uni.getStorage({
key: key,
success: (res) => {
var value = JSON.parse(res.data);
return value;
},
fail: (err) => {
return false;
}
});
}
}
判断系统类型
判断app还是其他小程序等
可以看这个文档条件编译
判断是ios还是android
var u = navigator.userAgent, app = navigator.appVersion;
var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1; //g
var isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
if (isAndroid) {
//这个是安卓操作系统
}
if (isIOS) {
//这个是ios操作系统
}
还要其它的可以看原帖
消息推送
可以看这条帖子uniapp消息推送超详细
获取cid
//获取cid
//#ifdef APP-PLUS
const clientInfo = plus.push.getClientInfo()
console.log(clientInfo);
let cid = clientInfo.clientid;
//#endif
提取输入框里数字
需要将输入框里的字符串提取出数字
//从字符转中提取数组 用于输入框中提取数量
function extractNumberFromString(string) {
let number = string.replace(/[^0-9]/ig,"").replace(/\b(0+)/gi,"");
return number;
}
【升级版】可获取小数,但目前仍有部分提取不出,有问题的直接置0了
//从字符转中提取数组 用于输入框中提取数量
function extractNumberFromString(string) {
let number = string.replace(/[^\d.]/ig,"").replace(/(\d)(\.)(\d*)(\2*)(\d*)/g,"$1$2$3$5")
// .replace(/\b(0)\d/ig,"");
number = Number(number) || 0;
return number;
}
安全区域
运行到手机上后,顶部会和手机系统顶部重合
好像在manifest.json里可以设置安全区域 manifest.json说明文档
试了 但是不管用,之后再研究
目前是使用uni.getSystemInfoSync()
获取系统bar高度,在自定义的topbar里添加一个高度相同的view
<view class="cu-custom" :style="heightStyle"> <!--整个topbar高度-->
<view class="uni_topbar">
<view :style="style"></view> <!--安全区域高度-->
computed: {
style() {
const systemInfo = uni.getSystemInfoSync();
let customBarH = systemInfo.statusBarHeight;
let _style = `height: ${customBarH}px; background-color: #D93A55`;
return _style
},
heightStyle() {
const systemInfo = uni.getSystemInfoSync();
let customBarH = systemInfo.statusBarHeight;
let _style = `height: ${customBarH + 45}px;`;
return _style
}
},
APP权限配置
App升级、热更新
App端组件
管理后台组件
有个大佬整理的视频 感激不尽!!!!
使用原生api
如果需要使用原生api可以用Native.js
官方文档
一些常用的示例汇总
获取APP包名
//获取包名
//#ifdef APP-PLUS
let pName = ""; //包名
if (plus.os.name=="Android") {
pName = plus.android.runtimeMainActivity().getPackageName();
} else {
var NSBundle = plus.ios.importClass('NSBundle');
var bundle = NSBundle.mainBundle();
pName = bundle.bundleIdentifier();
plus.ios.deleteObject(bundle);
}
//#endif
常用样式
这些样式一般都放在App.vue中,所有页面都可以使用
.rowPart{
display: flex;
flex-direction: row;
}
.colPart{
display: flex;
flex-direction: column;
}
.itemCenterPart{
display: flex;
align-items: center;
}
.spaceBetweenPart{
display: flex;
-webkit-justify-content: space-between;
justify-content: space-between;
}
.borderBottomPart{
border-bottom: 1upx solid #EDEDED;
}
.borderTopPart{
border-top: 1upx solid #EDEDED;
}
.rowRightPart{
display: flex;
-webkit-justify-content: flex-end;
justify-content: flex-end;
}
.rowCenterPart{
display: flex;
-webkit-justify-content: center;
justify-content: center;
}
.colBottomPart{
display: flex;
-webkit-align-items: flex-end;
align-items: flex-end;
}
.colCenterPart{
display: flex;
-webkit-align-items: flex-start;
align-items: flex-start;
}
.colTopPart{
display: flex;
-webkit-align-items: center;
align-items: center;
}
.fillSurplusWidthPart{
flex-grow: 1;
}
文字超出隐藏
/* 超出部分用省略号 */
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
/*超过两行省略*/
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
文字自动换行
word-break:break-all;
Q&A
毫秒倒计时,使用setInterval,但实际倒计时时间要慢?
js是单线程的,setInterval回调里执行的代码会阻碍计时,导致计时变慢。
可以记录上个计时时间点的时间戳,在计时回调中用当前时间戳减上个时间戳的差来判断过去了多少毫秒。
this.timer = setInterval(() => {
let curTime = (new Date()).getTime(); //当前时间戳
this.milliseconds -= curTime - this.lastTime; //更新倒计时时间
if (this.milliseconds < 0) {
this.timeUp();
return;
}
this.lastTime = curTime;
this.countDown();
}, 10) //每10毫秒执行一次函数
使用uni.showToast不显示
- 首先确认能执行到该语句
- 是不是被hideToast隐藏了
- 还不行?那应该是被遮挡了
uni.request的data里参数没有传到后端
如果method:“POST”,就需要添加header让data转换为string
data: {
region:1,
mobile:this.mobile,
user_pwd:this.password,
sms_verify:this.otp,
},
header:{
'content-type':"application/x-www-form-urlencoded",
},
method:"POST",
自定义组件里需要在组件里控制关闭组件
父组件里引用自定义组件vertify-code,show是控制开关的变量。
但vertify-code里判断要关闭的时候,不能改变show来关闭,不允许改变组件参数
<vertify-code @sendSuccess='sendSuccess' @closeCodePanel='closeCodePanel' :show="showVerifyCodePanel" :region="region" :unique="1" :moblie="mobile">
</vertify-code>
在组件里设置一个数据open,含义和show相同,并监听show值变化,当show值变化时同时改变open,使用open控制组件显隐
data() {
return {
open:false,
};
},
watch: {
//监听show变量变化
show: function(val) {
setTimeout(() => {
this.open = val;
}, 100)
},
},
props: {
show: { type:Boolean,default:false}, //是否显示
unique: { type: [Number, String], default: 0 },
region: { type: String, default: "" }, //0--登录 1--注册、绑定手机 2--重置密码
moblie: { type: [Number, String], default: 0 },
},
点击事件穿透
红框和绿框为两个点击区域,当点击绿框按钮时,会执行两个区域的点击事件
注册事件时,添加事件修饰符
@tap.stop="onTapAddToCart(item)"
可以防止事件穿透
html中解决点击穿透
function onTapService(event) {
event.stopPropagation(); //阻止点击穿透
//点击事件。。
}
滑动事件穿透
如下图,在两个区域里滑动,蒙层底部仍会滑动
在相应组件上添加
@touchmove.stop.prevent="moveStopFunc()
方法:moveStopFunc() { return; },
自定义组件不会根据全局变量刷新
自定义组件里引用了全局变量,当全局变量改变时组件不会实时刷新
引用位置设为父组件传来的参数,由父组件将全局变量作为参数传过来,就可以实时刷新了
后端时间和前端时间差很多?
有个倒计时的功能,需要结束时间和当前时间,从接口获取了结束时间,没有当前时间,那就从拿系统时间吧。但是发现系统时间和后端当前时间差太多了,差好几个小时了
可能是需要转为东八区时间,就是后端时间+8小时
要不就让后端再传一个当前时间,直接用后端的时间来算
手机调试检测不到手机
- 检查是否开启了USB调试, 或者重启一下(百度就有教程)
- 连接类型为“传输照片” (我的手机是只有选择“传输照片”时才能检测到)
- 换个插口试试,最好把数据线插在主机后面的插口
- 换跟数据线试试
- 实在不行,重启uniapp,重启电脑,重启大法
重启电脑后不要开其他软件,只打开uniapp
想在Windows上连接ios咋办
下载一个爱思助手