- A+
前言
- 经过前面的文章介绍,基本上 UniApp 的内容就介绍完毕了
- 那么从本文开始,我们就开始进行一个项目的实战
- 这次做的项目是苹果计算器,这个项目的难度不是很大,但是也不是很简单,适合练手
创建项目
- 打开 HBuilderX,点击左上角
文件
->新建
->项目
:
搭建基本布局
项目创建完毕之后,首先来分析一下苹果计算器的整体布局结构,分为一上一下如下图:
- 上面的部分主要是显示计算结果的,下面的部分主要是显示计算器的按键
搭建上半部分布局
更改 index.vue 的内容如下:
<template> <view class="content"> <view class="result-view"></view> <view class="btns-view"></view> </view> </template> <script> export default { data() { return { } }, onLoad() { }, methods: { } } </script> <style lang="scss"> .content { width: 100%; height: 100%; background-color: black; padding-left: 30rpx; padding-right: 30rpx; box-sizing: border-box; } </style>
运行一下,看看效果发现,背景并没有是黑色,而是白色。
注意点:在 UniApp 中所有的元素都是放在 page 中的, 所以想要全屏,可以直接设置 page 的样式
我们需要在 App.vue
中修改一下:
<style lang="scss"> /*每个页面公共css */ page { width: 100%; height: 100%; } </style>
这么一改,就可以了,效果如下:
在改一下 index 的 navigationBarTitleText 为 计算器
,更改 pages.json 如下:
"pages": [{ "path": "pages/index/index", "style": { "navigationBarTitleText": "计算器" } }],
基本上大致的容器布局代码就写完了,再继续来完善一下一上一下的布局,更改样式:
.result-view { width: 100%; height: 35%; background: red; } .btns-view { width: 100%; height: 65%; background: blue; }
我这里使用的是 scss 进行编写,这两个类样式是编写在 .content
中的,效果如下:
一上一下区分完毕了,先来完善一下上面的部分,这个部分主要是显示计算结果的,我们需要在这个部分中放置一个文本框,用来显示计算结果,更改代码如下:
<template> <view class="content"> <view class="result-view"> <input class="result-box" type="text" v-model="showValue" disabled="true" style="font-size: 180rpx;" /> </view> <view class="btns-view"></view> </view> </template> <script> export default { data() { return { showValue: 0 } }, onLoad() { }, methods: { } } </script>
- 这里使用的是 input 标签,因为 input 标签可以设置 disabled 属性,这样就可以禁止用户输入了
- 然后我们给 input 设置了一个 v-model,这样就可以实现双向绑定了
- 然后我们给 input 设置了一个 style,这样就可以设置字体大小了
- 给 input 设置了一个 class,这样就可以设置样式了
.result-box
的样式如下:
.result-box { height: 30%; text-align: right; color: white; }
效果如下:
但是呢,我发现位置不对,这里我使用子绝父相的方式来进行布局,更改代码如下:
.result-view { width: 100%; height: 35%; background: red; position: relative; .result-box { height: 30%; text-align: right; color: white; position: absolute; left: 0; bottom: 0; } }
搭建下半部分布局
上方的内容先到此为止,接下来完善一下下方的内容,通过我的观察,我发现是有规律的唯一没有规律的就是最后一行,这一行我们先不看,我先布局,不符合的地方我在单独处理,废话不多说我直接上代码。
- 首先在下方布局代码当中,添加一个 view
<view class="btn-radius"></view>
在这个 view 容器当中我添加了一个 class 用来设置圆角的,因为每个按钮都是圆角的,好,样式代码我先不编写,继续分析,那么这么多的按钮难道都是 c + v 去复制出来吧,不可能,所以我这里采用循环的方式来进行创建即可,这里我就直接贴代码:
buttons: [{ text: 'AC', class: 'ft-color bg-gray ml-zero', func: 'operator', params: 'clear', }, { text: '+/-', class: 'ft-color bg-gray', func: 'operator', params: 'opposite', }, { text: '%', class: 'ft-color bg-gray', func: 'operator', params: 'percent', }, { text: '÷', class: 'bg-orange', func: 'operator', params: 'divide', }, { text: '7', class: 'bg-darkgray ml-zero', func: 'inputText', params: '7', }, { text: '8', class: 'bg-darkgray', func: 'inputText', params: '8', }, { text: '9', class: 'bg-darkgray', func: 'inputText', params: '9', }, { text: '×', class: 'bg-orange', func: 'operator', params: 'multiply', }, { text: '4', class: 'bg-darkgray ml-zero', func: 'inputText', params: '4', }, { text: '5', class: 'bg-darkgray', func: 'inputText', params: '5', }, { text: '6', class: 'bg-darkgray', func: 'inputText', params: '6', }, { text: '-', class: 'bg-orange', func: 'operator', params: 'minus', }, { text: '1', class: 'bg-darkgray ml-zero', func: 'inputText', params: '1', }, { text: '2', class: ' bg-darkgray', func: 'inputText', params: '2', }, { text: '3', class: ' bg-darkgray', func: 'inputText', params: '3', }, { text: '+', class: 'bg-orange', func: 'operator', params: 'plus', }, { text: '0', class: 'btn-size2 bg-darkgray ml-zero', func: 'inputText', params: '0', }, { text: '.', class: 'bg-darkgray', func: 'inputText', params: '.', }, { text: '=', class: 'bg-orange', func: 'operator', params: 'result', } ]
- 这里我定义了一个 buttons 数组,里面存放的是每个按钮的信息
- text:按钮的文本
- class:按钮的样式
- func:按钮的功能
- params:按钮的参数
这个是定义在 data 中的,然后我们需要在页面中进行循环,这里我使用的是 v-for,代码如下:
<view class="btns-view"> <view class="btn-radius" v-for="item in buttons" :key="item.text" :class="[item.class]" @click="operate(item)">{{item.text}}</view> </view>
- 这里我使用的是 v-for 来进行循环
- 然后我给每个按钮添加了一个 class,这个 class 是从 buttons 数组中获取的,动态样式
- 然后我给每个按钮添加了一个点击事件,这个点击事件调用 methods 中的 operate 方法, 传入的参数是当前按钮的信息
- 然后我给每个按钮添加了一个文本,这个文本也是从 buttons 数组中获取的,动态文本
- 然后我给每个按钮添加了一个 key,这个 key 是当前按钮的文本,这个 key 确定了每个按钮的唯一性
运行一下,效果如下:
内容都显示出来了,现在只需要去编写样式即可, 我这里采用 flex 布局,代码如下:
.btns-view { width: 100%; height: 65%; background: blue; display: flex; flex-wrap: wrap; justify-content: space-evenly; .btn-radius { margin-left: 30rpx; width: 150rpx; height: 150rpx; line-height: 150rpx; border-radius: 50%; text-align: center; font-size: 60rpx; color: white; } }
运行,效果如下图,但是发现还是有问题的:
这个问题呢,我已经想到了,之前不是在 data 中定义了一个 buttons 数组吗,这个数组中存放的是每个按钮的信息,在信息中有一个 class 属性里面有一个 ml-zero
这个是用来设置按钮的左边距的,凡是添加了这个属性就代表着没有左边距,直接上样式代码:
.ml-zero { margin-left: 0; }
运行,效果如下,可以看到已经非常接近苹果计算器的样式了:
到这里基本上已经完成了大部分的布局了,接下来将对应字体的样式写写本文的内容就大致完毕了,样式代码如下:
- ft-color:字体颜色
.ft-color { color: black; }
- bg-orange:橙色背景
.bg-orange { background-color: orange; }
- bg-darkgray:深灰色背景
.bg-darkgray { background: gray; }
- bg-gray:灰色背景
.bg-gray { background-color: darkgrey; }
- btn-size2:按钮大小
.btn-size2 { width: 300rpx; border-radius: 75rpx; }
最后将不用的样式清理掉,删除 .result-view
中的 background: red;
和 .btns-view
中的 background: blue;
。
最后我再附上一张最后的效果图:
End
- 如果你有任何问题或建议,欢迎在下方留言,我会尽快回复
- 如果你觉得本文对你有帮助,欢迎点赞、收藏,你的支持是我写作的最大动力