Commit 6ba5c8f2 authored by sheng du's avatar sheng du
Browse files

add

parents
No related merge requests found
Pipeline #815 failed with stages
in 0 seconds
{ // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
// launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数
"version": "0.0",
"configurations": [{
"default" :
{
"launchtype" : "local"
},
"mp-weixin" :
{
"launchtype" : "local"
},
"type" : "uniCloud"
}
]
}
<script>
import config from './config';
//app.js
export default {
data() {
return {};
},
onLaunch: function() {
// 展示本地存储能力
var logs = uni.getStorageSync('logs') || [];
logs.unshift(Date.now());
uni.setStorageSync('logs', logs);
// 获取用户信息
uni.getSetting({
success: (res) => {
if (res.authSetting['scope.userInfo']) {
// 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
uni.getUserInfo({
success: (res) => {
// 可以将 res 发送给后台解码出 unionId
this.globalData.userInfo = res.userInfo;
// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
// 所以此处加入 callback 以防止这种情况
if (this.userInfoReadyCallback) {
this.userInfoReadyCallback(res);
}
}
});
}
}
});
},
globalData: {
userInfo: null,
url: config.apiRoot,
// url:'https://hkland.kupurui.cn',
// url:'http://183.230.204.109:8000',
tcid: ''
}
};
</script>
<style>
@import './font/font.css';
/**app.wxss**/
text,
input,
button {
/* font-family: 'PingFang Medium'; */
}
.chaxun {
width: 100%;
height: 88rpx;
color: #fff;
line-height: 88rpx;
text-align: center;
font-size: 34rpx;
outline: none;
background-color: #89e5e0;
border-radius: 44rpx;
border: 0;
}
</style>
\ No newline at end of file
# miniprogram-to-uniapp 转换说明
## 0x00 转换模式
根据转换模式,转换后的项目使用相应的工具打开,目前有两种模式:
### HBuilder X 模式
转换后的目录(以_uni结尾的目录), 需使用HBuilder X导入,进行运行和调试。
如果项目使用了npm模块,需先使用npm install等命令进行安装,然后再运行
### Vue-cli 模式
转换后的目录(以_vue-cli结尾的目录), 需使用命令行安装依赖、运行和打包。
详见文档:https://uniapp.dcloud.io/quickstart-cli.html#%E8%BF%90%E8%A1%8C%E3%80%81%E5%8F%91%E5%B8%83uni-app
注:
上述两种项目类型,可以相互转换。
[uni-app HBuilderX 工程与 vue-cli 工程相互转换](https://ask.dcloud.net.cn/article/35750)
## 0x01 调试建议
如果您想转换小程序为uni-app项目,并发布为App,
建议运行到H5平台,因为H5平台速度快,而且与App平台贴合度更高。
只有当强依赖硬件时,才使用真机调试,这样可以节约时间!
## 0x02 常见问题
### 1.命令行提示:“'wtu'不是内部或外部命令, 也不是可运行的程序”
一般是node未安装在默认目录导致的,参照文章 [解决“npm不是内部或外部命令“](https://www.cnblogs.com/ldq678/p/10291824.html) 解决。
### 2.PowerShell里提示:无法加载文件 XXXXXXXXX.ps1,因为在此系统上禁止运行脚本。
以管理员身份运行`powershell`,执行
```
set-executionpolicy remotesigned
```
输入 y 即可
或者,在PowerShell输入 `cmd` 后回车也行
### 3.setData为什么没有转换?需要我手动改吗?那我有100多个页面怎么改呀?
`setData`函数已内置,在main.js通过mixin全局混入,所以不用转换,可直接使用`setData`函数!!!
### 4.命令行报错:"cannot read property ‘某某某’ of undefined"
报错解释:有代码“`xx.某某某`”,但xx的值是undefined,因此,需要进报错的页面,调试调试,为啥xx为undefined,相应的调试代码即可。
常见原因:可能接口跨域,可能真的没值,也可能没声明变量,也可能是工具转换问题等。
### 5.为什么我运行到H5或app时,拿不到小程序用户的信息?为什么登录失败?
转换后的uni-app项目,如需运行到其他小程序、H5和App时,登录和支付功能均需“重新对接”,需要增加 “新” 接口!
### 6.跨域问题:为什么我的接口都没有返回数据呀?
控制台有“CORS”、“Access-Control-Allow-Origin”等关键字时,不要犹豫,果断判断是因为跨域,导致访问接口失败。
跨域,前端老生常谈,有N种解决办法,最简单的办法是运行到“内置浏览器”。
PS: 仅仅 H5 平台存在跨域问题!发布后上传到服务器无此问题!
### 7.Vant项目怎么转换呀?
Vant项目比较常见的报错是:代码`<button class="{{ utils.bem('action-sheet__item', { disabled: item.disabled || item.loading }) }} {{ item.className || '' }}"></button>`转到后,运行会报错,因为uni-app不支持在class里面写函数)
由于Vant的一些语法uni-app并不支持,因此需要特殊处理一下,这里分享三种方案,可以根据自己的情况进行选择。
#### 方案一:【替换Vant组件】
转换前,将vant组件全部用别的组件库替换掉再转换。
#### 方案二:【替换Vant组件】
转换后,将vant组件使用uview1.x替换掉同功能组件。
#### 方案三:【不替换Vant组件】
转换后,按uniapp引入小程序组件文档重新引入vant组件(小程序自定义组件支持:
https://uniapp.dcloud.io/tutorial/miniprogram-subject.html#%E5%B0%8F%E7%A8%8B%E5%BA%8F%E8%87%AA%E5%AE%9A%E4%B9%89%E7%BB%84%E4%BB%B6%E6%94%AF%E6%8C%81)
### 8.小程序转换为uni-app项目后,还能转换成其他小程序项目吗?
当然可以,必须可以!
小程序转换为uni-app项目后,就是uni-app项目了,uni-app项目能做啥就能做啥,
能再次生成为各种小程序、发布H5和App。
### 9.uni-app生成的小程序项目,还能再转换回uni-app项目吗?
不能。不支持这种项目的转换!
### 其他
- 因各种原因,本工具并非100%完美转换!有问题实属正常!
- 如遇运行报错,请在https://github.com/zhangdaren/miniprogram-to-uniapp,将详细情况提交Issue!
/**
* http 请求封装
* @author tangsj
* @param {*} url 请求地址
* @param {*} options 请求参数
*/
import config from '../config';
import utils from '../utils';
// 记录请求中的请求数,控制loading显示
let requestCount = 0;
let hasError = false;
export function fetch(url, options) {
const header = {
key: 'bdc27dab6487a7f4b94cefdfea8da8b8',
token: 'bdc27dab6487a7f4b94cefdfea8da8b8',
propertyId: config.propertyId,
};
if(uni.getStorageSync('token')){
header['token'] = uni.getStorageSync('token')
}
options = Object.assign({
loading: true,
method: 'GET',
data: {},
holdTip: false,
}, options);
return new Promise((resolve, reject) => {
if (requestCount === 0 && options.loading) {
hasError = false;
uni.showLoading({
title: '加载中...',
});
}
requestCount += 1;
uni.request({
url: `${config.apiRoot}${url}`,
data: options.data,
method: options.method,
header,
success: (res) => {
console.log(res)
if (+res.data.code !== 200) {
if(res.data.message === '登录过期,请重新登录!'){
console.log("fdsa")
uni.removeStorageSync('token');
uni.reLaunch({
url: '/basicsPage/login/index',
});
}
if (!options.holdTip) {
uni.showToast({
title: res.message || '服务器异常!',
icon: 'none',
});
hasError = true;
}
return reject(res.data || {});
}
return resolve(res.data || {});
},
fail: (err) => {
console.log(err);
hasError = true;
uni.showToast({
title: '服务器异常!',
icon: 'none',
});
reject({
msg: '服务器异常!',
});
},
complete: () => {
requestCount -= 1;
if (requestCount === 0 && options.loading) {
if (hasError) {
setTimeout(() => {
uni.hideLoading();
}, 2000);
} else {
uni.hideLoading();
}
}
},
});
});
}
const http = {
get(url, data = {}, options = {}) {
return fetch(url, {
method: 'GET',
data: data.params,
...options,
});
},
post(url, data = {}, options = {}) {
if (data.params) {
// 将param放到url 参数里面
const query = utils.buildQueryString(data.params);
url += `?${query}`;
delete data.params;
}
return fetch(url, {
method: 'POST',
data,
...options,
});
},
};
export default http;
const files = require.context('.', false, /\.js$/);
const modules = {};
files.keys().forEach((key) => {
if (key === './index.js' || key === './http.js') return;
const reg = /^\.\/(.*)\.js$/;
const m = key.match(reg);
if (m[1]) {
modules[m[1]] = files(key).default;
}
});
export default modules;
import http from './http';
export default {
/**
* 获取手机号
* @param {*} data
* @returns
*/
getMobile(data) {
return http.post('/api/user/getMobile', data);
},
/**
* 访客申请
* @param {*} data
* @returns
*/
apply(data) {
return http.post('/api/visitor_apply/apply', data);
},
// /**
// * 获取用户信息
// * @returns
// */
// getUserInfo(params) {
// return http.get('/api/user/me', {
// params
// });
// },
};
\ No newline at end of file
File added
<template>
<view class="car-number">
<view class="wrap" @tap="focusHandler">
<view class="left">
<view :class="[
'cell',
{ active: index === current },
]" v-if="index != fill.length-1" v-for="(val, index) in fill" :key="index" @tap.stop="focusHandler(index)">
<!-- <view v-if="index === 2" class="point"></view> -->
<view class="val">
{{val}}
</view>
<!-- <view v-if="index === length - 1 && !val" class="new-energy">新能源</view> -->
<view class="border"></view>
</view>
</view>
<view class="right">
<view class="new-energy">新能源</view>
<view :class="[
'cell',
{ active: index === current },
]" v-if="index == fill.length-1" v-for="(val, index) in fill" :key="index" @tap.stop="focusHandler(index)">
<!-- <view v-if="index === 2" class="point"></view> -->
<view class="val">
{{val}}
</view>
<!-- <view v-if="index === length - 1 && !val" class="new-energy">新能源</view> -->
<view class="border"></view>
</view>
</view>
</view>
<key-board v-if="focus" :type="kType" @on-delete="keyDeleteHandler" @on-input="keyInputHandler"
@on-hide="keyHideHandler"></key-board>
</view>
</template>
<script>
import KeyBoard from '../codecook-keyboard/codecook-keyboard.vue';
export default {
name: 'CarNumber',
components: {
KeyBoard
},
props: {
value: {
type: String,
default: '',
},
length: {
type: Number,
default: 8
}
},
data() {
return {
focus: false,
current: 0,
fill: new Array(this.length).fill(''),
}
},
computed: {
kType() {
return this.current === 0 ? 'provinces' : 'areas';
},
},
watch: {
fill(val) {
this.$emit('input', val.join(''));
this.$emit('change', val);
},
value(val) {
if (val && val !== this.fill.join('')) {
this.defaultFill();
}
},
},
methods: {
defaultFill() {
this.value.split('').forEach((key, index) => {
if (index >= this.length) {
return;
}
this.$set(this.fill, index, key);
});
this.current = Math.min(this.value.length, this.length - 1);
},
focusHandler(index = 0) {
this.focus = true;
this.current = index;
console.log(this.current);
},
keyDeleteHandler() {
this.$set(this.fill, this.current, '');
if (this.current <= 0) {
return;
}
this.current -= 1;
},
keyInputHandler(key) {
this.$set(this.fill, this.current, key);
if (this.current >= this.length - 1) {
return;
}
this.current += 1;
},
keyHideHandler() {
this.$emit('on-hide');
this.focus = false;
},
},
beforeMount() {
if (this.value) {
this.defaultFill();
}
},
mounted() {
this.focus = false;
},
}
</script>
<style scoped lang="less">
.car-number {
position: relative;
width: 100%;
.wrap {
width: 100%;
height: 100%;
display: flex;
justify-content: space-between;
.left {
display: flex;
justify-content: space-between;
align-items: center;
height: 110rpx;
width: 100%;
border-radius: 8rpx;
background: #FFFFFF;
border: 1px solid #E6E6E6;
}
.right {
display: flex;
align-items: center;
flex-shrink: 0;
margin-left: 10rpx;
width: 84rpx;
height: 110rpx;
border-radius: 8rpx;
background: #FFFFFF;
position: relative;
border: 1px dashed #53E78E;
}
.new-energy {
position: absolute;
top: -24rpx;
right: -12rpx;
width: 74rpx;
height: 34rpx;
border-radius: 8rpx;
background: #53E78E;
display: flex;
justify-content: center;
align-items: center;
font-size: 22rpx;
color: #fff;
}
}
.cell {
background: #FFFFFF;
// border-radius: 4px;
border-right: 1rpx solid #CCCCCC;
box-sizing: border-box;
width: 82rpx;
height: 74rpx;
color: #333;
font-size: 36rpx;
display: flex;
justify-content: center;
align-items: center;
position: relative;
// &:nth-child(2) {
// margin-right: 14rpx;
// }
&:last-child {
border-right: none;
}
.point {
position: absolute;
left: -18rpx;
top: 50%;
transform: translateY(-50%);
width: 10rpx;
height: 10rpx;
background: #333333;
border-radius: 50%;
}
// .new-energy {
// width: 70rpx;
// height: 70rpx;
// display: flex;
// justify-content: center;
// align-items: center;
// position: absolute;
// right: 0;
// top: 0;
// font-size: 16rpx;
// font-weight: 400;
// color: #959595;
// }
.val {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
}
.border {
position: absolute;
bottom: 6rpx;
flex-shrink: 0;
flex-grow: 0;
height: 2rpx;
background: transparent;
width: 100%;
}
&.active {
.border {
width: 80%;
background: #3EDAD1;
}
}
// &.no-border {
// border-right: none;
// }
}
}
</style>
\ No newline at end of file
File added
<template>
<view class="car-keyboard">
<view class="status-bar">
<view class="close" @click="hideHandler">
关闭
</view>
</view>
<view class="keys-container">
<view class="row" v-for="(row, index) in keys" :key="index">
<view
:class="[
'key',
{ last: j === row.length - 1 },
{ 'is-delete': deleteKeys.includes(key) },
]"
v-for="(key, j) in row"
:key="key"
@click="keyTapHandler(key)"
>
<view class="txt" v-if="!deleteKeys.includes(key)">
{{key}}
</view>
<view class="delete" v-else></view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'KeyBoard',
components: {
},
props: {
value: {
type: Boolean,
default: false,
},
type: {
type: String,
default: 'provinces',
validator: (value) => {
return ['provinces', 'areas'].indexOf(value) !== -1
}
},
},
data() {
return {
deleteKeys: ['-', '='], // 避免2个删除按钮key冲突
provinces: [
[ "", "", "", "", "", "", "", "", "", "" ],
[ "", "", "", "", "", "", "", "", "", "" ],
[ "", "", "", "", "", "", "", "", "", "" ],
[ "", "", "", "", "使", "", "", "", "=" ],
],
areas: [
[ "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" ],
[ "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P" ],
[ "A", "S", "D", "F", "G", "H", "J", "K", "L" ],
[ "Z", "X", "C", "V", "B", "N", "M", "-" ],
],
}
},
watch: {
},
computed: {
keys() {
return this[this.type];
},
},
methods: {
keyTapHandler(key) {
if (this.deleteKeys.includes(key)) {
this.$emit('on-delete');
return;
}
this.$emit('on-input', key);
},
hideHandler() {
this.$emit('on-hide');
}
},
beforeMount() {
},
mounted() {
},
}
</script>
<style scoped lang="less">
.car-keyboard {
position: fixed;
/* #ifdef MP-WEIXIN */
bottom: 0;
/* #endif */
/* #ifndef MP-WEIXIN */
bottom: 100rpx;
/* #endif */
left: 0;
width: 100%;
background-color: #F5F5F5;
z-index: 2;
}
.status-bar {
height: 80rpx;
background: #DFE8E7;
color: #323330;
display: flex;
flex-direction: row-reverse;
}
.close {
font-size: 30rpx;
height: 100%;
padding: 0 20rpx;
display: flex;
align-items: center;
}
.keys-container {
padding: 23rpx 13rpx 30rpx 13rpx;
}
.row {
display: flex;
flex-wrap: wrap;
justify-content: center;
margin-bottom: 14rpx;
}
.key {
width: 60rpx;
height: 72rpx;
background: #FFFFFF;
border: 1rpx solid #E6E6E6;
box-sizing: border-box;
border-radius: 4rpx;
color: #323330;
font-size: 36rpx;
display: flex;
align-items: center;
justify-content: center;
margin-right: 14rpx;
.delete {
width: 66rpx;
height: 40rpx;
background: url('../../static/icon_delete.png') no-repeat;
background-size: 100% 100%;
}
&.is-delete {
width: 134rpx;
}
&.last {
margin-right: 0;
}
}
</style>
// #ifdef H5
const baseUrl = '';
// #endif
const phpRoot = '';
// #ifdef MP-WEIXIN
// const baseUrl = 'https://pmdc.hklcn.com'; // 本地
const baseUrl = 'https://hkland.kupurui.cn'; // 测试服
// const baseUrl = 'https://pmdc.hklcn.com'; // 正式服
// #endif
const imageView = 'https://hkland.kupurui.cn'; // 测试服
// const imageView = 'https://pmdc.hklcn.com'; // 正式服
export default {
baseUrl,
phpRoot,
imageView
};
/**
* 系统配置参数
*/
import development from './development';
import production from './production';
const { NODE_ENV } = process.env;
let base = {};
if (NODE_ENV === 'development') {
base = development;
} else if (NODE_ENV === 'production') {
base = production;
}
const Config = {
propertyId: 1,
apiRoot: `${base.baseUrl}`,
...base,
};
export default Config;
\ No newline at end of file
// #ifdef H5
const baseUrl = '';
// #endif
const phpRoot = '';
// #ifdef MP-WEIXIN
// const baseUrl = 'https://pmdc.hklcn.com'; // 本地
const baseUrl = 'https://hkland.kupurui.cn'; // 测试服
// const baseUrl = 'https://pmdc.hklcn.com'; // 正式服
// #endif
const imageView = 'https://hkland.kupurui.cn'; // 测试服
// const imageView = 'https://pmdc.hklcn.com'; // 正式服
export default {
baseUrl,
phpRoot,
imageView
};
File added
File added
File added
File added
File added
File added
@font-face {
/* font-family: 'PingFang Medium'; */
/* src: url('./PingFang Medium.ttf'); */
font-weight: normal;
font-style: normal;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment