uni-app实战仿微信app开发

百度云盘

1CSS样式
推荐使用scss

学习地址:https://www.sass.hk/

学习地址:http://www.ruanyifeng.com/blog/2012/06/sass.html

html标签嵌套和css样式一一对应,方便维护

页面或组件的第一个标签的class名称和文件名称一样

尽量使用 > 子元素选择器

尽量不在html标签内写样式,当html标签内的样式超过三个时,应为其建立一个class

image

动态写入样式,样式名应改为小驼峰命名,例如:padding-top => paddingTop

image

当同类别标签只有一个时,可以不命名class,使用 > 子元素选择器对相应的标签设置样式

image

页面中不同功能模块之间应加注释并空一行

image
JavaScript

尽量使用es6语法

学习地址:http://es6.ruanyifeng.com/

举例几点常用规范:

使用let代替var,常量应使用const定义

使用箭头函数,可以正常取到页面中的this对象

methods中的方法命名时应加一个前缀,作者使用的是hd,handle的缩写,以区别外部引入的方法

方法应有备注,并且上下空一行

在功能调试完后,相关的打印代码可保留,但应该注释掉

image

数据请求应封装成promise进行调用,并使用try catch处理异常,对错误进行提示

尽量减少代码嵌套

image

应使用 === 进行强类型比较,而不是 ==

当情况只有两种时,尽量用三元运算,而不是if else

字符的处理尽量用模板字符串 `` 而不是 + ,变量放在${}里面

image
vuex

学习资料:https://vuex.vuejs.org/zh/guide/

vuex的文件结构

store文件夹位于根目录

 

image.png

模块模板,文件名article.js

 

    export default {
            // 命名空间
        namespaced: true,
            // 变量数据
        state: {
            detail: {}
        },
            // 获取变量的快捷方法
        getters: {},
            // 变量写操作
        mutations: {
            SET_detail(state, obj) {
                state.detail = obj
            }
        },
            // 复杂且异步的方法
        actions: {
            functionName({state, commit, dispatch}, data) {
                return new Promise((resolve, reject) => {
                    // 发出一个请求
                    request().then(res => {
                        // 正确的请求响应
                        // 处理数据,调用同模块中的mutations
                        commit('SET_detail', res)
                        // 处理数据,调用同模块中的actions
                        dispatch('functionName2', res)
                        // 返回正确
                        resolve(res)
                    }).catch(err => {
                        // 错误的请求响应
                        // 返回错误
                        reject(err)
                    })
                })
            },
            functionName2({state, commit, dispatch}, data) {
                return new Promise((resolve, reject) => {
                    resolve()
                })
            }
        }
    }

写好的模块要在index.js中引用

 

    import Vue from 'vue'
    import Vuex from 'vuex'
    import article from './modules/article'
    Vue.use(Vuex)
    export default new Vuex.Store({
        modules: {
            article
        }
    })

最终在main.js中引用

 

    import Vue from 'vue'
    import App from './App'
     
    import store from './store/index'
    Vue.prototype.$store = store
     
    App.mpType = 'app'
     
    const app = new Vue({
        ...App,
        store,
    })
    app.$mount()

引用模块中的变量和方法

 

    // 引用变量
    const { detail } = this.$store.state.article;
    // 引用mutations
    this.$store.commit('article/SET_detail', {});
    // 引用actions
    this.$store.dispatch('article/functionName', {})

Nativejs

js操作移动端底层的相关API

学习地址:http://www.html5plus.org/doc/h5p.html

制作一个全局显示的组件

相应api:http://www.html5plus.org/doc/zh_cn/nativeobj.html#plus.nativeObj.View

 

    export default {    
        showWeixinS: {},    
        showWeixinV: {},    
        showWeixinO: {},    
        init() {    
            const screenHeight = plus.screen.resolutionHeight;  
            const screenWidth = plus.screen.resolutionWidth;    
            // 初始化普通遮罩  
            this.showWeixinS = new plus.nativeObj.View("showWeixinS", {
                top: '0px',
            left: '0px',    
                height: '100%',
                width: '100%',  
                backgroundColor: 'rgba(0,0,0,0.5)'  
            })  
            // 内容   
            this.showWeixinV = new plus.nativeObj.View("showWeixinV", {
                top: (screenHeight - 315) / 2,  
                height: 315,    
                left: (screenWidth - 300) / 2,  
                width: 300  
            });
            const time = new Date().getTime();
            this.showWeixinV.draw([
                {   
                    // 背景   
                    tag: 'rect',    
                    color: 'rgb(255,255,255)',  
                    rectStyles: {   radius: '10px'  },  
                    position: {  width: '300px',  height: '315px'  }
                },  {   
                    // 头像   
                    tag: 'img',
                    id: time + 'img',   
                    src: '/static/logo.png',    
                    position: {  top: '28px',  left: (300 - 45) / 2,  width: '45px',  height: '45px'  }
                },  {   
                    tag: 'font',    id: Math.random() * 1000 + time,    
                    text: '导师微信',   
                    textStyles: {  size: 15,  align: 'center'  },   
                    position: {   top: '80px',  left: 0,  width: 300,  height: 21  }    
                },  {
                // 微信号
                    tag: 'font',    
                    id: time + 'num',   
                    text: 'num',    
                    textStyles: {  size: 18,  align: 'center',  overflow: 'ellipsis'  },    
                    position: {  top: '104px',  left: 0,  width: 300,  height: 25  }    
                },  {   
                    // 按钮   
                    tag: 'rect',    
                    color: 'rgba(255, 140, 148, 1)',    
                    rectStyles: {  radius: 23  },   
                    position: {  top: 150,  left: 40,  width: 220,  height: 46  }   
                },  {   
                    // 按钮文字
                    tag: 'font',    id: Math.random() * 1000 + time,    
                    text: '复制并打开微信',    
                    textStyles: {  size: 18,  color: 'rgba(255, 255, 255, 1)',  align: 'center',  verticalAlign: 'middle',  overflow: 'ellipsis'  },    
                    position: {  top: 150,  left: 40,  width: 220,  height: 46  }   
                },  {
                    // 图标
                    tag: 'img',
                    id: Math.random() * 1000 + time,    
                    src: '/static/images/comm/remind.png',
                    position: {   top: 219,  left: 22,  width: 17,  height: 17  }   
                }, {    
                    // 提示文字
                    tag: 'font',    
                    id: Math.random() * 1000 + time,    
                    text: ' 温馨提示,为了保障您的权益,跳出APP切勿进行私人转账',   
                    textStyles: {  size: 12,  color: 'rgba(153, 153, 153, 1)',  align: 'left',  whiteSpace: 'normal'  },    
                    position: {  top: 216,  left: 22,  width: 260,  height: 40  }   
                },  
            ]);
            //处理遮罩层点击   
            this.showWeixinS.addEventListener("click", () => {
                this.showWeixinS.hide();
                this.showWeixinV.hide();    
            });
            this.showWeixinO = {    
                imgId: time + 'img',    
                numId: time + 'num'
        };  
        },  
     
        showWeixin({ num, imgUrl }) {   
            const { showWeixinS, showWeixinV, showWeixinO } = this;
            const screenHeight = plus.screen.resolutionHeight;  
            const screenWidth = plus.screen.resolutionWidth;    
            showWeixinV.clearRect({ top: '0px', left: '0px', width: '300px', height: '315px' }, showWeixinO.imgId);
            showWeixinV.clearRect({ top: '0px', left: '0px', width: '300px', height: '315px' }, showWeixinO.numId);
            showWeixinV.draw([  
                {   
                    // 头像   
                    tag: 'img',
                    id: showWeixinO.imgId,  
                    src: imgUrl,    
                    position: { top: '28px',    left: (300 - 45) / 2,   width: '45px', height: '45px',  }   
                },  
                {   
                    // 微信号  
                    tag: 'font',
                    id: showWeixinO.numId,
                    text: num,  
                    textStyles: {   size: 18,   align: 'center',    overflow: 'ellipsis'    },
                    position: { top: '104px',   left: 0,    width: 300, height: 25  }   
                },  
            ]);
            // 点击按钮
            this.showWeixinV.addEventListener("click", (e) => {
                const top = (screenHeight - 315) / 2 + 150;
                const left = (screenWidth - 300) / 2 + 40;  
                if (top < e.screenY && e.screenY < top + 46 && left < e.screenX && e.screenX < left + 220) {    
                    uni.setClipboardData({  
                        data: num,  
                        success: () => {    
                            console.log('success');
                            plus.runtime.launchApplication({
                                pname: 'com.tencent.mm',
                                extra: { url: 'http://www.html5plus.org' }
                            },  function(e) {   
                                alert('Open system default browser failed: ' + e.message);  
                            });
                        },  
                        fail:(err) => {
                            console.log('err', err);    
                        }   
                    });
                }   
            });
            showWeixinS.show()  
            showWeixinV.show()  
        },  
        // 关闭弹窗
        hideWeixinPanel() {
            const { showWeixinS, showWeixinV } = this;  
            showWeixinS.hide();
            showWeixinV.hide();
        }
    }  

在main.js引用到全局进行调用

 

    // 私有子窗口
    import msv from './utils/mySubView.js'
    Vue.prototype.$msv = msv;

效果

 

image.png
使用uniapp的subNVue

配置:https://uniapp.dcloud.io/collocation/pages?id=subpackages
相关API:https://uniapp.dcloud.io/api/window/subNVues?id=app-getsubnvuebyid
以下举例制作全局引用

文件路径

 

image.png

在引用的页面需在pages.json中配置

 

image.png

子窗口:showWeixin.nvue

 

    <template>
        <div class="show-weixin">
            <image class="sw-image" :src="imgUrl"></image>
            <text style="font-size: 30rpx; margin-top: 10rpx;">导师微信</text>
            <text style="font-size: 36rpx; font-weight:500; margin-top: 10rpx;">{{ num }}</text>
            <div class="sw-button" @click="hdGotoWeixin"><text class="swb-text">复制并打开微信</text></div>
            <div class="sw-remind">
                <image class="swr-image" src="../../../static/images/comm/remind.png"></image>
                <text class="swr-text">温馨提示,为了保障您的权益,跳出APP切勿</text>
                <text class="swr-text">进行私人转账</text>
            </div>
        </div>
    </template>
     
    <script>
    export default {
        data() {
            return {
                num: '',
                imgUrl: ''
            };
        },
        created() {
            const subNVue = uni.getSubNVueById('showWeixin');
            subNVue.onMessage(msg => {
                // console.log('监听来自所属页面的 message' + JSON.stringify(msg));
                const { num, imgUrl } = msg.data;
                this.num = num;
                this.imgUrl = imgUrl;
            });
        },
        methods: {
            // 前往微信
            hdGotoWeixin() {
                const { num } = this;
                // console.log('hdGotoWeixin', num);
                uni.setClipboardData({
                    data: num,
                    success: () => {
                        console.log('success');
                        plus.runtime.launchApplication(
                            { pname: 'com.tencent.mm', extra: { url: 'http://www.html5plus.org' } },
                            function(e) {
                                alert('Open system default browser failed: ' + e.message);
                            }
                        );
                        const subNVue = uni.getSubNVueById('showWeixin');
                        subNVue.hide('fade-in', 200);
                    },
                    fail: err => {
                        console.log('err', err);
                    }
                });
            }
        }
    };
    </script>
     
    <style scoped>
    .show-weixin {
        flex: 1;
        border-radius: 20rpx;
        background-color: #ffffff;
        flex-direction: column;
        align-items: center;
    }
    .sw-image {
        width: 90rpx;
        height: 90rpx;
        border-radius: 45rpx;
        margin-top: 56rpx;
    }
    .sw-button {
        width: 440rpx;
        height: 90rpx;
        margin-top: 40rpx;
        background-color: rgba(255, 140, 148, 1);
        border-radius: 45rpx;
        justify-content: center;
        align-items: center;
    }
    .swb-text {
        font-size: 30rpx;
        color: #ffffff;
    }
    .sw-remind {
        width: 520rpx;
        margin-top: 48rpx;
        flex-direction: row;
        flex-wrap: wrap;
    }
    .swr-image {
        width: 34rpx;
        height: 34rpx;
        margin-right: 10rpx;
    }
    .swr-text {
        font-size: 24rpx;
        color: rgba(153, 153, 153, 1);
    }
    </style>

相关页面引用

 

            // 把微信号写到粘贴板
            hdGetNum() {
                const { weChatNo, merchantImage } = this.audio;
                const subNVue = uni.getSubNVueById('showWeixin');
                subNVue.postMessage({
                    num: weChatNo,
                    imgUrl: `${this._API.fileUrl}${merchantImage}`
                });
                subNVue.show('fade-in', 250);
            },

常用uniapp插件

下拉刷新,可npm安装:https://ext.dcloud.net.cn/plugin?id=343

自定义头部:https://ext.dcloud.net.cn/plugin?id=974

图片裁剪:https://ext.dcloud.net.cn/plugin?id=1076

分享:https://ext.dcloud.net.cn/plugin?id=482
常用npm模块

时间日期格式转化 moment:http://momentjs.cn/docs/#/displaying/

表单校验 validator:https://www.npmjs.com/package/validator

猜你喜欢

转载自www.cnblogs.com/nlong/p/12344794.html