web前端练手项目代码(打造创业公司官网)
在规划篇和设计篇中已经确定我们的需求,前端的技术实现层面我们选中了 nuxtjs 这个实现 vuejs ssr 的框架,目的是为之后的扩展打下一个好的基础,比如增加资讯页面、作品详情页面、Blog等。
结合设计稿,我们本来计划是用一些第三方的UI框架或者是直接写一套样式进来,但是考虑这套设计稿中的色彩、元素和预留的一些组件扩展,比如Button、Text、Card等这些组件在以后的业务中也会经常用到,虽然有很多前端框架实现的很好,但是并不是我们自己创作的UI/UX,最终无法形成很好的品牌效应。
最终考虑还是决定自行实现,恰好刚完成的一个大数据展示的业务中用到 tailwindCss 这个框架,这个是工具优先的 css 框架,灵活性非常高,内部很好的实现了CSS中常用的工具,比如网格、网站自适应工具等,只需要按我们的设计进行定制规划就可以满足我们的需求,并且 nuxtjs 也实现了 tailwind 的插件。那么我就开始前端实现的旅程吧:
项目搭建
$ yarn create nuxt-app caixie-website-nuxtjs
# 执行选择结果如下
create-nuxt-app v2.14.0
✨ Generating Nuxt.js project in caixie-website-nuxtjs
? Project name caixie-website-nuxtjs
? Project description 北京采撷科技有限公司
? Author name baisheng
? Choose the package manager Yarn
? Choose UI framework Tailwind CSS
? Choose custom server framework none (Recommended)
? Choose Nuxt.js modules DotEnv
? Choose linting tools (Press <space> to select, <a> to toggle all, <i> to invert selection)
? Choose test framework None
? Choose rendering mode Universal (SSR)
? Choose development tools (Press <space> to select, <a> to toggle all, <i> to invert selection)
Successfully created project caixie-website-nuxtjs
To get started:
cd caixie-website-nuxtjs
yarn dev
To build & start for production:
cd caixie-website-nuxtjs
yarn build
yarn start
✨ Done in 68.03s.
接下来我们开始规划工程目录工程目录如下
前端工程目录
components 目录是我们根据设计稿的规划,将整个页面进行组件化分形成的,方便后期调整各组件样式和结构。由于采用了 tailwind 去做样式,实现上就简单很多,拿 service 组件为例:components/Service.vue
<template>
<div id="service"
class="container bg-center bg-no-repeat bg-contain sm:pb-16 sm:mt-16 landing-changelog-bg text-center ">
<span class="text-3xl font-black leading-tight text-indigo-100 sm:text-4xl">
服务范围
</span>
<p class="mt-8 mb-12 font-light text-gray-700 sm:mt-4 sm:text-xl">
<span class="block font-normal text-indigo-80"> 从概念到现实需要大量的时间和工作,你需要一个补充你技能的团队</span>
</p>
<div class="grid grid-cols-1 lg:grid-cols-3 sm:grid-cols-1">
<div class="flex flex-col justify-center text-gray-700 text-center bg-white px-8 py-2 m-4 h-40 rounded shadow hover:shadow-large transition-shadow duration-700 ease-in-out " v-for="(item, key) in services" :key="key">
<span class="font-bold text-indigo-100">{{item.title}}</span>
<p class="font-normal text-indigo-60">{{item.desc}}</p>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
services: [{
title: '网站开发',
desc: '响应式网站设计、H5、WebGL'
}, {
title: '移动端研发',
desc: 'IOS & Android、小程序'
}, {
title: '后端服务',
desc: '云服务、API 服务'
}, {
title: '运维服务',
desc: '服务器维护、部署、故障处理'
}, {
title: '产品策划',
desc: '需要分析、产品整理、原型设计'
}, {
title: '设计服务',
desc: '标准设计、高水平设计'
}]
}
}
}
</script>
自适应样式的效果如下:
PC端
移动端
以上简单的10几行代码就可以很精准的实现出自适应效果。
tailwind.config.js包含的是全部的样式配置,包含配色、排版、字体、阴影等,配置文件内容如下:
const {COLORS} = require('./colors')
// Depth level 1 (sitting on background)
const BOX_SHADOW_BORDER_LIGHTER = `0 0 0 1px rgba(${COLORS.indigoRgb}, .08)`;
const BOX_SHADOW_BORDER = `0 0 0 1px rgba(${COLORS.indigoRgb}, .08)`;
const BOX_SHADOW_BORDER_DARKER = `0 0 0 1px rgba(${COLORS.indigoRgb}, .16)`;
const BOX_SHADOW_SITTING = `0 4px 4px -4px rgba(${COLORS.indigoRgb}, .32)`;
// Depth level 2 (dropdowns, dialogs, draggables when lifted)
const BOX_SHADOW_LIFTED = `0 16px 24px -8px rgba(${COLORS.indigoRgb}, .32)`;
// Depth level 3 (huge shadows)
const BOX_SHADOW_LARGE = `0 16px 40px -4px rgba(${COLORS.indigoRgb}, .2)`;
// Focus style
const BOX_SHADOW_FOCUS = `0 0 0 3px ${COLORS.focus}`;
const BOX_SHADOW_BUTTON = `0 0 0 1px rgba(20, 11, 47, 0.12), 0 4px 4px -4px rgba(0, 0, 0, .32)`
const BOX_SHADOW_BUTTON_hover = `0 0 0 1px rgba(20, 11, 47, 0.32), 0 4px 4px -4px rgba(0, 0, 0, .32)`
module.exports = {
prefix: '',
important: false,
separator: ':',
theme: {
screens: {
sm: '640px',
md: '768px',
lg: '1024px',
xl: '1280px',
},
colors: {
transparent: 'transparent',
black: '#000',
white: '#fff',
gray: {
100: '#f7fafc',
200: '#edf2f7',
300: '#e2e8f0',
400: '#cbd5e0',
500: '#a0aec0',
600: '#718096',
700: '#4a5568',
800: '#2d3748',
900: '#1a202c',
},
red: {
100: '#fff5f5',
200: '#fed7d7',
300: '#feb2b2',
400: '#fc8181',
500: '#f56565',
600: '#e53e3e',
700: '#c53030',
800: '#9b2c2c',
900: '#742a2a',
},
orange: {
100: '#fffaf0',
200: '#feebc8',
300: '#fbd38d',
400: '#f6ad55',
500: '#ed8936',
600: '#dd6b20',
700: '#c05621',
800: '#9c4221',
900: '#7b341e',
},
// yellow: "#ffb300",
// y80: "#ffc233",
// y60: "#ffd166",
// y40: "#ffe199",
// y20: "#fff0cc",
// y12: "#fff5e0",
// y08: "#fff9eb",
// y04: "#fffcf5",
// y02: "#fffefa",
yellow: {
100: '#ffb300',
80: '#ffc233',
60: '#faf089',
40: '#ffe199',
20: '#fff0cc',
12: '#fff5e0',
8: '#fff9eb',
4: '#fffcf5',
2: '#fffefa',
},
green: {
100: '#f0fff4',
200: '#c6f6d5',
300: '#9ae6b4',
400: '#68d391',
500: '#48bb78',
600: '#38a169',
700: '#2f855a',
800: '#276749',
900: '#22543d',
},
teal: {
100: '#e6fffa',
200: '#b2f5ea',
300: '#81e6d9',
400: '#4fd1c5',
500: '#38b2ac',
600: '#319795',
700: '#2c7a7b',
800: '#285e61',
900: '#234e52',
},
blue: {
100: '#ebf8ff',
200: '#bee3f8',
300: '#90cdf4',
400: '#63b3ed',
500: '#4299e1',
600: '#3182ce',
700: '#2b6cb0',
800: '#2c5282',
900: '#2a4365',
},
indigo: {
100: "#24124d",
80: "#4f4270",
60: "#7b7194",
40: "#a7a0b8",
20: "#d3d0db",
12: "#e4e2e9",
8: "#eeecf1",
4: "#f4f3f6",
2: "#fbfafc",
},
purple: {
100: "#512da8",
80: "#7457b9",
60: "#9781cb",
40: "#b9abdc",
20: "#dcd5ee",
12: "#eae5f4",
8: "#f1eff8",
4: "#f8f7fc",
2: "#fcfbfd",
rgba: `rgba(${COLORS.purpleRgb}, 0.04)`,
rgbaDark: `rgba(${COLORS.purpleRgb}, 0.08)`
},
pink: {
100: '#fff5f7',
200: '#fed7e2',
300: '#fbb6ce',
400: '#f687b3',
500: '#ed64a6',
600: '#d53f8c',
700: '#b83280',
800: '#97266d',
900: '#702459',
},
magenta: {
100: "#f84f77",
80: "#f97292",
60: "#fb95ad",
40: "#fcb9c9",
20: "#fedce4",
12: "#fee9ee",
8: "#fff1f5",
4: "#fff8fa",
2: "#fffcfc"
},
},
spacing: {
px: '1px',
'0': '0',
'1': '0.25rem',
'2': '0.5rem',
'3': '0.75rem',
'4': '1rem',
'5': '1.25rem',
'6': '1.5rem',
'8': '2rem',
'10': '2.5rem',
'12': '3rem',
'16': '4rem',
'20': '5rem',
'24': '6rem',
'32': '8rem',
'40': '10rem',
'48': '12rem',
'56': '14rem',
'64': '16rem',
},
backgroundColor: theme => theme('colors'),
backgroundPosition: {
bottom: 'bottom',
center: 'center',
left: 'left',
'left-bottom': 'left bottom',
'left-top': 'left top',
right: 'right',
'right-bottom': 'right bottom',
'right-top': 'right top',
top: 'top',
},
backgroundSize: {
auto: 'auto',
cover: 'cover',
contain: 'contain',
},
borderColor: theme => ({
...theme('colors'),
default: theme('colors.gray.300', 'currentColor'),
}),
borderRadius: {
none: '0',
sm: '0.125rem',
default: '0.25rem',
lg: '0.5rem',
full: '9999px',
},
borderWidth: {
default: '1px',
'0': '0',
'2': '2px',
'4': '4px',
'8': '8px',
},
boxShadow: {
default: '0 0 0 1px rgba(20, 11, 47, 0.12), 0 4px 4px -4px rgba(0, 0, 0, .32)',
md: BOX_SHADOW_BUTTON_HOVER,
lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',
'2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)',
inner: 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)',
outline: '0 0 0 3px rgba(66, 153, 225, 0.5)',
none: 'none',
borderLighter: BOX_SHADOW_BORDER_LIGHTER,
border: BOX_SHADOW_BORDER,
borderDark: BOX_SHADOW_BORDER_DARKER,
sitting: BOX_SHADOW_SITTING,
lifted: BOX_SHADOW_LIFTED,
large: BOX_SHADOW_LARGE,
focus: BOX_SHADOW_FOCUS,
buttonHover: BOX_SHADOW_BUTTON_HOVER
},
container: {},
cursor: {
auto: 'auto',
default: 'default',
pointer: 'pointer',
wait: 'wait',
text: 'text',
move: 'move',
'not-allowed': 'not-allowed',
},
fill: {
current: 'currentColor',
},
flex: {
'1': '1 1 0%',
auto: '1 1 auto',
initial: '0 1 auto',
none: 'none',
},
flexGrow: {
'0': '0',
default: '1',
},
flexShrink: {
'0': '0',
default: '1',
},
fontFamily: {
sans: [
'-apple-system',
'BlinkMacSystemFont',
'"Segoe UI"',
'Roboto',
'"Helvetica Neue"',
'Arial',
'"Noto Sans"',
'sans-serif',
'"Apple Color Emoji"',
'"Segoe UI Emoji"',
'"Segoe UI Symbol"',
'"Noto Color Emoji"',
],
serif: [
'Georgia',
'Cambria',
'"Times New Roman"',
'Times',
'serif',
],
mono: [
'Menlo',
'Monaco',
'Consolas',
'"Liberation Mono"',
'"Courier New"',
'monospace',
],
},
fontSize: {
xs: '0.75rem',
sm: '0.875rem',
base: '1rem',
lg: '1.125rem',
xl: '1.25rem',
'2xl': '1.5rem',
'3xl': '1.875rem',
'4xl': '2.25rem',
'5xl': '3rem',
'6xl': '4rem',
},
fontWeight: {
hairline: '100',
thin: '200',
light: '300',
normal: '400',
medium: '500',
semibold: '600',
bold: '700',
extrabold: '800',
black: '900',
},
height: theme => ({
auto: 'auto',
...theme('spacing'),
full: '100%',
screen: '100vh',
}),
inset: {
'0': '0',
auto: 'auto',
},
letterSpacing: {
tighter: '-0.05em',
tight: '-0.025em',
normal: '0',
wide: '0.025em',
wider: '0.05em',
widest: '0.1em',
},
lineHeight: {
none: '1',
tight: '1.25',
snug: '1.375',
normal: '1.5',
relaxed: '1.625',
loose: '2',
},
listStyleType: {
none: 'none',
disc: 'disc',
decimal: 'decimal',
},
margin: (theme, { negative }) => ({
auto: 'auto',
...theme('spacing'),
...negative(theme('spacing')),
}),
maxHeight: {
full: '100%',
screen: '100vh',
},
maxWidth: {
xs: '20rem',
sm: '24rem',
md: '28rem',
lg: '32rem',
xl: '36rem',
'2xl': '42rem',
'3xl': '48rem',
'4xl': '56rem',
'5xl': '64rem',
'6xl': '72rem',
full: '100%',
},
minHeight: {
'0': '0',
full: '100%',
screen: '100vh',
},
minWidth: {
'0': '0',
full: '100%',
},
objectPosition: {
bottom: 'bottom',
center: 'center',
left: 'left',
'left-bottom': 'left bottom',
'left-top': 'left top',
right: 'right',
'right-bottom': 'right bottom',
'right-top': 'right top',
top: 'top',
},
opacity: {
'0': '0',
'25': '0.25',
'50': '0.5',
'75': '0.75',
'90': '.9',
'100': '1',
},
order: {
first: '-9999',
last: '9999',
none: '0',
'1': '1',
'2': '2',
'3': '3',
'4': '4',
'5': '5',
'6': '6',
'7': '7',
'8': '8',
'9': '9',
'10': '10',
'11': '11',
'12': '12',
},
padding: theme => theme('spacing'),
stroke: {
current: 'currentColor',
},
textColor: theme => theme('colors'),
width: theme => ({
auto: 'auto',
...theme('spacing'),
'1/2': '50%',
'1/3': '33.33333%',
'2/3': '66.66667%',
'1/4': '25%',
'2/4': '50%',
'3/4': '75%',
'1/5': '20%',
'2/5': '40%',
'3/5': '60%',
'4/5': '80%',
'1/6': '16.66667%',
'2/6': '33.33333%',
'3/6': '50%',
'4/6': '66.66667%',
'5/6': '83.33333%',
'1/12': '8.33333%',
'2/12': '16.66667%',
'3/12': '25%',
'4/12': '33.33333%',
'5/12': '41.66667%',
'6/12': '50%',
'7/12': '58.33333%',
'8/12': '66.66667%',
'9/12': '75%',
'10/12': '83.33333%',
'11/12': '91.66667%',
full: '100%',
screen: '100vw',
}),
zIndex: {
auto: 'auto',
'0': '0',
'10': '10',
'20': '20',
'30': '30',
'40': '40',
'50': '50',
},
transitionProperty: {
none: 'none',
all: 'all',
default: 'background-color, border-color, color, opacity, transform',
colors: 'background-color, border-color, color',
opacity: 'opacity',
transform: 'transform',
shadow: 'box-shadow',
},
transitionTimingFunction: {
linear: 'linear',
in: 'cubic-bezier(0.4, 0, 1, 1)',
out: 'cubic-bezier(0, 0, 0.2, 1)',
// 'in-out': 'cubic-bezier(0.4, 0, 0.2, 1)',
'in-out': 'cubic-bezier(0.2, .6, .6, 1)',
},
// transition: box-shadow 150ms cubic-bezier(.2,.6,.6,1);
transitionDuration: {
'75': '75ms',
'100': '100ms',
'150': '150ms',
'200': '200ms',
'300': '300ms',
'500': '500ms',
'700': '700ms',
'1000': '1000ms',
},
},
variants: {
transitionProperty: ['responsive', 'focus', 'hover'],
transitionTimingFunction: ['responsive', 'focus', 'hover'],
transitionDuration: ['responsive', 'focus', 'hover'],
alignContent: ['responsive'],
alignItems: ['responsive'],
alignSelf: ['responsive'],
appearance: ['responsive'],
backgroundAttachment: ['responsive'],
backgroundColor: ['responsive', 'hover', 'focus'],
backgroundPosition: ['responsive'],
backgroundRepeat: ['responsive'],
backgroundSize: ['responsive'],
borderCollapse: ['responsive'],
borderColor: ['responsive', 'hover', 'focus'],
borderRadius: ['responsive'],
borderStyle: ['responsive'],
borderWidth: ['responsive'],
boxShadow: ['responsive', 'hover', 'focus'],
cursor: ['responsive'],
display: ['responsive'],
fill: ['responsive'],
flex: ['responsive'],
flexDirection: ['responsive'],
flexGrow: ['responsive'],
flexShrink: ['responsive'],
flexWrap: ['responsive'],
float: ['responsive'],
fontFamily: ['responsive'],
fontSize: ['responsive'],
fontSmoothing: ['responsive'],
fontStyle: ['responsive'],
fontWeight: ['responsive', 'hover', 'focus'],
height: ['responsive'],
inset: ['responsive'],
justifyContent: ['responsive'],
letterSpacing: ['responsive'],
lineHeight: ['responsive'],
listStylePosition: ['responsive'],
listStyleType: ['responsive'],
margin: ['responsive'],
maxHeight: ['responsive'],
maxWidth: ['responsive'],
minHeight: ['responsive'],
minWidth: ['responsive'],
objectFit: ['responsive'],
objectPosition: ['responsive'],
opacity: ['responsive', 'hover', 'focus', 'active'],
order: ['responsive'],
outline: ['responsive', 'focus'],
overflow: ['responsive'],
padding: ['responsive'],
pointerEvents: ['responsive'],
position: ['responsive'],
resize: ['responsive'],
stroke: ['responsive'],
tableLayout: ['responsive'],
textAlign: ['responsive'],
textColor: ['responsive', 'hover', 'focus'],
textDecoration: ['responsive', 'hover', 'focus'],
textTransform: ['responsive'],
userSelect: ['responsive'],
verticalAlign: ['responsive'],
visibility: ['responsive'],
whitespace: ['responsive'],
width: ['responsive'],
wordBreak: ['responsive'],
zIndex: ['responsive'],
transition: ['responsive', 'hover', 'focus'],
},
corePlugins: {
// outline: false,
},
plugins: [
function({ addBase, config }) {
addBase({
'a': {
color: config('theme.colors.teal.500'),
},
'h1': {
fontSize: config('theme.fontSize.2xl'),
fontWeight: config('theme.fontWeight.bold')
},
'h2': {
fontSize: config('theme.fontSize.xl'),
fontWeight: config('theme.fontWeight.bold')
},
'h3': {
fontSize: config('theme.fontSize.base'),
fontWeight: config('theme.fontWeight.bold')
},
'p': { marginTop: '0.5em' },
})
},
]
}
nuxt.config.js中包含了 nuxt的基础配置,和 tailwind 模块配置,重点配置如下:
/*
** Nuxt.js dev-modules
*/
buildModules: [
// Doc: https://github.com/nuxt-community/nuxt-tailwindcss
'@nuxtjs/tailwindcss',
],
tailwindcss: {
configPath: '~/tailwind.config.js',
cssPath: '~/assets/main.styl'
},
其中 main.styl,包含了 tailwind 的 css 工具的引入,内容如下
@tailwind base;
@tailwind components;
@tailwind utilities;
这样基础配置和实现完成后,就可以打包发布,执行
yarn build
所有开发工作完成,接下来就是正式上线部署。详细内容请见运维篇。
,免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com