一.项目展示、项目初始化及基本配置
(1).创建项目
koa2 jsplusplus
cd jsplusplus && npm install
(2).项目配置
npm install
(3).目录及文件改造
const ENV = require('./env');
module.exports = {
MYSQL_CONF: {
base: {
host: 'localhost',
dialect: 'mysql',
pool: {
max: 5,
min: 0,
idle: 10000
}
},
conf: ['txclass', 'root', ENV.isPrd ? 'xxx' : '12345678']
}
};
const Sequelize = require('sequelize');
module.exports = {
STRING: Sequelize.STRING,
INT: Sequelize.INTEGER,
DECIMAL: Sequelize.DECIMAL,
TEXT: Sequelize.TEXT
}
const ENV = process.env.NODE_ENV;
module.exports = {
isDev: ENV === 'dev',
isPrd: ENV === 'production'
}
module.exports = [
{
title: '腾讯课堂 - JS++',
link: '//msiwei.ke.qq.com',
logoUrl: '//tximg.jsplusplus.com/txclass.png'
},
{
title: 'bilibili - JS++',
link: '//space.bilibili.com/378372969',
logoUrl: '//tximg.jsplusplus.com/bilibili.png'
},
{
title: '今日头条 - JS++',
link: '//www.toutiao.com/c/user/104117716175/#mid=1610678420152324',
logoUrl: '//tximg.jsplusplus.com/toutiao.png'
}
];
module.exports = [
{
title: 'jQuery',
logoUrl: '//img.jsplusplus.com/website/sprites/link_sprites.png',
link: 'https://api.jquery.com/',
bgSize: '528px 320px',
bgPosition: '-186px -10px'
},
{
title: 'Git',
logoUrl: '//img.jsplusplus.com/website/sprites/link_sprites.png',
link: 'https://git-scm.com/',
bgSize: '528px 320px',
bgPosition: '-10px -90px'
},
{
title: 'VueJS',
logoUrl: '//img.jsplusplus.com/website/sprites/link_sprites.png',
link: 'https://cn.vuejs.org/v2/guide/',
bgSize: '528px 320px',
bgPosition: '-186px -250px'
},
{
title: 'ReactJS',
logoUrl: '//img.jsplusplus.com/website/sprites/link_sprites.png',
link: 'https://doc.react-china.org/',
bgSize: '528px 320px',
bgPosition: '-186px -170px'
},
{
title: 'NodeJS',
logoUrl: '//img.jsplusplus.com/website/sprites/link_sprites.png',
link: 'https://nodejs.org/zh-cn/docs/',
bgSize: '528px 320px',
bgPosition: '-186px -90px'
},
{
title: 'Webpack',
logoUrl: '//img.jsplusplus.com/website/sprites/link_sprites.png',
link: 'https://webpack.js.org/concepts/',
bgSize: '528px 320px',
bgPosition: '-362px -10px'
}
];
module.exports = [
{
title: '就业班',
link: '//ke.qq.com/course/391728'
},
{
title: '提升班',
link: '//ke.qq.com/course/438871'
},
{
title: '全修班',
link: '//ke.qq.com/course/334138'
},
{
title: '架构班',
link: '//ke.qq.com/course/1185455'
}
];
const env = require('./env'),
isPrd = env.isPrd;
const URL = {
SOURCE: isPrd ? '//source.jsplusplus.com/' : '//localhost:3300/'
}
module.exports = {
INDEX: {
HEAD: {
TITLE: '妙思维JS++前端开发官方网站 - WEB|JavaScript|Vue|React|Node',
KEYWORD: '前端开发,WEB开发,在线课程,编程,项目实战,项目架构,JavaScript,Vue,React,Node',
DESCRIPTION: 'JS++前端开发工程师精英就业班与提升班课程是针对前端开发零基础、爱好者、职业技术提升、互联网创业相关人员的一套完整的WEB前端开发学习体系,该体系通过深度基础课程对学员进行培养,使学员掌握最完整最有深度的技术理论知识和实战的基础技能。',
FAVICON: '/img/logo108.png'
},
STYLESHEETS: [
URL.SOURCE + 'css/index.css'
],
SCRIPTS: [
URL.SOURCE + 'js/index.js'
]
},
LIST: {
HEAD: {
TITLE: '妙思维JS++前端开发官方网站 - WEB|JavaScript|Vue|React|Node',
KEYWORD: '前端开发,WEB开发,在线课程,编程,项目实战,项目架构,JavaScript,Vue,React,Node',
DESCRIPTION: 'JS++前端开发工程师精英就业班与提升班课程是针对前端开发零基础、爱好者、职业技术提升、互联网创业相关人员的一套完整的WEB前端开发学习体系,该体系通过深度基础课程对学员进行培养,使学员掌握最完整最有深度的技术理论知识和实战的基础技能。',
FAVICON: '/img/logo108.png'
},
STYLESHEETS: [
URL.SOURCE + 'css/list.css'
],
SCRIPTS: [
URL.SOURCE + 'js/list.js'
]
},
ERROR: {
HEAD: {
TITLE: '妙思维JS++前端开发官方网站 - WEB|JavaScript|Vue|React|Node',
KEYWORD: '前端开发,WEB开发,在线课程,编程,项目实战,项目架构,JavaScript,Vue,React,Node',
DESCRIPTION: 'JS++前端开发工程师精英就业班与提升班课程是针对前端开发零基础、爱好者、职业技术提升、互联网创业相关人员的一套完整的WEB前端开发学习体系,该体系通过深度基础课程对学员进行培养,使学员掌握最完整最有深度的技术理论知识和实战的基础技能。',
FAVICON: '/img/logo108.png'
},
STYLESHEETS: [
URL.SOURCE + 'css/error.css'
],
SCRIPTS: [
URL.SOURCE + 'js/error.js'
]
}
}
module.exports = {
infomation: '//tximg.jsplusplus.com/qr_infomation.jpg'
};
module.exports = {
IMG_BASE_URL: '//tximg.jsplusplus.com/'
}
class Home{
async index(ctx,next){
await ctx.render('index',{
title:'首页'
})
}
async list(ctx,next){
await ctx.render('list',{
title:'列表页'
})
}
async error(ctx,next){
await ctx.render('error',{
title:'错误页面'
})
}
}
module.exports = new Home();
const router = require('koa-router')(),
controller = require('../controllers/Home')
router.get('/', controller.index)
router.get('/list/:kw?',controller.list)
router.get('/error',controller.error)
router.get('*',controller.error)
module.exports = router
app.use(views(__dirname + '/src/views', {
extension: 'ejs'
}))
npm install cross-env –save-dev
再在NODE_ENV=xxxxxxx前面添加cross-env
const Sequelize = require('sequelize'),
{ MYSQL_CONF } = require('../configs/db');
const seq = new Sequelize(...MYSQL_CONF.conf, MYSQL_CONF.base);
module.exports = seq;
const URL = {
IMG_BASE_URL: '//tximg.jsplusplus.com/'
}
建立js文件夹其中建立index.js list.js error.js入口文件
二.完成layout模板编写以及公共样式引入
(1).变更控制器
const PAGE_CONF = require('../configs/page')
class Home{
async index(ctx,next){
await ctx.render('index',{
title:'首页',
PAGE_CONF:PAGE_CONF.INDEX
})
}
async list(ctx,next){
await ctx.render('list',{
title:'列表页',
PAGE_CONF:PAGE_CONF.LIST
})
}
async error(ctx,next){
await ctx.render('error',{
title:'错误页面',
PAGE_CONF:PAGE_CONF.ERROR
})
}
}
module.exports = new Home();
(2).在views中建立layout文件夹里面建立foot.ejs head.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<%
var HEAD = PAGE_CONF.HEAD,
STYLES = PAGE_CONF.STYLESHEETS;
%>
<meta charset="UTF-8">
<meta name="keyword" content="<%= HEAD.KEYWORD %>" />
<meta name="description" content="<%= HEAD.DESCRIPTION %>" />
<meta rel="shortcut icon" href="<%= HEAD.FAVICON %>" type="image/x-icon" />
<title><%= HEAD.TITLE %></title>
<% for (var i = 0; i < STYLES.length; i ++) { %>
<link rel="stylesheet" href="<%= STYLES[i] %>" />
<% } %>
</head>
<body>
<%
var SCRIPTS = PAGE_CONF.SCRIPTS;
%>
<% for (var i = 0; i < SCRIPTS.length; i ++) { %>
<script src="<%= SCRIPTS[i] %>"></script>
<% } %>
</body>
</html>
(3).views下的各个ejs页面中引入|
<%- include('layout/head.ejs', { PAGE_CONF }) %>
<H1>INDEX</H1>
<%- include('layout/foot.ejs', { PAGE_CONF }) %>{PAGE_CONF}%>
(4).js下的入口文件引入
import $ from 'jquery';
import '../styles/resets.css';
import '../styles/common.css';
import '../styles/iconfont.css';
import '../styles/ui.scss';
import '../styles/header.scss';
import '../styles/courseNav.scss';
import '../styles/courseList.scss';
import '../styles/courseItem.scss';
import '../styles/noDataTip.scss';
import '../styles/footer.scss';
(5).更改layout中的ejs
<html lang="zh-CN">
三.header部分抽离子模板、模板出口设计
(1).建立文件夹
header中建立header.ejs logo.ejs nav.ejs search.ejs
(2).编写模板
<header class="header">
<%- include('logo.ejs')%>
<%- include('nav.ejs',{navData}) %>
<%- include('search.ejs') %>
</header>
const PAGE_CONF = require('../configs/page'),
navData = require('../configs/nav');
class Home{
async index(ctx,next){
await ctx.render('index',{
title:'首页',
PAGE_CONF:PAGE_CONF.INDEX,
navData
})
}
async list(ctx,next){
await ctx.render('list',{
title:'列表页',
PAGE_CONF:PAGE_CONF.LIST
})
}
async error(ctx,next){
await ctx.render('error',{
title:'错误页面',
PAGE_CONF:PAGE_CONF.ERROR
})
}
}
module.exports = new Home();
<%- include('layout/head.ejs', { PAGE_CONF }) %>
<div class="container">
<%- include('template/common/header/index.ejs') %>
</div>
<%- include('layout/foot.ejs', { PAGE_CONF }) %>
<div class="header-logo">
<a href="/" class="logo-lk"></a>
</div>
<div class="header-nav">
<ul class="nav-list clearfix">
<% for(var i = 0; i<navData.length; i++){
var item = navData[i]
%>
<li class="nav-item">
<a href="<%= item.link%>" class="nav-lk" target="_blank">
<%= item.title%>
<i class="iconfont icon-arrow-right"></i>
</a>
</li>
<%}%>
</ul>
</div>
<div class="header-search">
<div class="search-wrap J_headerSearch">
<input type="text" class="input input-search" placeholder="搜索课程"/>
<button class="btn btn-search">
<i class="iconfont icon-search"></i>
</button>
</div>
</div>
<div class="header-search"> <div class="search-wrap J_headerSearch"> <input type="text" class="input input-search" placeholder="搜索课程"/> <button class="btn btn-search"> <i class="iconfont icon-search"></i> </button> </div> </div>