目录
一、简介
二、前端职责
三、开发步骤
四、技术选型
五、页面展示
一、简介
做一个网站时,能看到的一切都是前端程序员的工作,负责网页或者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>