uni-app使用websocket(封装、心跳检测)_howcoder的博客-CSDN博客_uniapp websocket

mikel阅读(522)

来源: uni-app使用websocket(封装、心跳检测)_howcoder的博客-CSDN博客_uniapp websocket

前言:
最近想在uni-app的小程序中使用websocket进行双通讯的,而uni-app的插件市场中对websocket也做了很好的封装,例如:socket.io,但由于后端使用java的websocket,导致我在socket的url总是对应不上那边,所以无奈只能改成原生websocket,而uni-app中websocket很多文章都有介绍,然而直接使用时总是有或多或少的问题,所以对其进行了封装和修改,并且在项目中能正常使用,下面就直接上代码

封装websocket
class websocketUtil {
constructor(url, time) {
this.is_open_socket = false //避免重复连接
this.url = url //地址
this.data = null
//心跳检测
this.timeout= time //多少秒执行检测
this.heartbeatInterval= null //检测服务器端是否还活着
this.reconnectTimeOut= null //重连之后多久再次重连

try {
return this.connectSocketInit()
} catch (e) {
console.log(‘catch’);
this.is_open_socket = false
this.reconnect();
}
}

// 进入这个页面的时候创建websocket连接【整个页面随时使用】
connectSocketInit() {
this.socketTask = uni.connectSocket({
url: this.url,
success:()=>{
console.log(“正准备建立websocket中…”);
// 返回实例
return this.socketTask
},
});
this.socketTask.onOpen((res) => {
console.log(“WebSocket连接正常!”);
clearTimeout(this.reconnectTimeOut)
clearTimeout(this.heartbeatInterval)
this.is_open_socket = true;
this.start();
// 注:只有连接正常打开中 ,才能正常收到消息
this.socketTask.onMessage((res) => {
console.log(res.data)
});
})
// 监听连接失败,这里代码我注释掉的原因是因为如果服务器关闭后,和下面的onclose方法一起发起重连操作,这样会导致重复连接
// uni.onSocketError((res) => {
// console.log(‘WebSocket连接打开失败,请检查!’);
// this.is_open_socket = false;
// this.reconnect();
// });
// 这里仅是事件监听【如果socket关闭了会执行】
this.socketTask.onClose(() => {
console.log(“已经被关闭了”)
this.is_open_socket = false;
this.reconnect();
})
}

//发送消息
send(value){
// 注:只有连接正常打开中 ,才能正常成功发送消息
this.socketTask.send({
data: value,
async success() {
console.log(“消息发送成功”);
},
});
}
//开启心跳检测
start(){
this.heartbeatInterval = setTimeout(()=>{
this.data={value:”传输内容”,method:”方法名称”}
console.log(this.data)
this.send(JSON.stringify(this.data));
},this.timeout)
}
//重新连接
reconnect(){
//停止发送心跳
clearInterval(this.heartbeatInterval)
//如果不是人为关闭的话,进行重连
if(!this.is_open_socket){
this.reconnectTimeOut = setTimeout(()=>{
this.connectSocketInit();
},3000)
}
}
}

module.exports = websocketUtil
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
调用方式
1.单页面调用
引入
import wsRequest from ‘./static/js/websocket.js’
1
使用
new wsRequest(“ws://xxx:3100/connect/websocket”,5000)
1
2.全局调用
在main.vue页面中
//引入websocket文件
import wsRequest from ‘./static/js/websocket.js’
//开启websocket
let websocket = new wsRequest(“ws://xxx:3100/connect/websocket”,5000)
//挂载到全局
Vue.prototype.$socket = websocket
1
2
3
4
5
6
页面中调用
let data={value:”传输内容”,method:”方法名称”}
this.$socket.send(JSON.stringify(data));
1
2
注意事项
//在测试环境时url可以写成 ws://xxx:3100/connect/websocket
new wsRequest(“ws://xxx:3100/connect/websocket”,5000)

//发布体验版或正式版,url一定要写成 wss://xxx:3100/connect/websocket
new wsRequest(“wss://xxx:3100/connect/websocket”,5000)
1
2
3
4
5
除此之外,还需要在微信管理平台中对小程序的开发–>开发管理–>开发设置–>服务器域名 加入以下配置

 

————————————————
版权声明:本文为CSDN博主「howcoder」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42000816/article/details/113307548

 报错from ./node_modules/@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib/loaders/templateLoader.js_科技小栈的博客-CSDN博客_templateloader.js

mikel阅读(252)

来源: (1条消息) 报错from ./node_modules/@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib/loaders/templateLoader.js_科技小栈的博客-CSDN博客_templateloader.js

今天在做uni-app的时候,遇到一个坑,自己说实话也太水了,

编译的时候一直出问题:

一直报错:

出现这个问题的原因是:

因为你在编写页面的时候,没有闭合view:

正确的写法:

最后就可以成功了的编译出来了:

关注我的公众号:

uniapp与webview之间的相互传值 - 奔跑吧前端(李钊) - 博客园

mikel阅读(860)

来源: uniapp与webview之间的相互传值 – 奔跑吧前端(李钊) – 博客园

1.uni-app 如何发送数据到 H5? 其实很接单、在 web-view 中只需要通过 URL 就可以向 H5 进行传参 例如在 uni-app 中:

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
<template>
    <view class="advertisement" style="width: 100%;">
        <web-view :src="url" @message="message"></web-view>
    </view>
</template>
<script>
export default {
    data() {
        return {
            url:'/hybrid/html/local.html?data='
        };
    },
    onLoad(data) {<br>          //这里对要传入到webview中的参数进行encodeURIComponent编码否则中文乱码
        this.url+=encodeURIComponent(data.data)
    },
    mounted() {},
    methods: {
        message(event){
            console.log(event.detail.data);
        }
    }
};
</script>
<style scoped="scoped" lang="scss">
@import './advertisement.scss';
</style>

那么在 H5 中是如何接收值得呢?

复制代码
console.log(getQuery('data'));  //获取 uni-app 传来的值
            
            
            //取url中的参数值
            function getQuery(name) {
                // 正则:[找寻'&' + 'url参数名字' = '值' + '&']('&'可以不存在)
                let reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
                let r = window.location.search.substr(1).match(reg);
                console.log(r);
                if(r != null) {
                    // 对参数值进行解码
                    return decodeURIComponent(r[2]);
                }
                return null;
            }
复制代码

2.webview向uniapp传值

复制代码
<script>
    document.addEventListener('UniAppJSBridgeReady', function() {
        //向uniapp传值
        uni.postMessage({
            data: {
                action: 'message'
            }
        });
        uni.getEnv(function(res) {
            console.log('当前环境:' + JSON.stringify(res));
        });
    });
</script>
复制代码

uniapp接受

复制代码
//message接受方法

<template>
    <view class="advertisement" style="width: 100%;">
        <web-view :src="url" @message="message"></web-view>
    </view>
</template>
复制代码

如果你遇到h5传值给app,无法接收到消息,请转移到我的另一篇博客,看看是否是这个问题https://www.cnblogs.com/lizhao123/p/16170173.html

uni-app之条件判断详解【uni-app小程序开发】(二)_uniapp if_上进小菜猪的博客-CSDN博客

mikel阅读(340)

来源: uni-app之条件判断详解【uni-app小程序开发】(二)_uniapp if_上进小菜猪的博客-CSDN博客

文章目录
一.前文回顾
二.干货学习
2.1 条件判断:v-if
2.2 条件判断:v-show
2.3 空标签
三,本文总结/下文预告
3.1 本文总结
3.2 下文预告
一.前文回顾
本专栏的上一篇文章写了使用uni-app开发非原生小程序的:
1.v-bind:数据变量
2.v-on:绑定事件
3.v-model:双向绑定
以及export default初始化对象等等。
我们本文研究,条件判断。

二.干货学习
2.1 条件判断:v-if
v-if:决定某个内容或区块是否挂载。
我们尝试使用一个简单的if判断条件看一下。

<view v-if=”false”>{{mxa}}</view>
1
我们在data数据集里写下msg的值:

data() {
return {
mxa: ‘我显示了’
}
},

因为我们的if条件为true为真,所以下面的“我显示了”这句话会正常显示输出!
效果如下:

如果改为:

<view v-if=”false”>{{mxa}}</view>

if判断的条件为假,则“我显示了”这句话不会正常显示输出。

拓展:
我们还可以把布尔类型写到数据集里,这样更加友好。
做法非常简单,如下;

return {
msg: ‘Hello’,
arr: [1, 2, 3],
flag: true,
mxa: ‘我显示了’,
}

<view v-if=”flag”>{{mxa}}</view>

这样v-if里的flag会自动调用data数据集里的布尔值,执行条件判断语句。
后续我们可以写一些变式,计时器等等,来控制它的使用。

当然我们还可以使用else:

<view v-if=”flag”>{{mxa}}</view>
<view v-else>其他情况</view>

这块应该很好理解吧。截图看一下:

我们可以进阶的思考一下:
点击按钮交替显示内容:

methods: {
show() {
console.log(‘你好上进小菜猪’);
this.flag= !this.flag;
}
}
2.2 条件判断:v-show
v-show:是否显示。
这里要注意v-show和v-if的区别。

2.3 空标签
uni-app框架的语法是靠近与小程序的语法的,所以空标签可以用:

<block></block>
1
或者使用uni-app的空标签:

<template></template>
1
俩个效果一样,贴近于微信小程序,但是还是推荐使用

<block></block>
1
三,本文总结/下文预告
3.1 本文总结
本文讲解了条件判断的v-if和v-show的用法和区别
1.条件判断:v-if决定某个内容或区块是否挂载。
2.条件判断:v-show:是否显示。

还有空标签的俩种用法:
1,这个是贴近于微信小程序的写法。

<block></block>
1
2.这个是的uni-app框架的写法。

<block></block>
1
俩者效果一样。

3.2 下文预告
下篇文章记录uni-app框架的列表渲染等用法与心得。

————————————————
版权声明:本文为CSDN博主「上进小菜猪」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_52908342/article/details/125153853

php怎样将浮点数转为整数-PHP问题-PHP中文网

mikel阅读(262)

来源: php怎样将浮点数转为整数-PHP问题-PHP中文网

php将浮点数转为整数的方法:

php中的内置函数intval()用于获取变量的整数值。成功时返回var的integer值,失败时返回0。空的array返回0,非空的array返回1。

intval()函数通过使用指定的进制 base 转换(默认是十进制),返回变量 var 的 integer 数值。 intval() 不能用于 object,否则会产生 E_NOTICE 错误并返回 1。

语法:

1

int intval ( mixed $var [, int $base = 10 ] )

参数说明:

  • $var:要转换成 integer 的数量值。
  • $base:转化所使用的进制。

如果 base 是 0,通过检测 var 的格式来决定使用的进制:如果字符串包括了 “0x” (或 “0X”) 的前缀,使用 16 进制 (hex);否则,如果字符串以 “0” 开始,使用 8 进制(octal);否则,将使用 10 进制 (decimal)。

(相关推荐:php培训

代码示例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

<?php

echo intval(42);

// 42

echo intval(4.2);

// 4

echo intval('42');

// 42

echo intval('+42');

// 42

echo intval('-42');

// -42

echo intval(042);

// 34

echo intval('042');

// 42

?>

以上就是php怎样将浮点数转为整数的详细内容,更多请关注php中文网其它相关文章!

😭血泪合集!uniapp小程序开发的超长实践总结! - 掘金

mikel阅读(345)

来源: 😭血泪合集!uniapp小程序开发的超长实践总结! – 掘金

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

前言

在经历了多个uniapp小程序项目开发后,我将我所有的踩坑实战经验复盘总结,以下内容仅针对uniapp开发微信小程序的场景,其中除了uniapp外还有一些小程序开发的注意点,希望这篇文章可以帮助大家避坑。以下全文干货(干到口渴那种)

如果你期待或者需要一个开源的微信小程序社区,可以 oil社区 gitee链接 关注我的开发进度噢,欢迎⭐star

uniapp简介

先放官方介绍,如果熟悉已经了解uniapp的同学可以跳过。

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

使用uniapp的话我们可以使用 vue.js 的语法来写 小程序 ,简而言之就是将常规vue.js开发中 template 模板从 html 替换成 wxml 就可以开发小程序,那么这么做有什么好处呢!

  1. 减少技术学习压力,如果你会vue的话你可以直接上手,如果你不会vue的话顺便把vue学了,而且还可以享受到vue的周边生态福利
  2. 语法相交于原生的小程序语法更加方便,如果你开发过小程序那你一定会感受到 this.setData()原生小程序组件 开发的麻烦与恐惧
  3. uniapp除了可以打包成各个平台的小程序还可以打包成app,具体不列举,如官网下图。 image.png
  4. 程序开发工具的代码提示比较拉跨,虽然相比前几年有很大进步,但是还是没有达到我想要的水平。

uniapp开发准备

ide工具安装

HBuilder官网链接

工欲善其事,必先利其器。开发uniapp的第一步是安装一个官方的ide工具 HbuilderX ,对于开发uni-app来说我只推荐这一个ide工具,确实非常方便,可以帮助我们快速生成页面模板和组件模板可视化的页面配置优秀的代码提示代码补全能力 等等。

HbuilderX 相比 vscode 还是有一些不足之处,一些插件生态不是很健全。但是开发uni-app就是非 HbuilderX 莫属了(毕竟是官方的东西)

HbuilderX 的安装非常方便,直接在官网下载安装就OK了。下载完成后我们需要安装一些插件,打开HbuilderX ,在顶部栏选择工具->插件安装,如下图

image.png

打开后我们可以看到当前已安装的插件一些官方插件,这里由于年代久远我不记得最初的时候哪几个没安装了,但是下面红框圈起来的是一定要安装的,一个是用于git版本管理的插件,一个是用于编译sass的插件。

image.png

我们还可以设置我们的编辑器主题和字符大小,代码缩进等,如果你是有其他编辑器使用习惯的可以适当调整。我原本是使用vscode进行开发的,所以我切换成了 雅蓝 的主题,实际页面效果和vscode one dark pro编辑器风格代码颜色 一模一样!

image.png

以上步骤我认为都是必要的,舒服美观的开发环境可以极大的提升你的开发兴趣!

项目目录结构分析

新建项目

HbuilderX 安装配置完毕后,我们就可以开始开发了,首先我们需要创建一个项目,我们点击ide左上角 文件-> 新建 ->项目 ,然后我们选择 uniapp 项目 ,模板选择 默认模板

image.png

创建完成后,我们可以看到左侧文件树中新增了一个以项目名命名的文件,其中是hbuilder为我们内置的项目模板

image.png

以下是uniapp给我们的项目框架介绍,有一些文件夹是没有在模板中内置的,因此我们需要自己手动创建以下,例如最外层的components,用来放置我们的一些全局通用组件

    

┌─components            符合vue组件规范的uni-app组件目录
│  └─comp-a.vue         可复用的a组件
├─pages                 业务页面文件存放的目录
│  ├─index
│  │  └─index.vue       index页面
│  └─list
│     └─list.vue        list页面
├─static                存放应用引用的本地静态资源(如图片、视频等)的目录,注意: 静态资源只能存放于此
├─uni_modules           存放[uni_module](/uni_modules)规范的插件。
├─wxcomponents          存放小程序组件的目录,详见
├─main.js               Vue初始化入口文件
├─App.vue               应用配置,用来配置App全局样式以及监听 应用生命周期
├─manifest.json         配置应用名称、appid、logo、版本等打包信息,详见
└─pages.json            配置页面路由、导航条、选项卡等页面类信息,详见
    
复制代码

如下图,在开发的过程中,我依据vue项目的开发习惯,在pages中依照业务功能来创建功能分类文件夹,最常见的是按照首页的tabbar来区分功能模块,每一个文件夹中存放该功能涉及的所有页面,且每一个功能文件夹中还有一个单独的components文件夹用于放置该仅功能文件夹中的页面依赖的组件。

image.png

新建页面

我们需要创建新页面的时候可以通过hbuilder内置的页面模板来快速创建,右键点击左侧文件树中当前的项目,选择 新建页面 ,输入页面名称以及选择模板就可以创建了,一般我选择的是scss的模板,创建完成后会自动帮你在page.json中注册该页面。

image.png

通用插件封装

既然uniapp选择使用vue.js作为开发框架,那么我们一定要利用上vue中的一些优秀特性,例如插件(plugin),关于vue插件的介绍大家可以直接去官网看。

vue 插件官方介绍链接

通过引入插件,我们可以极大的提升我们的开发效率,当然如果是第一次使用uniapp进行开发可能不清楚哪个功能适合封装成插件引入,下面我就介绍一下一些我在实际开发中封装的一些通用插件

在封装前我们需要写一个 config 文件,方便我们快速自定义一些颜色和请求路径等。

//congif.js
const config = {
	baseUrl:'https://example.cn',//请求的基本路径
	modalColor:'#5271FF', //弹窗颜色 
}

module.exports = config
复制代码

弹窗插件

在小程序中,如果我们没有自定义弹窗和拟态框组件的话一般都是使用官方的showModal或者showToast api来进行一些用户交互。这种非常频繁使用到的操作非常适合封装起来快速调用。具体代码如下

插件代码

const config = require('../config.js')

var message = {
	toast(title, type = 'text') {
		if (title.length > 15) {
			console.error('toast长度超过15个字符,当前长度为' + title.length)
			return
		}
		var icon = 'none'
		if (type) {
			switch (type) {
				case 'text':
					icon = 'none'
					break
				case 'suc':
					icon = 'success'
					break
				case 'err':
					icon = 'error'
					break
			}
		}
		uni.showToast({
			title,
			icon
		})
	},
	confirm(title, confirmColor) {
		return new Promise((res, rej) => {
			uni.showModal({
				title,
				cancelColor: '#b6b6b6',
				confirmColor: confirmColor || config.modalColor,
				success: (result) => {
					if (result.cancel) {
						rej(result)
					} else if (result.confirm) {
						res(result)
					}
				}

			})
		})
	},
	async message(content, confrimText) {
		return new Promise((res) => {
			uni.showModal({
				title: '提示',
				content,
				showCancel: false,
				confirmColor: config.modalColor,
				success: (result) => {
					res(result)
				}
			})
		})
	}
}
module.exports = message

复制代码

示例调用

this.message.toast('回答已删除')
复制代码

请求插件

在vue中我们常用的请求库是axios,几乎每一个开发者都会将axios进行一个二次封装,以减少调用时的代码量以及进行一些全局配置。在uni-app中我们无须引入第三方的请求库,直接使用官方提供的 uni.request(OBJECT) 这个api来进行请求的调用,当然我们也是要做一个二次封装的。具体代码如下

插件代码

//http.js
const config = require('../config.js')
const message = require('./message.js')
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

复制代码

示例调用

async getAnswer() {
  const res = await this.http.get('/applet/answerList', {
    qId: this.question.id,
  })
  if (res.code === 200) {
    return res.data
  } else {
    this.message.toast('请求失败')
    return false
  }
}
复制代码

在上面的代码中我们可以看到,我们引入两个依赖文件分别是configmessage 这个在下面会说的,在http对象中有五个方法,分别是post,get,update,delete对应着 restful api 的增删查改操作,还有一个upload 方法用来上传文件。在小程序中请求我们不需要考虑跨域的问题,我们的默认请求路径是从 config这个依赖文件中获取的。而这时候我们还可以利用第一个 弹窗插件 快速的进行消息提示。

存储插件

在使用vue的时候我们常常会使用vuex + vuex-persistedstate来使我们的数据可以全局使用以及持久化,在小程序中我们有两种全局数据的存储方式 一种是globalData,通过在App.vue中添加globalData这个值来进行数据全局化,例如我们可以用来保存我们的小程序版本。

export default {
  globalData: {
    version: '1.0.0'
  }
}
复制代码

但是globalData的数据不是持久化的,当我们退出小程序再进入的时候就重新初始化了,所以我们还有一种全局数据存储方式是storage,类比我们web端的localstroge,使用方式也几乎一样。通过官方提供的api实现本地存储的效果

image.png

在小程序中往往没有web端那么复杂的数据结构,虽然uniapp小程序也可以使用vuex作为一个全局数据管理的库,但我自己还是做了一个简化版的方便自己使用。这个插件是在很久以前写的了,只是非常简单的实现,如果想要省略setData操作可以用 proxy 劫持存储的值去存在本地。

插件代码

var store = {
	_init(){
		if(uni.getStorageSync('store')==''){
			uni.setStorageSync('store',{})
			return
		}
		const data = uni.getStorageSync('store')
		for(let i in data){
			if(!this[i]){
				this[i] = data[i]
			}
		}
	},
	setData(key,value){
		if(key == '_init'||key=='setData'){
			console.error('store:非法key值',key)
			return
		}
		this[key] = value
		uni.setStorageSync('store',this)
		console.log(uni.getStorageSync('store'))
	}
}

module.exports = store

复制代码

示例使用

this.store.setData('user',{name:'oil'}) // 赋值
console.log(this.store.user) // 读值
复制代码

表单验证插件

表单验证是使用的是一个很轻量开源的表单验证库JSValidate,可以直接点击链接在仓库看源码,下面就不放代码了,讲一下如何使用。 JSValidate gitee链接

示例调用

// validate.js
const validate = {
	userForm:{
		intro:	'@个人简介|require',
		college: '@学校|require!请选择你的学校',
		nickname:'@昵称|require'
	}
}

module.exports = validate

复制代码

在表单中写入一个表单验证方法,如果条件不符合的话就使用弹窗进行提示

//form.js
validateForm() {
  // 表单验证方法
  const validate = require("./validate")
  const validator = new this.validator()
  var result = validator.check(validate.userForm, this.form, false)
  if (result !== true) {
    this.message.message(result)
    return false
  }
  return true
}

复制代码

时间处理插件

关于时间处理插件我在项目中使用的也是一个开源的轻量级js库 day.js,具体的使用方式参考官方文档,day.js几乎包含了所有时间处理相关的操作,例如时间对比,时间转换等。 day.js官方文档链接

day.js其中有一项功能特别常用,就是一个相对时间转换的功能,相对时间转换就是将一个时间字符串例如年月日时分秒转换成几秒前,十分钟前,几个月前等等。使用的方式如下代码,我们使用vue的computed来进行时间字符串的处理,通过 闭包computed方法内传入时间字符串参数,然后通过day.js的formNow方法返回一个中文的相对时间。date就是我封装后引入的插件了。

示例代码

computed: {
  relativeDate() {
    return (date) => {
      return this.date(date).fromNow()
    }
  }
}
复制代码

当我们拥有了很多个插件之后(如下图),我们的插件之间可能会共享一些配置,例如上文中的config.js,接下来我们可以写一个入口文件index.js用来将我们写的插件引入,然后在main.js中安装我们的插件。

image.png

示例代码

// index.js
const http = require('./lib/http')
const message = require('./lib/message')
const router = require('./lib/router')
const validator = require('./lib/validator')
const date = require('./lib/date')
const store = require('./lib/store')
const to = require('./lib/to')
const oil = {
  message,
  http,
  router,
  validator,
  date,
  store,
  to,
  install(Vue) {
    this.store._init()
    for (let i in this) {
      if (i == 'install') {
        continue
      }
      Vue.prototype[i] = this[i]
    }

    delete this.install
  }
}

export default oil
复制代码
// main.js
import Vue from 'vue'
import oilUni from './oil-uni/index.js'
Vue.use(oilUni)
app.$mount()
复制代码

我们在入门文件中定义了一个对象叫做oiloil上除了我们写好的方法还有一个特殊的方法就是installinstall 的作用就是在我们使用Vue.use()的时候会将Vue的构造器传入install方法作为第一个参数,然后我们将所有方法都绑定在Vue的原型链上。

安装后,我们只需要在页面或组件的js中使用 this. + xx插件 就可以访问到封装的插件了。

常用组件封装

插件的作用是将我们的代码进行一个模块化,以便捷的复用一些常用的操作。而组件化则是帮助我们进行一个ui上的封装和复用。由于小程序的场景一般都不是很复杂,所以非常通用的组件也不多,下面只说说我在业务中常用的一些组件库和自己封装的组件

第三方组件库引入

colorUI

首先推荐的就是我几乎在所有小程序项目上都有用的 colorUI,与其说 colorUI 是一个组件库,不如说它是一个样式库。 colorUI github链接

在colorUI中封装了大量的行内样式,我们不需要频繁的在templatestyle间切换,大大的减少了我们的心智负担。可以类比 tailwindcss 这个样式库,但是在HBuilderX中,有着非常健全的colorUI样式的代码提示。其实不止是colorUI。你自己写的样式或者引用的文件在HBuilderX中都会获得很完整的一个代码提示。如下图

image.png

colorUI中并没有为我们提供功能上封装好的组件,但是在它的示例源码中,大部分场景都可以直接将样式和代码复制出来改造一下直接使用,例如图片上传表单组件等。 colorUI示例页面

colorUI的引入也非常简单,将colorUI的包放在项目根目录下,然后在App.vuestyle中引用就OK了,colorUI包含了三个文件,一个是main.css,里面是colorUI所有的样式代码,icon 是colorUI的图标,animation 是colorUI的动画,三个包的功能都是通过在 行内class 中写入指定代码来使用。

image.png

//App.vue
<style>
	@import "colorui/main.css";
	@import "colorui/icon.css";
	@import "colorui/animation.css";
</style>
复制代码

vant-weapp

vant几乎是vue生态在移动端个人认为最好用的组件库了,几乎所有场景的组件都有涵盖到,而vant有一个小程序专用的 weapp 版本。 vant weapp 官方文档

vant weapp 是用原生小程序的语法写的,和uniapp中的vue语法有些出入,所以引入的时候需要做一些特殊操作,下面说一下 vant weapp 如何引入。

  1. 首先需要下载vant weapp,将vant文件夹放在项目根目录下的wxcomponent文件夹里,没有就新建一个。 image.png
  2. App.vue中引入一下样式文件,
<style>
	@import "/wxcomponents/vant/common/index.wxss";
</style>
复制代码
  1. 接下来我们就可以在页面中引入了,引入并不能直接在页面或组件中import,而是得按照小程序的使用方式在pages.json中引入,如下代码,在指定页面的 usingComponents 配置项中添加 组件名:组件路径 ,然后就可以直接在页面中使用了
{
  "pages": [ 
    {
      "path": "pages/home/home",
      "style": {
        "navigationBarTitleText": "",
        "enablePullDownRefresh": false,
        "usingComponents": {
          "van-progress": "/wxcomponents/vant/progress/index"
        }
      }
    }
  ]
}
复制代码

要注意vant weapp官方文档中的语法是小程序的,自己转换成vue的就OK了

滚动容器组件

在引入以上两个组件库后,咱们开发时的大部分场景都可以在其中找到对应组件,顶多是进行一个二次封装以适配业务。

常见业务场景

登录页面

在小程序中,登录往往不像web端需要输入账号密码或者手机验证码登录,而是使用各个平台的快速鉴权功能,例如微信小程序就是可以通过向微信官方的api发送请求来获取用户信息。

获取用户信息

因此我们在设计页面的时候往往只需要非常简单的一个按钮来获取用户信息,下面我将用一个项目中的登录功能来给大家展示uniapp实现微信小程序登录获取用户信息的方法

<template>
	<button class="cu-btn bg-blue shadow-blur round lg" @click="login">
            立即登录
	</button>
</template>
<script>
export default {
    methods: {
	async login() {
            uni.showLoading({
		mask: true,
		title: '登录中'
		})
            const res = await uni.getUserProfile({
		desc: '用于存储用户数据'
		})
	uni.hideLoading()
	if (res[0]) {
		this.message.toast('获取失败', 'text')
		return
	}
        this.getUser(res[1].userInfo)
        },
        async getUser(userInfo) {
            uni.showLoading({
                    mask: true,
                    title: '登录中'
            })
            const loginRes = await uni.login()
            if (loginRes[0]) {
                    uni.hideLoading()
                    this.message.toast('获取失败')
                    return
            }
            const res = await this.http.post('/applet/weChatLogin', {
                    code: loginRes[1].code
            }, 'form')
            uni.hideLoading()
            if (!res.data) {
                    this.router.push('/pages/form/userForm', {
                            userInfo,
                            handle: 'add'
                    })
                    return
            }
            this.store.setData('user', res.data)
    },}
        
复制代码

我们来分析一下上面的代码,首先我们使用 uni.getUserProfile api来获取用户的基本信息,例如头像,昵称,地区等。接下来我们调用 uni.login 获取code值。 code值是用来传递给后端获取微信给用户的 唯一标识 openid 的。

我将code码传递给后端,后端解析出openid并在数据库中查看当前用户是否已有用户信息,没有的话则为第一次登录。第一次登录我们就跳转至表单页面 完善个人信息获取用户手机号码

后端的具体代码在这里不详细展开说,只说整体实现过程。

获取用户手机号码

获取用户号码有一个必要的条件就是点击open-typegetPhoneNumberbutton 标签触发,且需要使用 getphonenumber 绑定一个事件。点击这个按钮时,微信会弹出一个授权获取手机号码的框框,用户选择了同意的话就会触发我们的 getphonenumber 方法。

getphonenumber 方法的参数e.detail中有两个属性 encryptedData(加密数据)iv(初始化矢量) 这两个参数是用来传递给后端进行手机号码的解析的,后端的具体流程比较复杂,下次单出一篇文章讲。

还有一点非常非常重要的,如果你是一个社区型的应用,用户可能发表一些评论和文章,那么咱们保存的用户头像就必须一直有效,如果我们使用微信官方提供的默认头像链接直接存储在数据库,那么当用户换头像之后,原先的链接就会失效

所以我们需要做的是使用 uni.downloadFile api将用户的头像下载为本地文件,再将本地文件上传至服务器,用户头像就会一直有效了!

具体代码如下,已经将业务抽离了,只剩核心代码。

<button class="cu-btn bg-blue shadow-blur round lg" open-type="getPhoneNumber"
        @getphonenumber="getTel" @click="getCode">确定提交
</button>
复制代码
async uploadAvatar() {
        // 上传用户头像
         if (this.updateImg) {
                var uploadRes = await this.http.upload('/applet/file/uploadFile', [this.form.avatarUrl])
        }
        else if (this.userInfo) {
                var downloadRes = await uni.downloadFile({
                        url: this.userInfo.avatarUrl
                })
                if (downloadRes[0]) {
                        uni.hideLoading()
                        this.message.toast('登录失败')
                        return
                }
                var uploadRes = await this.http.upload('/applet/file/uploadFile', [downloadRes[1].tempFilePath])
        }
         else {
                return
        }
        this.form.avatarUrl = uploadRes[0]
},
async getTel(e) {
        // 首次登录,获取用户手机号码
        if (!e.detail.encryptedData || !e.detail.iv) {
                this.message.toast('登录失败')
                return
        }
        uni.showLoading({
                mask: true,
                title: '登录中'
        })
        await this.uploadAvatar()
        this.form.tags = this.tag.arr.map(item => item.name).join(',')
        const res = await this.http.post('/applet/authorization', {
                code: this.code,
                iv: e.detail.iv,
                encryptedData: e.detail.encryptedData,
                userInfo: this.form
        }, 'json')
        uni.hideLoading()
},
复制代码

列表页面

下面讲讲咱们非常非常常见的一个业务场景,那就是 列表页面,列表页面看似简单,实则暗藏玄机。例如下拉刷新,上滑加载,没有更多内容的提示,关键字搜索,标签栏匹配,空白页面,列表项组件的复用等等。在一开始就设计完整会对开发效率和整体的代码健壮性有很大帮助!

我将用我实际开发中的代码示例为大家演示一个列表的功能实现。还是一样,我抽离了业务代码只剩核心代码!

<!-- 页面代码 -->
<scroll-view
  :scroll-y="true"
  style="height: 100vh"
  :refresher-enabled="true"
  :refresher-triggered="list.flag"
  @refresherrefresh="refresh"
  @scrolltolower="getAnswer"
  :enable-back-to-top="true"
  :scroll-into-view="list.scrollId"
  :scroll-with-animation="true"
>
  <view style="position: relative" class="bg-white">
    <view v-for="(item,index) in list.data" :key="index" >
      <answer-item
        :data="item"
      ></answer-item>
    </view>
  </view>
  <view
    class="cu-load bg-gray text-main loading"
    style="height: 40px"
    v-if="!list.nomore"
  ></view>
</scroll-view>

复制代码
// js代码
export default {
components: {
        AnswerItem,
},
data() {
        return {
                list: {
                        data: [],
                        flag: false, //是否展示刷新
                        limit: 10,
                        total: 0,
                        nomore: false, //是否显示到底
                        empty: false, //是否显示为空,
                        error: false, //是否请求错误,
                }

        };
},
async onLoad(e) {
        this.getQuestion()
        await this.getAnswer()
        async getAnswer() {
				
},
methods: {
    async getAnswer() {
        const listHandle = require("../../utils/js/listHandle")
        const id = this.list.data.length ? this.list.data[this.list.data.length - 1].id : ''
        const res = await this.http.get('/applet/answerList', {
                qId: this.question.id,
                limit: this.list.limit,
                userId: this.store.user ? this.store.user.id : '',
                id
        })
        if (res.code === 200) {
                const list = listHandle.add(res.data, this.list.data, this.list.limit)
                Object.assign(this.list, list)
                return res.data
        } else {
                this.list.error = true
                this.message.toast('请求失败')
                return false
        }
},
async refresh() {
        // 刷新方法
        const listHandle = require("../../utils/js/listHandle")
        this.list.flag = true
        this.list.nomore = false
        this.list.empty = false
        this.list.error = false
        this.list.loadNum = 0
        const res = await this.http.get('/applet/answerList', {
                qId: this.question.id,
                limit: this.list.limit,
                userId: this.store.user ? this.store.user.id : '',
                id: ''
        })
        this.list.flag = false
        if (res.code === 200) {
                const list = listHandle.update(res.data, this.list.limit)
                Object.assign(this.list, list)
        } else {
                this.list.err = true
                this.message.toast('请求失败')
        }
},
}
}
复制代码
// listHandle.js 列表项处理的方法
const listHandle = {
  add(resData, listData, limit) {
    var ret = {
      nomore: false,
      empty: false,
      data: []
    }
    if (resData) {
      if (resData.length < limit) {
        // 获取数据条数小于页码数,显示已到底
        ret.nomore = true
      }
      ret.data = listData.concat(resData)
    } else {
      ret.data = listData
      ret.nomore = true
      if (!listData.length) {
        // 请求已无返回数据且当前列表无数据,显示为空
        ret.empty = true
      }
    }
    return ret
  },
  update(resData, limit) {
    var ret = {
      nomore: false,
      empty: false,
      data: []
    }
    if (resData) {
      if (resData.length < limit) {
        // 获取数据条数小于页码数,显示已到底
        ret.nomore = true
      }
      ret.data = resData
    } else {
      ret.nomore = true
      // 请求已无返回数据且,显示为空
      ret.empty = true
    }
    return ret
  }
}

module.exports = listHandle

复制代码

注意点

在手机端上滑加载的时候,如果你是按照时间的倒序来排序,传统web底部分页器那样传一个页码数和单页条数给后端查询的话。如果在你上滑的过程中有用户发布新的内容,那么你的列表中就会有 重复的项

举个例子:你最初取了十条数据,当你上滑到底部加载时传了一个 page=2limit=10给后端,意思是将所有数据十条作为一页,我要拿第二页的内容。但是这时候有用户添加了一条新的数据,你第一页的最后一条就被挤到第二页去了,此时你拿到的数据第一条会和上一次拿到的最后一条一模一样!

想要解决这个问题也很简单,我们在向后端传递数据的时候不要按页码数去传值。我们将当前数据的最后一条的id传给后端,让后端取 id比这个值更小的十条,此时不论有多少用户插入新的数据都不会对你的结果产生影响。当然要实现这种功能的前提是你的数据表id是递增的,如果不是你也可以用数据的创建时间的那个字段来传递。 对应这个功能的是下面这行代码。

const id = this.list.data.length ? this.list.data[this.list.data.length - 1].id : ''

跨页面方法调用

在uniapp小程序的开发中,我们可能会遇到一种场景,就是我需要在当前页面调用上一个页面的方法。 例如:我要实现一个搜索功能,当我点进搜索详情输入关键词后,我要返回列表页面并触发一次搜索方法,如下图

1.gif

我的实现方式如下

searchFunc(){
  let pages = getCurrentPages()
  let page = pages[pages.length - 2]
  page.$vm.searchText = this.search.text
  page.$vm.refresh()
  this.router.back()
}
复制代码

getCurrentPages() 是一个全局函数,用于获取当前页面栈的实例,以数组形式按栈的顺序给出。我们当前页面就是数组最后一项,那么上一个页面就是pages[pages.length - 2]。当然我们还要记得加上$vm属性,因为在uniapp中我们的数据和方法是挂载这个实例上的。我们可以通过这个示例访问到对应页面的所有数据和方法!

踩坑注意点

以下列出的问题不仅仅有uni-app的,更多的是小程序本身的一些问题

scoll-view scroll-into-view跨组件

在小程序的scroll-view标签上有一个scroll-into-view属性,这个属性值可以传入一个id,当我们更改这个值时我们就会滚动到指定id的容器位置。

但是如果我们的scroll-view被封装在组件中使用时,我们在slot

scroll-view无法下拉刷新

原因

应该是scroll-view元素的下拉位置在元素渲染时就确定了,而我们赋予scroll-view的高度更改了下拉位置,导致下拉的时候没法拉到位

解决方法

在scroll-view的高度变量确定后再渲染scroll-view元素,具体的做法如下代码

<scroll-view 
	scroll-y="true" 
	:style="'height:'+height" 
	v-if="height"  
	:refresher-enabled='true'
	:refresher-triggered='list.flag' 
	@refresherrefresh='refresh' 
	@scrolltolower='loadMore'>
</scroll-view>
复制代码

scroll-view sticky样式问题

问题描述

scroll-view 是小程序常常会用到的一个标签,在滚动窗口内我们可能会有一个顶部标签栏,如果我们不想通过计算高度去固定在顶部的话我们可以使用 position:sticky 加一个边界条件例如top:0 属性实现一个粘性布局,在容器滚动的时候,如果我们的顶部标签栏触碰到了顶部就不会再滚动了,而是固定在顶部。

但是在小程序中如果你在scroll-view元素中直接为子元素使用sticky属性,你给予sticky的元素在到达父元素的底部时会失效,如果你遇到过一定会非常印象深刻😭。

解决方法

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

ios固定输入框字体移动bug

问题描述

在一个固定于页面中间的滚动容器内放了一个表单,在安卓端测试功能完好,在IOS端有一个bug。当输入框在输入后没有点击其他位置使输入框失焦的话,如果滚动窗口内部的字体也会跟着滚动下面使解决方法

//原本的输入框
<input></input>
复制代码

解决方法

使用这个方法更改后,不仅布局的样式不会改变,而且字体随着固定的滚动窗口一起滚动的bug也会解决

// 更改后的输入框
<textarea fixed="true" auto-height="true" ></textarea>
复制代码

真机时间错误BUG

问题描述

在小程序中使用new Date().toLocaleDateString() api获取时间的时候,在开发工具中显示为当前时间,而在真机中显示为其他地区的时间

BUG产生原因

toLocaleDateString()方法依赖于底层操作系统在格式化日期上。 例如,在美国,月份出现在日期(06/22/2018)之前,而在印度,日期出现在月份(22/06/2018)之前。

解决方案

使用new Date()构造函数来获取年月日后拼接

如果没有输入任何参数,则Date的构造器会依据系统设置的当前时间来创建一个Date对象。

DatetoLocaleDateString()的区别在于一个是获取系统当前设置的时间,一个则是底层操作系统来格式化时间

//具体代码如下
let date = new Date()
date = date.getFullYear() + '/' + (date.getMonth() + 1) + '/' + date.getDate()
date = date.split('/')
if (date[1] < 10) {
		date[1] = '0' + date[1]
	}
if (date[2] < 10) {
	date[2] = '0' + date[2]
	}
date = date.join('-')
复制代码

自动全局引入组件

功能介绍

如果大家有用过vue2开发项目,就知道在vue2中可以通过webpack的api进行自动全局组件引入,不需要在页面中一个一个手动引入,如下代码

const requireComponent = require.context("@/components", true, /\.vue$/);
// 通过webpack获取conponents目录下所有组件
const global = {
  install(app) {
    const components = requireComponent.keys(); // 获得组件数组
    for (let component of components) {
      let componentName = component.replace(/(.*\/)*([^.]+).*/gi, "$2"); // 获得组件名称
      app.component(componentName, requireComponent(component).default); // 将组件挂载到全局
    }
  },
};
export default global;

复制代码

将global.js放在components的同级目录,然后在 main.js 中引入并使用 Vue.use 来使用插件就OK了,这个方法就可以帮我们自动将组件挂载到全局。

注意点

在uniapp中这个上面这个方法是不能使用的,我们在上面的代码中可以看到这一行 app.component(componentName, requireComponent(component).default);

在uniapp中 app.component 这个方法是不能传入变量作为组件名的,只能直接传入字符串,因此我们就没法使用它来自动引入组件啦。

总结

作者:oil欧哟
链接:https://juejin.cn/post/7020680215009427470
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

HbuilderX开发微信小程序流程_有趣的灵魂°的博客-CSDN博客

mikel阅读(464)

来源: HbuilderX开发微信小程序流程_有趣的灵魂°的博客-CSDN博客

首先保证创建的项目是uin-app项目,其他类型的项目没有尝试过,现有nin-app项目是安卓项目,现在可以利用HbuilderX一键生成小程序,非常的方便,不得不夸赞一下uin-app框架的强大,支持跨平台开发

首先,HbuilderX的工具—->设置—–>运行配置

 

配置微信开发者工具路径。

然后去微信开发者工具中打开端口以便Hbuilder,设置—->安全设置,打开端口然后将端口号复制到Hbuilder

 

然后在Hbuilder中运行或者发布,选择小程序开发者工具那一项,就可以在开发者工具中预览和查看了。在开发者工具中上传代码发布
————————————————
版权声明:本文为CSDN博主「有趣的灵魂°」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_39288821/article/details/108092788

HBuilderX搭建微信小程序;HBuilderX开发uni-app微信小程序;uni-app开发微信小程序;使用uni-app搭建微信小程序;使用uni-ui模板搭建微信小程序步骤_i_am_a_div_日积月累_的博客-CSDN博客

mikel阅读(624)

来源: HBuilderX搭建微信小程序;HBuilderX开发uni-app微信小程序;uni-app开发微信小程序;使用uni-app搭建微信小程序;使用uni-ui模板搭建微信小程序步骤_i_am_a_div_日积月累_的博客-CSDN博客

1.选择模板 uni-ui

2.得到创建项目

3.获取APPid

在微信小程序电脑后台获取APPID
这个方法适用于自己申请的微信小程序(自己用的小程序)
打开微信小程序官网:https://mp.weixin.qq.com/ 并登陆

 

4.项目打包 打包后运行在微信小程序工具 才不会报错,如果报错app.json问题,查看此篇文章解决app.json问题
打包后多以文件夹 unpackage

打包方法:
HBuilderX打包方法

vue-cli打包方法

5.打包后,微信小程序工具打开项目 ,如果报以下错误,看图操作

报错信息:
common/main.js:
TypeError: window.WeixinJSBridge.beforeinvoke is not a function

VM304 WAService.js:1 TypeError: window.WeixinJSBridge.beforeinvoke is not a function

Unhandled promise rejection TypeError: WebAssembly.instantiate(): Argument 0 must be a buffer source or a WebAssembly.Module object
at Object.t.wasm_initialize (VM304 WAService.js:1)6.微信小程序部分设置:
1.是否勾选不校验合法域名??(勾中后,在开发时候就不会校验某些域名,例如下载文件和图片时候就不会校验图片的域名地址;但是必须要在小程序后台开发配置好对应域名,否则本地测试可以,但线上就会报域名错误;而不选中就可以在开发时候看到错误信息)
2.设置代理和端口

 

 

7.运行到微信小程序

8.小程序发布需要先设置:
将appID填入到使用uni-app开发的项目manifest.json中

 

9.具体发布小程序看 发布小程序流程

10.因为我们使用的是uni-ui,所以必须要有uni-ui的样式,这里我已经将hello-uniapp-master官方演示案例下的common拿了过来
全局使用uni-ui的样式,在App.vue中引入uni.css;
同时在这一步开启小程序发布后,自动更新提示,自动更新最新版本小程序

11.初始化npm工程

若项目之前未使用npm管理依赖(项目根目录下无package.json文件),先在项目根目录执行命令初始化npm工程:

npm init -y
1
cli项目默认已经有package.json了。HBuilderX创建的项目默认没有,需要通过初始化命令来创建。

12.vuex配置,vuex封装
注意:
1.uni-ui自带store 不需要再重新安装,可以直接创建store文件引入使用
2.在main.js内,将store对象挂载到vue实例中

13.接口uni.request请求接口封装

14.创建项目根目录下components文件夹,放公共vue组件

15.对微信小程序进行分包,uni-app分包步骤(如果不分包,后期打包代码太大会导致二维码预览失败,无法真机调试)

16.微信登录看这篇

17.如果需要自定义微信小程序的导航栏,点击微信小程序自定义tabBar

18.正式开发时候,配置好请求后,在浏览器H5页面和微信小程序工具上,调用接口是正常的,但是真机预览时候,使用真正的手机去调接口,如果没有配置在小程序官方地址上配置ip,那请求接口会无效。

配置ip:在小程序–开发–开发管理–开发设置–服务器域名–request合法域名

 

————————————————
版权声明:本文为CSDN博主「i_am_a_div_日积月累_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/i_am_a_div/article/details/117123206

微信小程序动态修改样式_kkk_3399的博客-CSDN博客_小程序动态修改样式

mikel阅读(249)

来源: 微信小程序动态修改样式_kkk_3399的博客-CSDN博客_小程序动态修改样式

前言
微信小程序动态修改样式:循环数组显示到页面,点击单独的按钮变换单独样式

一、wxml

<view class=”fb_tips”
wx:for=”{{arr11}}”
wx:key=”id”
>
<text class=”title_item {{item.isActive?’active’:”}} ”
bindtap=”clickpp” data-index=”{{index}}”
>{{item.value}}</text>

</view>

二、js
代码如下(示例):

Page({
data: {
arr11:[
{
id: 0,
value: “功能建议”,
isActive:false
},{
id: 1,
value: “购买遇到问题”,
isActive:false

},{
id: 2,
value: “性能问题”,
isActive:true
},{
id: 3,
value: “其他”,
isActive:false
}
]
},
clickpp(e) {
// 页面data-index传进来的索引
const index=e.currentTarget.dataset.index;
// console.log(index);
console.log(this.data.arr11[index].isActive);
// 拼接字符串
const isActive=`arr11[${index}].isActive`
// 使用setData修改当行数据
this.setData({
[isActive]: !this.data.arr11[index].isActive
})
// 打印数据
console.log(this.data.arr11[index].isActive);

}
})

三、wxss
.fb_tips {
display: flex;
flex-wrap: wrap;
}
.fb_tips text {
width: 30%;
padding: 10rpx;
text-align: center;
background-color: #fff;
margin: 20rpx 10rpx;
}
.fb_tips .active{
color:var(–themeColor);
border-bottom: 5rpx solid currentColor;
}

————————————————
版权声明:本文为CSDN博主「kkk_3399」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/kkk_3399/article/details/127678638

使用bat自动执行cmd命令(多个命令或单个命令)_鹏仔工作室的博客-CSDN博客_bat执行cmd命令

mikel阅读(256)

来源: 使用bat自动执行cmd命令(多个命令或单个命令)_鹏仔工作室的博客-CSDN博客_bat执行cmd命令

最近给其他公司开发的项目,需要部署到他那边公司大屏本地,他们大屏电脑动不动经常关机重启,重启一次就得找我们启动项目,非常的麻烦。

下面教大家如何使用bat写一段自动执行cmd启动项目的脚本。

首先,我们新建一个txt的文件,输入下方代码

cmd /k “cd /d 路径&&命令”
例如E盘下的A文件下的B文件,命令是anywhere

cmd /k “cd /d E:\A\B&&anywhere”
路径与命令使用&&隔开,编辑好以后保存,在将“txt”文件后缀改为“bat”,并双击打开,即可自动启动该路径下的cmd并自动执行命令。

其中代码中 /k 表示执行完命令不关闭cmd命令窗口,如果想执行完关闭,我们只需将 /k 更换为 /c 即可。

 

因为不止要启动前端程序,还得启动后端程序,那么我们如何自动执行多个命令呢?

我们只需给前面加上 start 即可,代码如下所示

start cmd /k “cd /d 路径&&命令”
start cmd /k “cd /d 路径&&命令”
例如

start cmd /k “cd /d E:\A\B&&anywhere”
start cmd /k “cd /d C:\xiangmu\wenjian&&java -jar sharedblog.jar”

修改完成后,记得保存bat格式。

最后,我只需给电脑设置开机自启自己写的bat程序即可。

围观地址
————————————————
版权声明:本文为CSDN博主「鹏仔工作室」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/tianpeng1996/article/details/123896364