前端开发流程与技术选型

目录

一、简介

二、前端职责

三、开发步骤

四、技术选型

五、页面展示


一、简介

做一个网站时,能看到的一切都是前端程序员的工作,负责网页或者app的结构、样式、用户操作网站时的事件逻辑(比如点击一个按钮)。

二、前端职责

前端程序员工作职责:

        ①和产品经理沟通需求,按照产品经理要求完成相应功能。

        ②和UI设计师沟通样式,按照UI设计图还原样式。

        ③和后端协作,对接后端api接口进行调试,进行登录验证,以及根据用户操作数据的增删改查。

三、开发步骤

从0-1开发一个前端项目,我们需要经历11个步骤。

具体步骤有:

其中有几个步骤详细说明一下:

四、技术选型

前端目前主要使用的技术有:

        ①前端运行环境:Node.js(npm是Node.js的官方包管理工具)

        ②框架:Vue、React、Uniapp、微信原生小程序框架、bootstrap、Angular等

        ③结构:HTML

        ④样式:CSS、CSS预处理器(Scss、Less、Stylus)

        ⑤逻辑:JavaScript(ECMAScript、Bom、Dom)

        ⑥代码分布式存储工具:Git、远程库(Gitee、Github、阿里云、腾讯云)

        ⑦打包工具:Webpack、Vite

        ⑧调试工具:Chrome DevTools(谷歌浏览器调试工具,可以调试手机端电脑端)、微信开发者工具(用来调试微信小程序、企业微信小程序、小游戏)

        ⑨兼容性:电脑端(各种尺寸的电脑、各种厂家的浏览器的样式和方法)、手机端(Android、iOS、Harmony等手机系统的差异) 、响应式开发

        ⑩浏览器:谷歌(google chrome)、360、火狐(Firefox)、Microsoft Edge、Safari

五、页面展示

这是一个Web前端页面:

使用Node.js环境、vue框架、Less(CSS预处理器)、谷歌浏览器展示。

这是一个微信小程序页面:

使用Node.js环境、Uniapp框架(vue3版本)、Scss(CSS预处理器)、微信开发者工具展示。

这是相应前端代码:

<template>
	<!-- 左右滑动切换月份 -->
	<view @touchstart="handleTouchStart" @touchend="handleTouchEnd">
		<view class="titleBox">
			<view class="title">{{ currentYear }}.{{ currentMonth }}</view>
		</view>
		<view class="week">
			<view v-for="(item, index) in week" :key="index">{{ item }}</view>
		</view>
		<!-- 日历 -->
		<view class="calendarbBox">
			<view class="singleDay" v-for="(item, index) in state.currentMonthAllDate" :key="index" @tap="selectedDate(item.date)">
				<!-- 不是当前月日期 class="dayTextB",如果选中则跳转至所属月份-->
				<text class="dayTextB" v-if="item.month != 'current'">{{ item.number }}</text>
				<!-- 没有选中当前日期class="dayText",选中当前日期class="dayTextA"-->
				<text class="dayTextA" v-if="item.month == 'current' && String(state.currentToday) == String(item.date)">{{ item.number }}</text>
				<text class="dayText" v-if="item.month == 'current' && String(state.currentToday) != String(item.date)">{{ item.number }}</text>
				<!-- 当天有计划+当前日期没有选中的标志 -->
				<view class="point" v-if="item.isPlan"></view>
				<!-- 当前日期选中的标志 -->
				<view class="selectedDayBGColor" v-if="String(state.currentToday) == String(item.date)"></view>
				<!-- 当天有计划+当前日期选中的标志 -->
				<view class="pointA" v-if="String(state.currentToday) == String(item.date) && item.isPlan"></view>
			</view>
		</view>
		<!-- 箭头 ,箭头向下展示周,箭头向上展示月-->
		<view class="arrowBox">
			<view class="arrowButtonRegion" @tap="changeShowWeekOrMonth">周/月</view>
		</view>
	</view>
</template>
 
<script setup>
 
import { reactive, toRefs, computed, onMounted, ref } from 'vue';
import { useStore } from 'vuex';
import { onLoad, onHide } from '@dcloudio/uni-app';
 
const store = useStore();
const state = reactive({
	week: ['日', '一', '二', '三', '四', '五', '六'],
	currentYear: '',
	currentMonth: '',
	currentToday: '',
	// 0周日,1周一
	monthFirstDayCurrentWeek: '',
	monthFinallyDayCurrentWeek: '',
	//currentMonthAllDate里面是一个一个的对象 ,对象属性number当前日期,isPlan当天是否有计划,month是否是当前月里面的日期,因为要显示不同的样式。还以根据需要在添加其他属性。
	currentMonthAllDate: [],
	lastMonthDateNumber: 0,
	nextMonthDateNumber: 0,
	// showMonthOrWeek为true,代表显示周,false显示月
	showMonthOrWeek: true,
	currentTodayDate: '',
	initialX: '',
	currentMonthNum: ''
});
const {
	currentMonthNum,
	initialX,
	currentTodayDate,
	showMonthOrWeek,
	lastMonthDateNumber,
	nextMonthDateNumber,
	currentMonthAllDate,
	week,
	currentMonth,
	currentYear,
	currentToday,
	monthFirstDayCurrentWeek,
	monthFinallyDayCurrentWeek
} = toRefs(state);
 
// 今天凌晨
state.currentTodayDate = new Date(new Date(new Date().toLocaleDateString()).getTime());
 
/**
 * 记录手指触碰初始位置
 */
const handleTouchStart = (event) => {
	state.initialX = event.changedTouches[0].clientX;
};
 
/**
 * 左右滑动事件
 */
const handleTouchEnd = (event, index) => {
	const currentX = event.changedTouches[0].clientX;
	if (currentX - state.initialX > 20) {
		//往右滑动,上个月
		state.currentTodayDate = state.currentMonth == 1 ? new Date(`${state.currentYear - 1}/12/1`) : new Date(`${state.currentYear}/${state.currentMonthNum - 1}/1`);
		getAllDatesOfCurrentMonth(state.currentTodayDate);
		return;
	}
	if (state.initialX - currentX > 20) {
		// 往左滑动,下个月
		state.currentTodayDate = state.currentMonth == 12 ? new Date(`${state.currentYear + 1}/1/1`) : new Date(`${state.currentYear}/${state.currentMonthNum + 1}/1`);
		getAllDatesOfCurrentMonth(state.currentTodayDate);
		return;
	}
};
 
/**
 * 选中哪天
 */
const selectedDate = (date) => {
	state.currentTodayDate = date;
	getAllDatesOfCurrentMonth(state.currentTodayDate);
	// 下面去后端请求计划数据,并展示
};
 
/**
 * 切换显示周还是月
 */
const changeShowWeekOrMonth = () => {
	state.showMonthOrWeek = !state.showMonthOrWeek;
	getAllDatesOfCurrentMonth(state.currentTodayDate);
};
 
/**
 * 得到当前月份/当前周的所有日期,dateData某天日期
 */
const getAllDatesOfCurrentMonth = (dateData) => {
	state.currentMonthAllDate = [];
	const today = new Date(dateData);
	state.currentToday = today;
	state.currentYear = today.getFullYear();
	state.currentMonthNum = today.getMonth() + 1;
	if (today.getMonth() + 1 < 10) {
		state.currentMonth = '0' + (today.getMonth() + 1);
	} else {
		state.currentMonth = today.getMonth() + 1;
	}
	// 上个月总天数
	const lastMonth = new Date(today.getFullYear(), today.getMonth() - 1, 1);
	state.lastMonthDateNumber = new Date(lastMonth.getFullYear(), lastMonth.getMonth() + 1, 0).getDate();
	// 下个月总天数
	const nextMonth = new Date(today.getFullYear(), today.getMonth() + 1, 1);
	state.nextMonthDateNumber = new Date(nextMonth.getFullYear(), nextMonth.getMonth() + 1, 0).getDate();
	const dates = [];
	// 用if,else判断显示周还是月
	if (state.showMonthOrWeek) {
		// 显示当前选中日期所在周
		let day = today.getDay();
		let startDate = new Date(today.getFullYear(), today.getMonth(), today.getDate() - day);
		let endDate = new Date(today.getFullYear(), today.getMonth(), today.getDate() - day + 6);
		let currentMonthTwo = today.getMonth() + 1;
		for (let i = startDate; i <= endDate; ) {
			let monthFlag = '';
			if (new Date(i).getMonth() + 1 == currentMonthTwo) {
				monthFlag = 'current';
			} else if (new Date(i).getMonth() + 1 > currentMonthTwo) {
				monthFlag = 'last';
			} else {
				monthFlag = 'next';
			}
			dates.push(new Date(i));
			state.currentMonthAllDate.push({ number: i.getDate(), month: monthFlag, date: new Date(i) });
			i.setDate(i.getDate() + 1);
		}
	} else {
		// 显示当前选中日期所在月
		const firstDayOfMonth = new Date(today.getFullYear(), today.getMonth(), 1);
		const lastDayOfMonth = new Date(today.getFullYear(), today.getMonth() + 1, 0);
		state.monthFirstDayCurrentWeek = firstDayOfMonth.getDay();
		state.monthFinallyDayCurrentWeek = lastDayOfMonth.getDay();
		// 补充上个月显示在本月的天数,例如5.1是周三,则周日周一周二显示上个月
		if (state.monthFirstDayCurrentWeek != 0) {
			// 判断上个月是不是上一年
			let isLastYearNumber = lastMonth.getMonth() + 1 == 12 ? 1 : 0;
			for (let i = 0; i < state.monthFirstDayCurrentWeek; i++) {
				state.currentMonthAllDate.push({
					number: state.lastMonthDateNumber - state.monthFirstDayCurrentWeek + 1,
					month: 'last',
					date: `${state.currentYear - isLastYearNumber}/${lastMonth.getMonth() + 1}/${state.lastMonthDateNumber - state.monthFirstDayCurrentWeek + 1}`
				});
				state.lastMonthDateNumber++;
			}
		}
		for (let i = firstDayOfMonth; i <= lastDayOfMonth; ) {
			dates.push(new Date(i));
			state.currentMonthAllDate.push({ number: dates.length, month: 'current', date: new Date(i) });
			i.setDate(i.getDate() + 1);
		}
		if (state.monthFinallyDayCurrentWeek != 6) {
			// 判断下个月是不是下一年
			let yearNumber = nextMonth.getMonth() + 1 == 1 ? 1 : 0;
			for (let i = 0; i < 6 - state.monthFinallyDayCurrentWeek; i++) {
				state.currentMonthAllDate.push({ number: i + 1, month: 'next', date: `${state.currentYear + yearNumber}/${nextMonth.getMonth() + 1}/${i + 1}` });
			}
		}
	}
	return dates;
};
getAllDatesOfCurrentMonth(state.currentTodayDate);
 
// 可删除,做了几个假数据,假装几天有计划的,isPlan为true代表当天有计划。
state.currentMonthAllDate[2].isPlan = true;
state.currentMonthAllDate[4].isPlan = true;
state.currentMonthAllDate[0].isPlan = true;
</script>
 
<style scoped lang="scss">
.calendarbBox {
	width: 735rpx;
	margin-left: 7.5rpx;
	display: flex;
	justify-content: space-around;
	flex-wrap: wrap;
	.singleDay {
		width: 105rpx;
		height: 87rpx;
		line-height: 87rpx;
		color: #333;
		font-size: 32rpx;
		font-weight: bold;
		text-align: center;
		position: relative;
		.dayText {
			position: relative;
			z-index: 9;
		}
		.dayTextA {
			position: relative;
			z-index: 9;
			color: #fff;
			font-size: 32rpx;
			font-weight: bold;
			text-align: center;
		}
		.dayTextB {
			position: relative;
			z-index: 9;
			color: #e1e1e1;
			font-size: 32rpx;
			font-weight: bold;
			text-align: center;
		}
		.point {
			width: 12rpx;
			height: 12rpx;
			background-color: #00b498;
			position: absolute;
			top: 65rpx;
			left: 50%;
			transform: translate(-50%, 0);
			border-radius: 50%;
		}
		.selectedDayBGColor {
			width: 87rpx;
			height: 87rpx;
			background-color: #00b498;
			border-radius: 50%;
			position: absolute;
			top: 0;
			left: 9rpx;
		}
		.pointA {
			width: 12rpx;
			height: 12rpx;
			background-color: #fff;
			position: absolute;
			top: 65rpx;
			left: 50%;
			transform: translate(-50%, 0);
			border-radius: 50%;
		}
	}
}
.transitionTime {
	transition: transform 0.5s;
}
.arrowBox {
	width: 750rpx;
	height: 109rpx;
	line-height: 109rpx;
	position: relative;
	.arrowButtonRegion {
		width: 100rpx;
		height: 50rpx;
		line-height: 50rpx;
		@include fsc();
		position: absolute;
		left: 50%;
		top: 50%;
		transform: translate(-50%, -50%);
		background-color: #00b488;
		border-radius: 10rpx;
		color: #fff;
		font-size: 28rpx;
		text-align: center;
	}
}
.titleBox {
	width: 750rpx;
	height: 92rpx;
	background-color: #fff;
	position: relative;
	padding-bottom: 60rpx;
	.title {
		position: absolute;
		left: 30rpx;
		top: 25rpx;
		color: #333;
		font-size: 53rpx;
		font-weight: bold;
		text-align: left;
	}
}
.week {
	width: 750rpx;
	height: 39rpx;
	color: #999;
	font-size: 32rpx;
	font-weight: bold;
	text-align: left;
	display: flex;
	justify-content: space-around;
	margin-left: 7.5rpx;
	margin-bottom: 49rpx;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/736809.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一、系统学习微服务遇到的问题集合

1、启动了nacos服务&#xff0c;没有在注册列表 应该是版本问题 Alibaba-nacos版本 nacos-文档 Spring Cloud Alibaba-中文 Spring-Cloud-Alibaba-英文 Spring-Cloud-Gateway 写的很好的一篇文章 在Spring initial上面配置 start.aliyun.com 重新下载 < 2、 No Feign…

嵌入式系统中的加解密签名

笔者来了解一下嵌入式系统中的加解密 1、背景与名词解释 笔者最近在做安全升级相关的模块&#xff0c;碰到了一些相关的概念和一些应用场景&#xff0c;特来学习记录一下。 1.1 名词解释 对称加密&#xff1a;对称加密是一种加密方法&#xff0c;使用相同的密钥&#xff08;…

力扣刷题 杨辉三角(使用c++ vector解法)

杨辉三角 题目描述示例1示例2提示:代码 题目描述 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例1 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] 示例2 …

4、SpringMVC 实战小项目【加法计算器、用户登录、留言板、图书管理系统】

SpringMVC 实战小项目 3.1 加法计算器3.1.1 准备⼯作前端 3.1.2 约定前后端交互接⼝需求分析接⼝定义请求参数:响应数据: 3.1.3 服务器代码 3.2 ⽤⼾登录3.2.1 准备⼯作3.2.2 约定前后端交互接⼝3.2.3 实现服务器端代码 3.3 留⾔板实现服务器端代码 3.4 图书管理系统准备后端 3…

【内存管理】页面分配机制

前言 Linux内核中是如何分配出页面的&#xff0c;如果我们站在CPU的角度去看这个问题&#xff0c;CPU能分配出来的页面是以物理页面为单位的。也就是我们计算机中常讲的分页机制。本文就看下Linux内核是如何管理&#xff0c;释放和分配这些物理页面的。 伙伴算法 伙伴系统的…

Visual Studio开发环境搭建

原文&#xff1a;https://blog.c12th.cn/archives/25.html Visual Studio开发环境搭建 测试&#xff1a;笔记本原装操作系统&#xff1a;Windows 10 家庭中文版 资源分享链接&#xff1a;提取码&#xff1a;qbt2 注意事项&#xff1a;注意查看本地硬盘是否够用&#xff0c;建议…

在阿里云使用Docker部署MySQL服务,并且通过IDEA进行连接

阿里云使用Docker部署MySQL服务&#xff0c;并且通过IDEA进行连接 这里演示如何使用阿里云来进行MySQL的部署&#xff0c;系统使用的是Linux系统 (Ubuntu)。 为什么使用Docker? 首先是因为它的可移植性可以在任何有Docker环境的系统上运行应用&#xff0c;避免了在不通操作系…

SpringBoot+ENC实现密钥加密及使用原理

&#x1f60a; 作者&#xff1a; 一恍过去 &#x1f496; 主页&#xff1a; https://blog.csdn.net/zhuocailing3390 &#x1f38a; 社区&#xff1a; Java技术栈交流 &#x1f389; 主题&#xff1a; SpringBootENC实现密钥加密及使用原理 ⏱️ 创作时间&#xff1a; 202…

AtCoder Beginner Contest 359 A~C(D~F更新中...)

A.Count Takahashi 题意 给出 N N N个字符串&#xff0c;每个字符串为以下两种字符串之一&#xff1a; "Takahashi" "Aoki" 请你统计"Takahashi"出现了多少次。 分析 输入并统计即可。 代码 #include <bits/stdc.h>using namespa…

web集群-nginx(nginx三种文件模块,nginx用户请求流程,域名访问网站,虚拟主机,搭建大型直播购物平台)

nginx文件模块 lineinfile未来修改配置文件使用&#xff0c;类似于sed -i ‘sg’ 和sed ‘cai’ 掌握file模块&#xff1a;创建文件&#xff0c;目录&#xff0c;创建软链接&#xff0c;修改权限和所有者&#xff0c;删除文件目录 服务管理systemd systemctl相当于linux sys…

[stm32]温湿度采集与OLED显示

一、I2C总线协议 I2C&#xff08;Inter-integrated circuit &#xff09;是一种允许从不同的芯片或电路与不同的主芯片通信的协议。它仅用于短距离通信&#xff0c;是一种用于两个或多个设备之间进行数据传输的串行总线技术&#xff0c;它可以让你在微处理器、传感器、存储器、…

UE5开发游戏Tutorial

文章目录 PlayerStart 初始化设置默认 LevelBP_Character 初始化BP_Character 添加动画BP_Character 攻击BP_Enemy 初始化 以及 AI 运动Camera Collision 相机碰撞BP_Character 生命以及伤害Wave Spawner 波生成UI 初始化以及 Damage Screen指定位置随机生成添加声音环境 Envir…

使用SpringCache实现Redis缓存

目录 一 什么是Spring Cache 二 Spring Cache 各注解作用 ①EnableCaching ②Cacheable ③CachePut ④CacheEvict 三实现步骤 ①导入spring cache依赖和Redis依赖 ②配置Redis连接信息 ③在启动类上加上开启spring cache的注解 ④ 在对应的方法上加上需要的注解 一 什么…

PINN解偏微分方程实例4

PINN解偏微分方程实例4 一、正问题1. Diffusion equation2. Burgers’ equation3. Allen–Cahn equation4. Wave equation 二、反问题1. Burgers’ equation3. 部分代码示例 本文使用 PINN解偏微分方程实例1中展示的代码求解了以四个具体的偏微分方程&#xff0c;包括Diffusio…

长亭谛听教程部署和详细教程

PPT 图片先挂着 挺概念的 谛听的能力 hw的时候可能会问你用过的安全产品能力能加分挺重要 溯源反制 反制很重要感觉很厉害 取证分析 诱捕牵制 其实就是蜜罐 有模板直接爬取某些网页模板进行伪装 部署要求 挺低的 对linux内核版本有要求 需要root 还有系统配置也要修改 …

论文阅读--Efficient Hybrid Zoom using Camera Fusion on Mobile Phones

这是谷歌影像团队 2023 年发表在 Siggraph Asia 上的一篇文章&#xff0c;主要介绍的是利用多摄融合的思路进行变焦。 单反相机因为卓越的硬件性能&#xff0c;可以非常方便的实现光学变焦。不过目前的智能手机&#xff0c;受制于物理空间的限制&#xff0c;还不能做到像单反一…

long long ago

一、long 众所周知&#xff0c;英文单词 long&#xff0c;表示长,长的。 但是&#xff0c;还有很多你不知道到的东西&#xff0c;根据英文单词首字母象形原则&#xff0c;我们可以做一下单词long结构分析&#xff1a; long l长 ong长 什么意思&#xff1f;就是说首字线 l…

Maven的依赖传递、依赖管理、依赖作用域

在Maven项目中通常会引入大量依赖&#xff0c;但依赖管理不当&#xff0c;会造成版本混乱冲突或者目标包臃肿。因此&#xff0c;我们以SpringBoot为例&#xff0c;从三方面探索依赖的使用规则。 1、 依赖传递 依赖是会传递的&#xff0c;依赖的依赖也会连带引入。例如在项目中…

AI大模型企业应用实战(14)-langchain的Embedding

1 安装依赖 ! pip install --upgrade langchain ! pip install --upgrade openai0.27.8 ! pip install -U langchain-openai ! pip show openai ! pip show langchain ! pip show langchain-openai 2 Embed_documents # 1. 导入所需的库 from langchain_openai import Open…

poi生成的excel,输入数字后变成1.11111111111111E+23

poi版本4.1.2 生成excel后&#xff0c;单元格输入数字&#xff0c;过长的话变成这样 解决&#xff1a;生成的时候设置单元格格式为文本格式 import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.io.FileOutputStream; imp…