前端开发流程与技术选型

news2024/10/7 8:23:56

目录

一、简介

二、前端职责

三、开发步骤

四、技术选型

五、页面展示


一、简介

做一个网站时,能看到的一切都是前端程序员的工作,负责网页或者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.coloradmin.cn/o/1862235.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

鸿蒙开发系统基础能力:【@ohos.inputMethodEngine (输入法服务)】

输入法服务 说明&#xff1a; 本模块首批接口从API version 8开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 import inputMethodEngine from ohos.inputMethodEngine;inputMethodEngine 常量值。 系统能力&#xff1a;以下各项对应…

TCP: 传输控制协议

TCP: 传输控制协议 TCP的服务TCP 的首部小结 本系列文章旨在巩固网络编程理论知识&#xff0c;后续将结合实际开展深入理解的文章。 TCP的服务 T C P和U D P都使用相同的网络层&#xff08;I P&#xff09;&#xff0c;T C P却向应用层提供与U D P完全不同的服务。 T C P提供一…

GPOPS-II教程(2): 可复用火箭再入大气层最优轨迹规划问题

问题描述 考虑一类可复用火箭再入大气层最优轨迹规划问题&#xff0c;其动力学方程为 { r ˙ v sin ⁡ γ , θ ˙ v cos ⁡ γ sin ⁡ ψ r cos ⁡ ϕ , ϕ ˙ v cos ⁡ γ cos ⁡ ψ r , v ˙ − F d m − F g sin ⁡ γ , γ ˙ F l cos ⁡ σ m v − ( F g v − v r …

malloc和new的本质区别

目录 一、结论 二、示例 1.实现类T 2.用malloc分配类T的内存空间 3.用new分配类T的内存空间 一、结论 malloc 和 new 都是用于在运行时动态分配内存的机制。但它们之间存在一些本质的区别&#xff0c;主要是在使用方面&#xff0c;现在我们直接说结论&#xff0c;然后在通过…

日光模拟器对显示器光干涉影响

太阳光模拟器应用领域 抬头显示器TFT日光照射仿真太阳光模拟器LED显示器阳光耐候老化测试仪器中的光照实验抬头显示器TFT日光照射仿真太阳光模拟器全光谱阳光太阳辐射环境模拟系统中的光LCD和OLED显示器强光试验太阳光模拟器日光模拟器的光谱匹配度测量方法新型LED太阳模拟器光…

Android音频系统

最近在做UAC的项目&#xff0c;大概就是接收内核UAC的事件&#xff0c;也就是声音相关事件。然后就是pcm_read和AudioTrackr->write之间互传。感觉略微有点奇怪&#xff0c;所以简单总结一下。 1 UAC的简要流程 open_netlink_socket 打开内核窗口&#xff0c;类似于ioctl。…

Verilog的逻辑系统及数据类型(一):四值逻辑系统

目录 1. Verilog采用的四值逻辑系统2.主要数据类型2.1 net&#xff08;线网&#xff09;2.2 寄存器类 &#xff08;register)2.3 Verilog中net和register声明语法2.3.1 net声明2.3.2 寄存器声明 2.4 选择正确的数据类型2.5 选择数据类型时常犯的错误2.5.1 信号类型确定方法总结…

使用 Spring Boot 3.x 与图形学技术,添加电子印章防伪特征

使用 Spring Boot 3.x 与图形学技术,添加电子印章防伪特征 在电子办公和无纸化办公日益普及的今天,电子印章的使用越来越广泛。然而,如何确保电子印章的安全性和防伪能力成为了一个亟待解决的问题。本文将通过 Spring Boot 3.x 和图形学技术,深入探讨如何为电子印章添加防…

速卖通自养号测评:安全高效的推广手段

在速卖通平台上&#xff0c;卖家们常常寻求各种方法来提升商品的曝光、转化率和店铺权重。其中&#xff0c;自养号测评作为一种低成本、高回报的推广方式&#xff0c;备受关注。然而&#xff0c;若操作不当&#xff0c;也可能带来风险。以下是如何安全有效地进行自养号测评的指…

label studio数据标注平台的自动化标注使用

&#xff08;作者&#xff1a;陈玓玏&#xff09; 开源项目&#xff0c;欢迎star哦&#xff0c;https://github.com/tencentmusic/cube-studio 做图文音项目过程中&#xff0c;我们通常会需要进行数据标注。label studio是一个比较好上手的标注平台&#xff0c;可以直接搜…

MAB规范(3):Chapter6 Glossary 术语表

第6章 - 术语表 此章不做过多的批注&#xff0c;都是些简单的术语解释。

【算法学习】判断点在多边形内外的算法以及确定内外两点连线与边界的交点

1.前言&#xff1a; 在GIS开发中&#xff0c;经常会遇到确定一个坐标点是否在一块区域的内部这一问题。 如果这个问题不是一个单纯的数学问题&#xff0c;例如&#xff1a;在判断DEM、二维图像像素点、3D点云点等含有自身特征信息的这些点是否在一个区域范围内部的时候&#x…

Java三层框架的解析

引言&#xff1a;欢迎各位点击收看本篇博客&#xff0c;在历经很多的艰辛&#xff0c;我也是成功由小白浅浅进入了入门行列&#xff0c;也是收货到很多的知识&#xff0c;每次看黑马的JavaWeb课程视频&#xff0c;才使一个小菜鸡见识到了Java前后端是如何进行交互访问的&#x…

20240626 每日AI必读资讯

&#x1f30d;警告&#xff01;OpenAI宣布全面封锁中国API接入&#xff01; - 7月9号开始封锁不支持的国家API - 如果在OpenAI不允许的国家使用其 API 将面临封杀 &#x1f517; 警告&#xff01;OpenAI 宣布全面封锁中国 API 接入-CSDN博客 &#x1f3b5;索尼、环球音乐、华…

29-Matplotlib数学表达式

Matplotlib数学表达式 Matplotlib 中的文本字符串都可以使用 Text Markup&#xff08;一种文本标记语言&#xff09;显现出来&#xff0c;具体的使用方法是将文本标记符放在一对美元符号$内&#xff0c;语法格式如下&#xff1a; #数学表达式 plt.title(r$\alpha > \beta$…

【c语言】二级指针

1&#xff0c;定义 本质还是从指针的角度去理解&#xff0c;只不过存的指针的值 2&#xff0c;使用方法

小程序的基本使用

【 0 】前言 【 0 】 这个就是js代码的存放地方 app.json // pages/banner/banner.js Page({/*** 页面的初始数据*/data: {},/*** 生命周期函数--监听页面加载*/onLoad(options) {},/*** 生命周期函数--监听页面初次渲染完成*/onReady() {},/*** 生命周期函数--监听页面显示…

互联网应用主流框架整合之Spring Boot运维体系

先准备个简单的系统&#xff0c;配置和代码如下 # 服务器配置 server:# 服务器端口port: 8001# Spring Boot 配置 spring:# MVC 配置mvc:# Servlet 配置servlet:# Servlet 的访问路径path: /sbd# 应用程序配置application:# 应用程序名称name: SpringBootDeployment# 配置数据…

云动态摘要 2024-06-25

给您带来云厂商的最新动态&#xff0c;最新产品资讯和最新优惠更新。 最新产品更新 Web应用防火墙 - 验证码支持微信小程序接入 阿里云 2024-06-25 支持客户从微信小程序场景下接入&#xff0c;提供人机识别的安全防护。 工业数字模型驱动引擎 - iDME控制台换新升级 华为云…

cropperjs 裁剪/框选图片

1.效果 2.使用组件 <!-- 父级 --><Cropper ref"cropperRef" :imgUrl"url" searchImg"searchImg"></Cropper>3.封装组件 <template><el-dialog :title"title" :visible.sync"dialogVisible" wi…