前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >山科小站小程序

山科小站小程序

作者头像
WindrunnerMax
发布2020-08-27 16:33:21
7990
发布2020-08-27 16:33:21
举报
文章被收录于专栏:Czy‘s BlogCzy‘s Blog

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;
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-03-24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Github:https://github.com/WindrunnerMax/SHST
    • 一、微信小程序转UNIAPP
      • 1. 文件对应关系
      • 2. App.vue文件
      • 3. 自定义组件
      • 4. 自定义文件夹
      • 5. 数据绑定
      • 6. template数据渲染
      • 7. 动态绑定class与style
      • 8. page.json
      • 9. 条件编译功能
      • 10. 阿里矢量图标库Iconfont
    • 二、山科小站实例
      • 1. 目录结构
    • 三、模块化
      • 1. Cookies操作
      • 2. 深浅拷贝
      • 3. 时间日期操作
      • 4. 事件总线
      • 5. 全局变量
      • 6. 加载提示
      • 7. 防抖与节流
      • 8. 正则匹配
      • 9. 网络请求
      • 10. 消息提示
      • 11. 自动更新
      • 12. 启动事件
    • 四、组件化
      • 1. 标题组件
      • 2. 卡片组件
      • 3. 列表组件
      • 4. 每日一句组件
      • 5. 天气组件
    • 五、小程序部署
      • 1. 初始化小程序
      • 2. 全局样式
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档