如何从零开始拆解uni-app开发的vue项目(一)

uni-app项目分析:

背景:最近接手一个前同事留下的半拉子项目,出拿过来觉得很简单;当我看到app.vue的时候很确定是vue项目,心里不怎么慌,果断安装node.js,然后就去npm ;安装VS code,事实并不是我期盼的那样,或者说根本就不能运行。

报错:应用vs code打开文件,输入命令npm run dev,项目根本就没有运行,一直显示缺少一个package.json文件。

最后由于进度问题,只能去找前同事,听他说前端这几年变化挺大,项目可能适用的是其他编译器,再三辗转确定是HBuilder X。 

一番操作之后,我下载了HBuilder X之后,运行项目其实也不是很顺利,因为这个编译器虽然是免安装的,但是运行之后就会提示缺少运行的插件,还好都是无脑安装。

项目运行后才发向,项目根本没有后台服务,当时心中有一万只羊驼一闪而过;这样的项目怎么还说是成功运行的?不管三七二十一,我先利用HBuilderX的内置管理器进行运行,登录的界面如下:

为了进一步弄清uni.app开发程序的架构,首先打开APP.vue希望从这里查到一点蛛丝马迹,如下图所示:

上图可以看到这个文件只有style样式和默认的Script方法;于是乎我只能从pages.json

这里的json文件都是一些路径组合,从 注解中了解到uni.app开发vue程序的启动格式:

//pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages

之后点击完对应的参考了解到:

 pages.json 页面路由

pages.json 文件用来对 uni-app 进行全局配置,决定页面文件的路径、窗口样式、原生的导航栏、底部的原生tabbar 等。

它类似微信小程序中app.json页面管理部分。注意定位权限申请等原属于app.json的内容,在uni-app中是在manifest中配置。

 以下是一个包含了所有配置选项的 pages.json :

{
	"pages": [{
		"path": "pages/component/index",
		"style": {
			"navigationBarTitleText": "组件"
		}
	}, {
		"path": "pages/API/index",
		"style": {
			"navigationBarTitleText": "接口"
		}
	}, {
		"path": "pages/component/view/index",
		"style": {
			"navigationBarTitleText": "view"
		}
	}],
	"condition": { //模式配置,仅开发期间生效
		"current": 0, //当前激活的模式(list 的索引项)
		"list": [{
			"name": "test", //模式名称
			"path": "pages/component/view/index" //启动页面,必选
		}]
	},
	"globalStyle": {
		"navigationBarTextStyle": "black",
		"navigationBarTitleText": "演示",
		"navigationBarBackgroundColor": "#F8F8F8",
		"backgroundColor": "#F8F8F8",
		"usingComponents":{
			"collapse-tree-item":"/components/collapse-tree-item"
		},
		"renderingMode": "seperated", // 仅微信小程序,webrtc 无法正常时尝试强制关闭同层渲染
		"pageOrientation": "portrait", //横屏配置,全局屏幕旋转设置(仅 APP/微信/QQ小程序),支持 auto / portrait / landscape
		"rpxCalcMaxDeviceWidth": 960,
		"rpxCalcBaseDeviceWidth": 375,
		"rpxCalcIncludeWidth": 750
	},
	"tabBar": {
		"color": "#7A7E83",
		"selectedColor": "#3cc51f",
		"borderStyle": "black",
		"backgroundColor": "#ffffff",
		"height": "50px",
		"fontSize": "10px",
		"iconWidth": "24px",
		"spacing": "3px",
    	"iconfontSrc":"static/iconfont.ttf", // app tabbar 字体.ttf文件路径 app 3.4.4+
		"list": [{
			"pagePath": "pages/component/index",
			"iconPath": "static/image/icon_component.png",
			"selectedIconPath": "static/image/icon_component_HL.png",
			"text": "组件",
      		"iconfont": { // 优先级高于 iconPath,该属性依赖 tabbar 根节点的 iconfontSrc
       			"text": "\ue102",
        		"selectedText": "\ue103",
        		"fontSize": "17px",
        		"color": "#000000",
        		"selectedColor": "#0000ff"
      		}
		}, {
			"pagePath": "pages/API/index",
			"iconPath": "static/image/icon_API.png",
			"selectedIconPath": "static/image/icon_API_HL.png",
			"text": "接口"
		}],
		"midButton": {
			"width": "80px",
			"height": "50px",
			"text": "文字",
			"iconPath": "static/image/midButton_iconPath.png",
			"iconWidth": "24px",
			"backgroundImage": "static/image/midButton_backgroundImage.png"
		}
	},
  "easycom": {
    "autoscan": true, //是否自动扫描组件
    "custom": {//自定义扫描规则
      "^uni-(.*)": "@/components/uni-$1.vue"
    }
  },
  "topWindow": {
    "path": "responsive/top-window.vue",
    "style": {
      "height": "44px"
    }
  },
  "leftWindow": {
    "path": "responsive/left-window.vue",
    "style": {
      "width": "300px"
    }
  },
  "rightWindow": {
    "path": "responsive/right-window.vue",
    "style": {
      "width": "300px"
    },
    "matchMedia": {
      "minWidth": 768
    }
  }
}

 接下来首先打开登录页面pages/index/index.vue页面,我们近一步分析:首先看一下Template代码:

<template>
    <view class="main">

        <!-- 登录框 -->
        <view class="loginBox"> 
            <view class="vv"></view>
            
            <view class="logoImgBox">
                <image :src="loginImage" mode=""></image>
            </view>
            
            <view class="loginInptu">
                <input type="text"  class="username" value="" placeholder="请输入用户名" maxlength="11" @input="phoneInput"/>
            </view>
            <view class="loginInptu" >
                <input type="password" class="password" value="" placeholder="请输入密码" maxlength="16" @input="passwordInpur"/>
            </view>
                            
            <view class="loginUp" @click="login">
                <image src="../../static/denglu.png" mode=""></image>
            </view>
            
        </view>        
    </view>
</template>

由上可以看到Template中可以看到:

有两个输入框input,利用不同的class设置是文本输入框还是密码输入框,并且定义了默认的placeholder提示信息,以及对应的数据长度maxlength;

一个图标形式的登录按钮,对应一个@Click的"login"事件。

从上有的template中我们还可以看到一个现场就是template中的所有的视图元素都是包裹在<view></View>标签中,这应该时uni.app的一种书写格式。

最近开了uni-app的官方文档了解到<view></View>相当于html中的<div></div>,意思应该同<div> 元素 (或 HTML 文档分区元素) 是一个通用型的流内容容器,在不使用CSS的情况下,其对内容或布局没有任何影响。此部分内容更新于2024-04-05.

接着我们对login函数进行分析:

<script>
    export default {
        data() {
            return {
                loginMode: 1,
                usernameType:"text",
                codeBut:"获取验证码",
                loginImage:"../../static/logo.png",
                codeClick:true,
                phone:"",
                password:"",
                code:"",
                username:"",
                loginres:0,
            }
        },
        onLoad() {
            
        },
        methods: {
            gotoMenu(){
                    uni.navigateTo({
                    url:"/pages/menu/menu/menu"
            
                    })
                },
            login()
            {
                
                uni.request({
                 url: 'http://127.0.0.1:5034/Login/Login2',
                 method: 'GET',      
                data: { g_UserID: this.username, g_Password: this.password},
                 success: (res) => {  
                      console.log('数据:'+this.username+this.password);  
                      //console.log(res.data);
                      var loginres = res.data.loginres;
                      console.log('loginres:'+loginres);  
                      //var _that = this
                      if(loginres == 1){
                          //console.log(res.data)
                          uni.showToast({
                              title: '登录成功',
                              icon: 'none',
                              duration:2000,
                            
                          });
                        
                        this.$globals.us = this.username;
                        
                        
                        uni.navigateTo({
                        url:"/pages/menu/menu/menu"
       
                        });
                        this.loginres = 0;
                        }
                        else if(loginres != 1){
                            uni.showToast({
                                title: '登录失败',
                                icon: 'none',
                                duration:2000
                            });
                            this.loginres = 0;
                        };
                 },  
                 fail: () => {console.log('登录失败'+this.username+this.password);},  
                 complete: () => {console.log('完成');}  
                });  
            },
        }
    }
</script>

在分析login方法时我们首先需要看一下Script怎么定义的数据:

 export default {
        data() {
            return {
                loginMode: 1,
                usernameType:"text",
                codeBut:"获取验证码",
                loginImage:"../../static/logo.png",
                codeClick:true,
                phone:"",
                password:"",
                code:"",
                username:"",
                loginres:0,
            }
        }

这个方法中我们可以看到所有在界面中会适用的参数及类型。

在来看一下method:{}中的方法:

methods: {
            gotoMenu(){
                    uni.navigateTo({
                    url:"/pages/menu/menu/menu"
            
                    })
                },
            login()
            {
                
                uni.request({
                 url: 'http://127.0.0.1:5034/Login/Login2',
                 method: 'GET',      
                data: { g_UserID: this.username, g_Password: this.password},
                 success: (res) => {  
                      console.log('数据:'+this.username+this.password);  
                      //console.log(res.data);
                      var loginres = res.data.loginres;
                      console.log('loginres:'+loginres);  
                      //var _that = this
                      if(loginres == 1){
                          //console.log(res.data)
                          uni.showToast({
                              title: '登录成功',
                              icon: 'none',
                              duration:2000,
                            
                          });
                        
                        this.$globals.us = this.username;
                        
                        
                        uni.navigateTo({
                        url:"/pages/menu/menu/menu"
       
                        });
                        this.loginres = 0;
                        }
                        else if(loginres != 1){
                            uni.showToast({
                                title: '登录失败',
                                icon: 'none',
                                duration:2000
                            });
                            this.loginres = 0;
                        };
                 },  
                 fail: () => {console.log('登录失败'+this.username+this.password);},  
                 complete: () => {console.log('完成');}  
                });  
            },
        }

method的中有两个方法:

 gotoMenu(){
                    uni.navigateTo({
                    url:"/pages/menu/menu/menu"
            
                    })
                },

这个方法从名称中可以看到是一个跳转功能,跳转的页面是项目下/pages/menu/menu/menu页面:

uni.request({
                 url: 'http://127.0.0.1:5034/Login/Login2',
                 method: 'GET',      
                data: { g_UserID: this.username, g_Password: this.password},
                 success: (res) => {  
                      console.log('数据:'+this.username+this.password);  
                      //console.log(res.data);
                      var loginres = res.data.loginres;
                      console.log('loginres:'+loginres);  
                      //var _that = this
                      if(loginres == 1){
                          //console.log(res.data)
                          uni.showToast({
                              title: '登录成功',
                              icon: 'none',
                              duration:2000,
                            
                          });
                        
                        this.$globals.us = this.username;
                        
                        
                        uni.navigateTo({
                        url:"/pages/menu/menu/menu"
       
                        });
                        this.loginres = 0;
                        }
                        else if(loginres != 1){
                            uni.showToast({
                                title: '登录失败',
                                icon: 'none',
                                duration:2000
                            });
                            this.loginres = 0;
                        };
                 },  
                 fail: () => {console.log('登录失败'+this.username+this.password);},  
                 complete: () => {console.log('完成');}  
                });  
            },

另一个方法是request一个路径,data: { g_UserID: this.username, g_Password: this.password}是传入的对应参数,可以看到:

success: (res) => {  
                      console.log('数据:'+this.username+this.password);  
                      //console.log(res.data);
                      var loginres = res.data.loginres;
                      console.log('loginres:'+loginres);  
                      //var _that = this
                      if(loginres == 1){
                          //console.log(res.data)
                          uni.showToast({
                              title: '登录成功',
                              icon: 'none',
                              duration:2000,
                            
                          });
                        
                        this.$globals.us = this.username;
                        
                        
                        uni.navigateTo({
                        url:"/pages/menu/menu/menu"
       
                        });
                        this.loginres = 0;
                        }
                        else if(loginres != 1){
                            uni.showToast({
                                title: '登录失败',
                                icon: 'none',
                                duration:2000
                            });
                            this.loginres = 0;
                        };
                 },

这段逻辑意思是登录成功后,首先在控制台打印调用接口时的参数,在根据 res.data.loginres的值判断进行弹窗显示,弹窗部分的代码:

 uni.showToast({
                              title: '登录成功',
                              icon: 'none',
                              duration:2000,
                          });

接着是this.$globals.us = this.username;别看只有一句代码,这句的意思是将用户名放入到global中,这个后期可做全局对象处理页面之间的权限验证等功能,按住alt+鼠标左键可以看到,对应的文件config.js

 接着是登录成功后跳转对应的menu菜单页面:

uni.navigateTo({
                        url:"/pages/menu/menu/menu"
       
                        });

 因此我按照前台数据类型,写了一个登录成功的方法,先看看菜单栏的功能,后台代码如下:

成功跳转后的功能如图:

码字不易,如果您觉的我的文章对您有帮助的话,建议您在经济能力之内慷慨打赏一元给我买瓶水, 这将是我下一步继续书写本题目的动力;如果您囊肿羞涩也没有关系,希望您点个关注,写点评论;您的支持将是我创作之路上的无线动力;青山依旧绿水长流,希望我们下期来能再见。

  • 30
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

A_nanda

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值