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