实践:给女朋友个性化定制应用-体重记录(一)

简介: 此系列的目的是帮助前端新人,熟悉现代前端工程化开发方式与相关技术的使用,普及一些通识内容

本文涉及内容


为提升阅读体验,文章将会分为多节发布,本节主要阐述前端部分


  • 初始化Vue3+Vite+TS项目
  • VantUI组件库引入
  • 移动端适配
  • 自定义组件开发
  • @vue/compiler-sfc
  • 彩色字体图标的使用


背景


女朋友天天都在念叨:"我又胖了,怎么不吃东西也没见轻"


为了记录每次体重数据的变化,就下载了记录体重的App,用了几个都不太满意(主要是不满意数据反映出的图表内容)


于是乎咱就拿出键盘⌨🖰就给她打造一个独一无二的


需求


长话短说:


  • 基本的体重记录(CRUD)
  • 多样化的数据统计报表
  • 反应每一次的变化
  • 最后一次与当天的第一次的比较
  • 指定时间区间里的变化
  • ...more


技术方案


明确了目标用户用户诉求后,接下来直接定技术方案

应用形式:H5(移动到Web应用)


前端


  • 框架:Vue3
  • 语言:TypeScript
  • 构建工具:Vite2
  • 组件:Vant UI
  • 网络:Axios
  • CSS预处理:Sass


后端


  • Node.js + TypeScript
  • 数据库:菲关系型数据库(MongoDB或云开发用文档数据库)


部署


均使用Serverless服务部署,性能好又便宜



概览


网络异常,图片无法展示
|


开发准备


项目初始化


直接使用搭建的ATQQ/vite-vue3-template模板初始化项目


网络异常,图片无法展示
|


引入Vant UI


添加依赖


yarn add vant@next


配置按需引入


// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import styleImport from 'vite-plugin-style-import'
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    styleImport({
      libs: [
        {
          libraryName: 'vant',
          esModule: true,
          resolveStyle: (name) => `vant/es/${name}/style`,
        },
      ],
    }),
  ]
})


// src/utils/vantUI.ts
import { App } from '@vue/runtime-core'
// 按需引入
import { Button } from 'vant'
const conponents = [Button]
export default function mountVantUI(app: App<Element>) {
  conponents.forEach((c) => {
    app.component(c.name, c)
  })
}


页面


一期预计4个页面:


  • 首页
  • 登录
  • 功能面板
  • 体重记录


快速建立好4个页面的模板


# src/pages/
├── 404           # 404
|  └── index.vue
├── dashboard     # 功能面板
|  └── index.vue
├── funcs
|  └── weight     # 体重记录
|     └── index.vue
├── home          # 首页
|  └── index.vue
└── login         # 登录页
   └── index.vue
directory: 6 file: 5


路由配置


页面确定后,配置一下页面路由


src/router/routes/index.ts


import { RouteRecordRaw } from 'vue-router'
import Home from '../../pages/home/index.vue'
const NotFind = () => import('../../pages/404/index.vue')
const Login = () => import('../../pages/login/index.vue')
const DashBoard = () => import('../../pages/dashboard/index.vue')
const Weight = () => import('../../pages/funcs/weight/index.vue')
const routes: RouteRecordRaw[] = [
  { path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFind },
  {
    path: '/',
    name: 'index',
    component: Home,
  },
  {
    path: '/login',
    name: 'login',
    component: Login,
  },
  {
    path: '/dashboard',
    name: 'dashboard',
    component: DashBoard,
  },
  {
    path: '/funs/weight',
    name: 'weight',
    component: Weight,
  },
]
export default routes


将顶层的router-view组件放在App.vue中

src/App.vue


<template>
  <div class="app">
    <router-view></router-view>
  </div>
</template>


移动端适配


首先在html模板中添加一句


<meta name="viewport" content="width=device-width, initial-scale=1.0" />


尺寸单位使用rem方案,设计稿按375来定


通过调研现有的响应式网站与模拟器中实测,尺寸主要由320,360,375,414四种,得出以下结果:


  • html根元素字体大小
  • 320:12px
  • 360:13.5px = 360/320*12
  • 375:14.0625px = 375/320*12
  • 414:沿用375方案


于是乎可以直接使用 媒体查询 处理单位的设置

App.vue中加入得出的如下代码:


<style>
@media screen and (min-width: 320px) {
  html {
    font-size: 12px;
  }
}
@media screen and (min-width: 360px) {
  html {
    font-size: 13.5px;
  }
}
@media screen and (min-width: 375px) {
  html {
    font-size: 14.0625px;
  }
}
</style>


注意:由于样式权重一样的情况下,会采用后定义的内容,所以大尺寸媒体查询代码的放在后面


TODO:补样式权重计算文章


不排除用户电脑访问应用的情况,为提升用户体验,将顶层容器标签固定为414px


App.vue中加入如下代码:


<style scoped>
.app {
  max-width: 414px;
  margin: 0 auto;
}
</style>


页面开发


准备工作基本完成后就开始糊页面


由于糊页面是个体力活儿,没有营养,文中只贴一些关键代码,完成代码,去仓库探索

页面使用@vue/compiler-sfc方案,开发提效,代码更直观


使用的渐变色来源:webgradients


首页



页面整体上只包含应用名简介导航登录3部分


<template>
  <div class="home">
    <h1 class="title">时光恋人</h1>
    <!-- 简介 -->
    <section class="introduce">
      <p v-for="(item, index) in introduces" :key="index">{{ item }}</p>
    </section>
    <section class="introduce">
      <p>
        <router-link to="/login">
          <van-button size="small" round :color="loginColor">点击体验</van-button>
        </router-link>
      </p>
    </section>
  </div>
</template>
<script lang="ts" setup>
import { reactive } from 'vue'
const introduces: string[] = reactive(['记录情侣之间', '日常生活趣事,生活足迹'])
const loginColor = 'linear-gradient(to right, #b8cbb8 0%, #b8cbb8 0%, #b465da 0%, #cf6cc9 33%, #ee609c 66%, #ee609c 100%)'
</script>


登录页



避免繁琐的注册流程,直接使用短信验证码登录方案


这个页面开发了一个自定义的 Input 组件


效果如下,包含icon输入区域输入提示注意提示4部分内容


网络异常,图片无法展示
|



Dom结构如下


<template>
  <div class="under-input">
    <van-icon class="icon" v-if="icon" :name="icon" />
    <input
      :maxlength="maxLength"
      :placeholder="placeholder"
      :type="type"
      :value="modelValue"
      @input="handleInput"
    />
  </div>
  <p v-if="tips" class="tips">
    {{ tips }}
  </p>
</template>


输入内容使用简单的正则进行校验


// 手机号
export const rMobile = /^[1]\d{10}$/
// 验证码
export const rCode = /\d{4}/


功能页



调研了一些类似的应用,最终选择采用卡片的形式展现各个功能入口

卡片组件主要包含功能介绍彩色图标两部分,效果如下


网络异常,图片无法展示
|


Dom结构如下:


<template>
  <div
    class="fun-card"
    :class="{
      disabled,
    }"
  >
    <div>
      <h1 class="title">{{ title }}</h1>
    </div>
    <span v-if="icon" :class="[icon]" class="iconfont icon"></span>
    <!-- lock -->
    <div v-if="disabled" class="lock">
      <span class="icon-lockclosed iconfont"> </span>
    </div>
  </div>
</template>


彩色字体图标



只需要简单的在模板中引入css资源,使用的时候直接书写class即可


<!-- index.html -->
<link rel="stylesheet" href="//at.alicdn.com/t/font_2609471_9womj4g1e15.css">


<!-- 使用图标 -->
<span class="icon-lockclosed iconfont"> </span>


本期效果


网络异常,图片无法展示
|



资料汇总



相关文章
|
数据挖掘 定位技术
男性多项身体维度数据探索
男性多项身体维度数据探索
336 0
|
2月前
|
搜索推荐 Java API
打造个性化天气应用:从概念到实现
【8月更文挑战第51天】在这篇文章中,我们将一起探索如何将一个天气应用的概念转化为现实。我们将深入讨论移动应用开发的核心概念,包括设计思路、技术选型、以及实际编码过程。通过一个简单的天气应用示例,你将学会如何利用现代移动开发工具和框架来创建自己的应用。无论你是编程新手还是有一定经验的开发者,这篇文章都将为你提供一条清晰的道路,帮助你理解并实践移动应用开发。
62 17
|
4月前
|
搜索推荐 C语言
青年歌手大赛:实时评分统计与分析程序设计
青年歌手大赛评分系统:C语言实现平均分计算(剔除最高与最低分) 在青年歌手大赛中,为了确保评分的公平性和准确性,本程序采用C语言设计了一套评分统计方案。该方案的核心功能是在收集10位评委对一位歌手的评分后,自动剔除一个最高分和一个最低分,然后计算剩余8个有效评分的平均值。
|
4月前
|
存储 C语言 索引
【实战编程】学生信息管理系统:一键实现数据插入、智能排序、精准查询与成绩统计(附完整源码,即学即用!)
结构体数组是C语言中一种复合数据类型,它结合了结构体的灵活性和数组的有序集合特性,允许你定义一组具有相同结构的数据项。结构体定义了一组不同数据类型的变量集合,而结构体数组则是这种结构的连续内存块,每个元素都是该结构类型的实例。这种方式特别适合管理具有相似属性的对象集合,如学生信息、员工记录等。
|
4月前
|
数据可视化 数据挖掘
问卷填写率优化:吸引更多受访者的秘诀
**摘要:** 提升问卷填写率的关键在于设计简洁的问卷、选择恰当的分发渠道和设置激励措施。确保问题清晰无歧义,视觉呈现吸引人。利用社交媒体、定时发送及鼓励分享来扩大覆盖。提供匹配受众兴趣的奖励,如小礼品或服务优惠,强调参与的公益价值,以及提供即时反馈以增强参与感。理解和尊重目标受众,以提高数据收集的效率和质量。
46 0
|
6月前
|
机器学习/深度学习 算法 数据可视化
数据报告分享|WEKA贝叶斯网络挖掘学校在校人数影响因素数据分类模型
数据报告分享|WEKA贝叶斯网络挖掘学校在校人数影响因素数据分类模型
|
NoSQL 定位技术 数据库
GIS如何分析台风影响范围和受灾人数
GIS如何分析台风影响范围和受灾人数
152 0
|
机器学习/深度学习 搜索推荐
《蘑菇街广告的排序:从历史数据学习到个性化强化学习》电子版地址
蘑菇街广告的排序:从历史数据学习到个性化强化学习
69 0
《蘑菇街广告的排序:从历史数据学习到个性化强化学习》电子版地址
|
机器学习/深度学习 数据采集 人工智能
『航班乘客满意度』场景数据分析建模与业务归因解释 ⛵
本文结合航空出行的场景,使用机器学习建模,详细分析了航班乘客满意度的影响因素:机上Wi-Fi服务、在线登机、机上娱乐质量、餐饮、座椅舒适度、机舱清洁度和腿部空间等。
449 0
『航班乘客满意度』场景数据分析建模与业务归因解释 ⛵
|
分布式计算 算法 数据可视化
房源画像实验演示(上)|学习笔记
快速学习房源画像实验演示(上)
512 0
房源画像实验演示(上)|学习笔记