山科小站
山東科技大學校園小程序,如果覺得不錯,點個star吧 😃
Github:https://github.com/WindrunnerMax/SHST
一、微信小程序轉UNIAPP
最近轉微信小程序項目到UNIAPP項目遇到的的一些注意事項和坑
整體來說遷移項目並不是很復雜,更多的是一些重復的工作
1. 文件對應關系
<template></template> 對應.wxml文件
<script></script> 對應.js文件
<style></style> 對應.wxss文件
在使用HBuildX創建.vue文件時會自動創建模板
2. App.vue文件
globalData、onPageNotFound()、onLaunch()定義於此
在 onLaunch() 中直接綁定於app的方法需要操作this.$scope
3. 自定義組件
created()方法定義為組件創建執行的方法
<slot></slot>作為組件xml插入點,可設置name屬性設置多個插入點
組件單獨掛載,在.vue文件引入后組件,在export default{components: {}}聲明引入組件名
全局掛載組件,在main.js引入並掛載import example from "example.vue"; Vue.component('example',example);
4. 自定義文件夾
自定義文件夾在打包時會自動編譯到/common/下
靜態資源放入static中,打包時目錄不會變動,wxml引入目錄不變
5. 數據綁定
微信小程序中使用 setData({}) 方法將數據發送到視圖層
Vue中數據雙向綁定,使用 this.param = value 重新渲染數據,
當然也可以重寫 setData({}) 方法,官網給予示例
setData:function(obj){
let that = this;
let keys = [];
let val,data;
Object.keys(obj).forEach(function(key){
keys = key.split('.');
val = obj[key];
data = that.$data;
keys.forEach(function(key2,index){
if(index+1 == keys.length){
that.$set(data,key2,val);
}else{
if(!data[key2]){
that.$set(data,key2,{});
}
}
data = data[key2];
})
});
}
6. template數據渲染
要使用的數據必須首先在export default {data() {return { param : value}}}中聲明
在xml節點屬性中使用:attr引用變量值,在xml節點的值使用{{param}}
循環wx:for="{{list}}" wx:key="{{index}}"> 改為 v-for="(item,index) in list" :key="index"
7. 動態綁定class與style
在ES6中可直接在:attr中使用新特性`string${param}string`來拼接字符串,但是微信小程序還不支持
手動拼接字符串的方式:attr="'string' + param"
Vue中提供了動態綁定的方式 <view class="static" :class="{value:active}" :style="{'attr': param}"></view>
8. page.json
在微信小程序的app.json路由在Unaipp中同樣由page.json文件統一管理
微信小程序時在app.json中寫入路由則創建文件,HbuildX中在創建頁面時可選自動在page.json創建路由
在page.json中style對應微信小程序某一頁面的json文件
9. 條件編譯功能
// #ifdef %PLATFORM%
平台特有的API實現,UNIAPP提供的條件編譯功能,非常適用於跨端開發
// #endif
10. 阿里矢量圖標庫Iconfont
將圖標添加到項目,以代碼的方式下載到本地
復制iconfont.css到項目,移除所有類似 url('iconfont.eot?t=1577846073653#iefix') format('embedded-opentype') 部分
在<view class='iconfont icon-shuaxin'></view>引用即可
二、山科小站實例
1. 目錄結構
SHST-UNI // 山科小站總目錄
├── components // 組件封裝
│ ├── headslot.vue // 帶solt的標題布局
│ ├── layout.vue // 卡片式布局
│ ├── list.vue // 展示用list布局
│ ├── sentence.vue // 每日一句封裝
│ └── weather.vue // 天氣封裝
├── modules // 模塊化封裝
│ ├── cookies.js // Cookies操作
│ ├── copy.js // 深淺拷貝
│ ├── datetime.js // 時間日期操作
│ ├── event-bus.js // 事件總線
│ ├── global-data.js // 全局變量
│ ├── loading.js // 加載提示
│ ├── operate-limit.js // 防抖與節流
│ ├── regex.js // 正則匹配
│ ├── request.js // 網絡請求
│ ├── toast.js // 消息提示
│ └── update.js // 自動更新
├── pages // 頁面
│ ├── Ext // 拓展組
│ ├── Home // Tabbar、輔助組
│ ├── Lib // 圖書館功能組
│ ├── Sdust // 科大組
│ ├── Study // 學習組
│ └── User // 用戶組
├── static // 靜態資源
│ ├── camptour // 校園導覽靜態資源
│ └── img // 圖標等靜態資源
├── unpackage // 打包文件
├── utils // 輔助功能
│ ├── amap-wx.js // 高德地圖SDK
│ └── md5.js // MD5引入
├── vector // 部署封裝
│ ├── resources // 資源文件
│ │ ├── camptour // 校園導覽配置文件
│ │ ├── asse.mini.wxss // 公共樣式庫
│ │ └── iconfont.wxss // 字體圖標
│ ├── dispose.js // 部署小程序
│ └── pubFct.js // 公有方法
├── App.vue // App全局樣式以及監聽
├── main.js // 掛載App,Vue初始化入口文件
├── manifest.json // 配置Uniapp打包等信息
├── pages.json // 路由
└── uni.scss // 內置的常用樣式變量
三、模塊化
1. Cookies操作
/**
* GetCookie
*/
function getCookies(res) {
var cookies = "";
if (res && res.header && res.header['Set-Cookie']) {
// #ifdef MP-ALIPAY
var cookies = res.header['Set-Cookie'][0].split(";")[0] + ";";
// #endif
// #ifndef MP-ALIPAY
var cookies = res.header['Set-Cookie'].split(";")[0] + ";";
// #endif
console.log("SetCookie:" + cookies);
uni.setStorage({
key: "cookies",
data: cookies
});
} else {
console.log("Get Cookie From Cache");
cookies = uni.getStorageSync("cookies") || "";
}
return cookies;
}
export { getCookies }
export default { getCookies }
2. 深淺拷貝
function shallowCopy(target, ...origin) {
return Object.assign(target, ...origin);
}
function extend(target, ...origin) {
return shallowCopy(target, ...origin);
}
function deepCopy(target, origin) {
for (let item in origin) {
if (origin[item] && typeof(origin[item]) === "object") {
// Object Array Date RegExp 深拷貝
if (Object.prototype.toString.call(origin[item]) === "[object Object]") {
target[item] = deepCopy({}, origin[item]);
} else if (origin[item] instanceof Array) {
target[item] = deepCopy([], origin[item]);
} else if (origin[item] instanceof Date) {
target[item] = new Date(origin[item]);
} else if (origin[item] instanceof RegExp) {
target[item] = new RegExp(origin[item].source, origin[item].flags);
} else {
target[item] = origin[item];
}
} else {
target[item] = origin[item];
}
}
return target;
}
export { extend, shallowCopy, deepCopy }
export default { extend, shallowCopy, deepCopy }
3. 時間日期操作
/**
* yyyy年 MM月 dd日 hh1~12小時制(1-12) HH24小時制(0-23) mm分 ss秒 S毫秒 K周
*/
const formatDate = (fmt = "yyyy-MM-dd", date = new Date()) => {
var week = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"];
var o = {
"M+": date.getMonth() + 1, //月份
"d+": date.getDate(), //日
"h+": date.getHours(), //小時
"m+": date.getMinutes(), //分
"s+": date.getSeconds(), //秒
"q+": Math.floor((date.getMonth() + 3) / 3), //季度
"S": date.getMilliseconds(), //毫秒
"K": week[date.getDay()]
};
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o) {
if (new RegExp("(" + k + ")").test(fmt))
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (( "00" + o[k]).substr(("" + o[k]).length)));
}
return fmt;
}
const extDate = () => {
// console.log("拓展Date原型");
Date.prototype.addDate = function(years = 0, months = 0, days = 0) {
if (days !== 0) this.setDate(this.getDate() + days);
if (months !== 0) this.setMonth(this.getMonth() + months);
if (years !== 0) this.setFullYear(this.getFullYear() + years);
}
}
/**
* 日期相差天數
*/
const dateDiff = (startDateString, endDateString) => {
var separator = "-"; //日期分隔符
var startDates = startDateString.split(separator);
var endDates = endDateString.split(separator);
var startDate = new Date(startDates[0], startDates[1] - 1, startDates[2]);
var endDate = new Date(endDates[0], endDates[1] - 1, endDates[2]);
var diff = parseInt((endDate - startDate) / 1000 / 60 / 60 / 24); //把相差的毫秒數轉換為天數
return diff;
}
export { formatDate, extDate, dateDiff }
export default { formatDate, extDate, dateDiff }
4. 事件總線
var PubSub = function() {
this.handlers = {};
}
PubSub.prototype = {
on: function(key, handler) { // 訂閱
if (!(key in this.handlers)) this.handlers[key] = [];
this.handlers[key].push(handler);
},
off: function(key, handler) { // 卸載
const index = this.handlers[key].findIndex(item => item === handler);
if (index < 0) return false;
if (this.handlers[key].length === 1) delete this.handlers[key];
else this.handlers[key].splice(index, 1);
return true;
},
commit: function(key, ...args) { // 觸發
if (!this.handlers[key]) return false;
this.handlers[key].forEach(handler => handler.apply(this, args));
return true;
},
}
export { PubSub }
export default { PubSub }
5. 全局變量
/**
* 顏色方案
*/
// var colorList = ["#EAA78C", "#F9CD82", "#9ADEAD", "#9CB6E9", "#E49D9B", "#97D7D7", "#ABA0CA", "#9F8BEC",
// "#ACA4D5", "#6495ED", "#7BCDA5", "#76B4EF","#E1C38F","#F6C46A","#B19ED1","#F09B98","#87CECB","#D1A495","#89D196"
// ];
var colorList = ["#FE9E9F", "#93BAFF", "#D999F9", "#81C784", "#FFCA62", "#FFA477"];
export { colorList }
export default { colorList }
6. 加載提示
/**
* startLoading
*/
function startLoading(option) {
switch (option.load) {
case 1:
uni.showNavigationBarLoading();
break;
case 2:
uni.showNavigationBarLoading();
uni.setNavigationBarTitle({
title: option.title || "加載中..."
})
break;
case 3:
uni.showLoading({
title: option.title || "請求中",
mask: true
})
break;
}
}
/**
* endLoading
*/
function endLoading(option) {
switch (option.load) {
case 1:
uni.hideNavigationBarLoading();
break;
case 2:
uni.hideNavigationBarLoading();
uni.setNavigationBarTitle({
title: option.title || "山科小站"
})
break;
case 3:
uni.hideLoading();
break;
}
}
export { startLoading, endLoading }
export default { startLoading, endLoading }
7. 防抖與節流
/**
* 防抖
* 定時器實現
*/
function debounceGenerater(){
var timer = null;
return (wait, funct, ...args) => {
clearTimeout(timer);
timer = setTimeout(() => funct(...args), wait);
}
}
/**
* 節流
* 時間戳實現
*/
function throttleGenerater(){
var previous = 0;
return (wait, funct, ...args) => {
var now = +new Date();
if(now - previous > wait){
funct(...args);
previous = now;
}
}
}
/*
// 節流
// 定時器實現
function throttleGenerater(){
var timer = null;
return (wait, funct, ...args) => {
if(!timer){
funct(...args);
timer = setTimeout(() => timer = null, wait);
}
}
}
*/
export { debounceGenerater, throttleGenerater }
export default { debounceGenerater, throttleGenerater }
8. 正則匹配
/**
* 正則匹配
*/
const regMatch = (regex, s) => {
var result = [];
var temp = null;
var flags = `${regex.flags}${regex.flags.includes("g") ? "" : "g"}`;
regex = new RegExp(regex, flags);
while (temp = regex.exec(s)) result.push(temp[1] ? temp[1] : temp[0]);
return result;
}
export { regMatch }
export default { regMatch }
9. 網絡請求
import {startLoading, endLoading} from "./loading";
import {getCookies} from "./cookies";
import {extend} from "./copy";
import {toast} from "./toast";
var headers = {'content-type': 'application/x-www-form-urlencoded'};
/**
* HTTP請求
*/
function ajax(requestInfo) {
var option = {
load: 1,
url: "",
method: "GET",
data: {},
headers: headers,
success: () => {},
resolve: () => {},
fail: function() { this.completeLoad = () => { toast("External Error");}},
reject: () => {},
complete: () => {},
completeLoad: () => {}
};
extend(option, requestInfo);
startLoading(option);
uni.request({
url: option.url,
data: option.data,
method: option.method,
header: headers,
success: function(res) {
if (!headers.cookie) headers.cookie = getCookies(res);
if(res.statusCode === 200){
try {
option.success(res);
option.resolve(res);
} catch (e) {
option.completeLoad = () => { toast("External Error");}
console.log(e);
}
}else{
option.fail(res);
option.reject(res);
}
},
fail: function(res) {
option.fail(res);
},
complete: function(res) {
endLoading(option);
try {
option.complete(res);
} catch (e) {
console.log(e);
}
option.completeLoad(res);
}
})
}
/**
* request promise封裝
*/
function request(option) {
return new Promise((resolve,reject) => {
option.resolve = resolve;
option.reject = reject;
ajax(option);
})
}
export { ajax, request }
export default { ajax, request }
10. 消息提示
/**
* 彈窗提示
*/
function toast(e, time = 2000, icon = 'none') {
uni.showToast({
title: e,
icon: icon,
duration: time
})
}
export { toast }
export default { toast }
11. 自動更新
/**
* 小程序更新
*/
function checkUpdate() {
if (!uni.getUpdateManager) return false;
uni.getUpdateManager().onCheckForUpdate((res) => {
console.log("Update:" + res.hasUpdate);
if (res.hasUpdate) { //如果有新版本
uni.getUpdateManager().onUpdateReady(() => { //當新版本下載完成
uni.showModal({
title: '更新提示',
content: '新版本已經准備好,單擊確定重啟應用',
success: (res) => {
if (res.confirm) uni.getUpdateManager().applyUpdate(); //applyUpdate 應用新版本並重啟
}
})
})
uni.getUpdateManager().onUpdateFailed(() => { //當新版本下載失敗
uni.showModal({
title: '提示',
content: '檢查到有新版本,但下載失敗,請檢查網絡設置',
showCancel: false
})
})
}
})
}
export { checkUpdate }
export default { checkUpdate }
12. 啟動事件
"use strict";
import globalData from "@/modules/global-data";
import request from "@/modules/request";
import {toast} from "@/modules/toast";
import {extend} from "@/modules/copy";
import {PubSub} from "@/modules/event-bus";
import {extDate} from "@/modules/datetime";
import {checkUpdate} from "@/modules/update";
import {getCurWeek} from "@/vector/pubFct";
function disposeApp(app){
extDate(); //拓展Date原型
checkUpdate(); // 檢查更新
app.$scope.toast = toast;
app.$scope.extend = extend;
app.$scope.eventBus = new PubSub();
app.$scope.extend(app.$scope, request);
app.$scope.extend(app.globalData, globalData);
app.globalData.colorN = app.globalData.colorList.length;
app.globalData.curWeek = getCurWeek(app.globalData.curTermStart);
}
/**
* APP啟動事件
*/
function onLaunch() {
var app = this;
disposeApp(this);
var userInfo = uni.getStorageSync("user") || {};
uni.login({
scopes: 'auth_base'
}).then((data) => {
var [err,res] = data;
if(err) return Promise.reject(err);
return app.$scope.request({
load: 3,
// #ifdef MP-WEIXIN
url: app.globalData.url + 'auth/wx',
// #endif
// #ifdef MP-QQ
url: app.globalData.url + 'auth/QQ',
// #endif
method: 'POST',
data: {
"code": res.code,
user: JSON.stringify(userInfo)
}
})
}).then((res) => {
app.globalData.curTerm = res.data.initData.curTerm;
app.globalData.curTermStart = res.data.initData.termStart;
app.globalData.curWeek = res.data.initData.curWeek;
app.globalData.loginStatus = res.data.Message;
app.globalData.initData = res.data.initData;
if(app.globalData.initData.custom){
let custom = app.globalData.initData.custom;
if(custom.color_list) {
app.globalData.colorList = JSON.parse(custom.color_list);
app.globalData.colorN = app.globalData.colorList.length;
}
}
if (res.data.Message === "Ex") app.globalData.userFlag = 1;
else app.globalData.userFlag = 0;
console.log("Status:" + (app.globalData.userFlag === 1 ? "User Login" : "New User"));
if (res.data.openid) {
var notify = res.data.initData.tips;
app.globalData.tips = notify;
var point = uni.getStorageSync("point") || "";
if (point !== notify) uni.showTabBarRedDot({ index: 2 });
console.log("SetOpenid:" + res.data.openid);
app.globalData.openid = res.data.openid;
uni.setStorageSync('openid', res.data.openid);
} else {
console.log("Get Openid From Cache");
app.globalData.openid = uni.getStorageSync("openid") || "";
}
return Promise.resolve(res);
}).then((res) => {
if (res.statusCode !== 200 || !res.data.initData || !res.data.initData.curTerm) return Promise.reject("DATA INIT FAIL");
else app.$scope.eventBus.commit('LoginEvent', res);
}).catch((err) => {
console.log(err);
uni.showModal({
title: '警告',
content: '數據初始化失敗,點擊確定重新初始化數據',
showCancel: false,
success: (res) => {
if (res.confirm) onLaunch.apply(app);
}
})
})
}
export default {onLaunch, toast}
四、組件化
1. 標題組件
<template name="headslot">
<view>
<view class="head-line">
<view class="head-left">
<view class="head-row" v-bind:style="{'background-color': color}"></view>
<view class="head-title">{{title}}</view>
</view>
<view style="margin-top: 3px;">
<slot></slot>
</view>
</view>
</view>
</template>
<script>
export default {
name: "headslot",
props: {
title: {
type: String
},
color: {
type: String,
default: "#79B2F9"
},
},
methods: {}
}
</script>
<style>
.head-line {
background-color: #FFFFFF;
padding: 10px 5px;
box-sizing: border-box;
display: flex;
border-bottom: 1px solid #EEEEEE;
justify-content: space-between;
}
.head-row {
width: 2px;
margin: 2px 5px;
}
.head-left{
display: flex;
justify-content: center;
}
.head-title{
display: flex;
justify-content: center;
align-items: center;
white-space: nowrap;
}
</style>
2. 卡片組件
<template>
<view>
<view class="lay-line" v-show="title">
<view class="lay-left-con">
<view class="lay-verline" :style="{background: color}"></view>
<view>{{title}}</view>
</view>
<view>
<slot name="headslot"></slot>
</view>
</view>
<view class="lay-card" :style="{color: computedColor}" :class="{'lay-min-top':!topSpace}">
<slot></slot>
</view>
</view>
</template>
<script>
export default {
name: "layout",
props: {
title: {
type: String,
required: true
},
color: {
type: String,
default: "#79B2F9"
},
topSpace: {
type: Boolean,
default: true
},
inheritColor: {
type: Boolean,
default: false
}
},
computed:{
computedColor: function(){
return this.inheritColor ? this.color : "unset";
}
},
methods: {}
}
</script>
<style>
.lay-line {
background-color: #FFFFFF;
padding: 12px 5px 10px 5px;
box-sizing: border-box;
display: flex;
border-bottom: 1px solid #EEEEEE;
justify-content: space-between;
align-items: center;
}
.lay-verline {
width: 2px;
margin: 2px 5px;
}
.lay-verline + view{
color: #000000;
}
.lay-card {
font-size: 13px;
background-color: #FFFFFF;
padding: 11px;
box-sizing: border-box;
margin-bottom: 10px;
}
.lay-min-top {
padding-top: 3px;
}
.lay-left-con {
display: flex;
}
</style>
3. 列表組件
<template name="list">
<view>
<view class="list-line">
<view class="list-left" v-bind:style="{'background-color': color}"></view>
<view class="list-right">{{title}}</view>
</view>
<view v-for="(item,index) in info" :key='index'>
<view class='list-card'>
<text >{{item}}</text>
</view>
</view>
</view>
</template>S
<script>
export default {
name: "list",
props: {
title: {
type: String,
default: "Default"
},
color: {
type: String,
default: "#79B2F9"
},
info: {
type: Array
}
},
methods: {}
}
</script>
<style>
.list-line{
background-color: #FFFFFF;
padding:10px 5px;
box-sizing: border-box;
display: flex;
margin-bottom: 10px;
}
.list-line .list-left{
width: 2px;
margin: 2px 5px;
}
.list-card{
font-size: 13px;
background-color: #FFFFFF;
padding: 15px;
box-sizing: border-box;
margin-bottom: 10px;
}
</style>
4. 每日一句組件
<template name="sentence">
<view>
<view style="margin: 6px 0 8px 3px;">{{sentence}}</view>
<view style="margin: 3px 0 8px 3px;">{{content}}</view>
<image class="sent-image" :src="url" mode="aspectFill"></image>
</view>
</template>
<script>
export default {
name: "sentence",
props: {},
methods: {},
data() {
return {
url: "",
sentence: "",
content: ""
}
},
created: function() {
var that = this;
uni.request({
url: "https://open.iciba.com/dsapi/",
success: function(res) {
that.url = res.data.picture2;
that.sentence = res.data.note;
that.content = res.data.content;
}
})
}
}
</script>
<style>
.sent-image {
width: 100%;
}
</style>
5. 天氣組件
<template name="weather">
<view>
<view class='weather'>
<view class='weaLeft'>
<view style="display: flex;align-items: center;justify-content: center;">
<image class='todayImg' mode="aspectFit" :src="host+'/public/static/weather/'+todayWeather[1]+'.png'"></image>
</view>
<view style='text-align:center;margin-top:6px;'>{{todayWeather[0]}}</view>
<view style='text-align:center;margin-top:3px;'>{{todayWeather[2]}}℃ - {{todayWeather[3]}}℃</view>
<view style='text-align:center;margin-top:3px;'>{{todayWeather[4]}}</view>
</view>
<view class='weaRight'>
<view class='weaRightTop'>
<image class='dayImg' mode="aspectFit" :src="host+'/public/static/weather/'+tomorrowWeather[1]+'.png'"></image>
<view class='weatherCon'>
<view style='text-align:center;margin-top:6px;'>{{tomorrowWeather[0]}}</view>
<view style='text-align:center;margin-top:3px;'>{{tomorrowWeather[2]}}℃ - {{tomorrowWeather[3]}}℃</view>
</view>
</view>
<view class='weaRightBot'>
<image class='dayImg' mode="aspectFit" :src="host+'/public/static/weather/'+tdatomoWeather[1]+'.png'"></image>
<view class='weatherCon'>
<view style='text-align:center;margin-top:3px;'>{{tdatomoWeather[0]}}</view>
<view style='text-align:center;'>{{tdatomoWeather[2]}}℃ - {{tdatomoWeather[3]}}℃</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: "weather",
props: {},
methods: {},
data() {
return {
todayWeather: ["", "CLEAR_DAY", 0, 0, "數據獲取中"],
tomorrowWeather: ["", "CLEAR_DAY", 0, 0],
tdatomoWeather: ["", "CLEAR_DAY", 0, 0],
host: "https://www.touchczy.top"
}
},
created: function() {
var that = this;
var ran = parseInt(Math.random() * 100000000000);
uni.request({
url: "https://api.caiyunapp.com/v2/Y2FpeXVuIGFuZHJpb2QgYXBp/120.127164,36.000129/weather?lang=zh_CN&device_id=" +
ran,
success: function(res) {
if (res.data.status === "ok") {
var weatherData = res.data.result.daily;
that.todayWeather = [weatherData.skycon[0].date, weatherData.skycon[0].value, weatherData.temperature[0].min,
weatherData.temperature[0].max, res.data.result.hourly.description
]
that.tomorrowWeather = [weatherData.skycon[1].date, weatherData.skycon[1].value, weatherData.temperature[1].min,
weatherData.temperature[1].max
]
that.tdatomoWeather = [weatherData.skycon[2].date, weatherData.skycon[2].value, weatherData.temperature[2].min,
weatherData.temperature[2].max
]
}
}
})
}
}
</script>
<style>
.weather {
display: flex;
border: 1px solid #eee;
transition: all 0.8s;
font-size: 13px;
border-radius: 3px;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.weaLeft {
width: 50% ;
padding: 10px;
border-right: 1px solid #eee;
}
.todayImg {
width: 40px !important;
height: 40px !important;
}
.dayImg {
width: 30px !important;
height: 30px !important;
margin: 0 0 0 15px;
align-self: center;
}
.weaRight {
width: 50%;
}
.weaRightBot,
.weaRightTop {
display: flex;
height: 50%;
text-align: center;
}
.weaRightBot {
border-top: 1px solid #eee;
}
.weatherCon {
align-self: center;
margin: 0 auto;
}
</style>
五、小程序部署
1. 初始化小程序
import dispose from "@/vector/dispose";
export default {
globalData: {
tips: "0",
openid: "",
userFlag: 0, // 0 未登錄 1 已登陸
initData: {},
version: "3.3.0",
curTerm: "2019-2020-1",
curTermStart: "2019-08-26",
url: 'https://www.touchczy.top/',
// url: 'http://dev.touchczy.top/',
},
onPageNotFound: (res) => { //處理404
uni.reLaunch({
url: 'pages/Home/auxiliary/notFound'
})
},
onLaunch: function() {
console.log("APP INIT");
dispose.onLaunch.apply(this); //啟動加載事件
},
onError: (err) => {
console.log(err);
dispose.toast("Internal Error");
}
}
2. 全局樣式
/*全局樣式*/
@import "@/vector/resources/asse.mini.wxss";
@import "@/vector/resources/iconfont.wxss";
button:after {
border: none;
}
button {
background: #fff;
border: none;
box-sizing: unset;
padding: 0;
margin: 0;
font-size: 13px;
line-height: unset;
height: auto;
}
.adapt{
box-sizing: border-box;
}
.tipsCon view{
padding: 5px;
}