1. 初始化
npm init -y
- 安装express
npm install express --save
- 安装Express 应用生成器
-
npm install express-generator -g
,安装在全局的话,可以直接express
调用 -
npm install express-generator --save-dev
,这样只安装在了当前目录,可以这样调用./node_modules/express-generator/bin/express-cli.js
-
-
./node_modules/express-generator/bin/express-cli.js -h
,查看express的功能 -
./node_modules/express-generator/bin/express-cli.js -f -e
,创建一个模版 -
npm install
,安装依赖(就是package.json里的dependencies下的东西) -
npm start
(就是执行package.json下的start),访问http://localhost:3000/,也可以PROT=4000 npm start
这样端口号就是4000 - bin目录里的www是网站的入口,它会调用app.js(入口 ),app.js通过中间件(app.use())设置路由,路由放在routes目录下,路由可以通过req.query得到查询参数
2. MVC
- C:routes
router.get('/', function(req, res, next) {
console.log(req.query) //url的查询参数
res.render('index', { title: 'Express' });
//渲染到views里的东西
});
- V:views
3. 中间件
var app = express();
// 没有挂载路径的中间件,应用的每个请求都会执行该中间件
app.use(function (req, res, next) {
console.log('Time:', Date.now());
next(); //进入下一个中间件
});
// 挂载至 /user/:id 的中间件,任何指向 /user/:id 的请求都会执行它
app.use('/user/:id', function (req, res, next) {
console.log('Request Type:', req.method);
next();
});
// 路由和句柄函数(中间件系统),处理指向 /user/:id 的 GET 请求
app.get('/user/:id', function (req, res, next) {
res.send('USER'); //发送请求,中间件执行结束
//若没有next,则请求不会再往下传了
});
可以用中间件进行页面跳转
var usersRouter = require('./routes/users');
app.use('/users', usersRouter);
4. 路由
若你请求的是文件,例如css:/stylesheets/style.css
,则在app.js里有static方法,从而得到文件,app.js不会再往下执行
app.use(express.static(path.join(__dirname, 'public')));
这一句会把请求的路径和目录和文件匹配,若有这个文件则返回文件
5. 配置webpack
- 去官网看配置,在根目录创建webpack.config.js文件,并在package.json的scripts里加上
"webpack": "webpack --config=webpack.config.js"
,在命令行运行npm run webpack
看webpack是否配置成功 - webpack配置成功后,安装onchange,
npm install --save-dev onchange
,在scripts里添加"watch": "onchange 'src/**/*.js' 'src/**/*.less' -- npm run webpack"
,在命令行运行npm run watch
,这样会监听src目录下所有js和less文件,改变了之后会自动运行npm run webpack
6. toast
用到jQuery的fadeIn()、fadeOut()
toast.prototype = {
createToast() {
let tpl = '<div class="toast">'+ this.msg +'</div>'
this.$toast = $(tpl)
$('body').append(this.$toast)
},
showToast(){
let self = this;
this.$toast.fadeIn(300,function () {
setTimeout(function () {
self.$toast.fadeOut(300,function () {
self.$toast.remove()
})
},self.dismissTime)
})
}
}
7. Less
@color: black //自定义一个叫@color的颜色
.rounded-corners (@radius: 5px) {
border-radius: @radius;
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
}
#header {
.rounded-corners;
}
#footer {
.rounded-corners(10px);
}
//嵌套
#header {
h1 {
font-size: 26px;
font-weight: bold;
}
p {
&:hover { border-width: 1px }
//&代表自己
}
}
//还可以计算
h1{
@fontSize * 2
}
8. 在全局引入jQuery
在webpack.config.js里添加一个resolve属性和plugins属性
module.exports = {
resolve: {
alias: {
jquery: path.join(__dirname, "src/js/lib/jquery.js"),
//若以jquery开头,则会引用这个路径的东西
mod: path.join(__dirname, "src/js/mod"),
//若以mod开头,则会引用这个路径的东西
less: path.join(__dirname, "src/less")
//若以less开头,则会引用这个路径的东西
//引用时`require('less/toast.less')`
}
},
plugins: [
new webpack.ProvidePlugin({
$: "jquery"
}), //相当于在每个文件写了个let $ = require('jquery')
]
}
1. $(selector).fadeIn(300,function(){} )
2. $(selector).fadeOut(300,function(){})
这两个jquery的API,淡入和淡出,第一个参数是时间,第二个参数是淡入淡出执行完后执行的函数
3. $(selector).outerWidth()
- width()方法用于获得元素宽度;
- innerWidth()方法用于获得包括padding的元素宽度
- outerWidth()方法用于获得包括padding和border的元素宽度
- outerWidth(true)方法用于获得包括padding、border和margin的元素宽度
4. $(selector).each(function(index){})
$('li').each(function( index ) {
console.log( index + ": " + $(this).text() );
});
5. $.each()
$.each([52, 97], function(index, value) {
alert(index + ': ' + value);
});
//0: 52
//1: 97
6. $("body").data()
我们可以在一个元素上设置不同的值,之后获取这些值:
$("body").data("foo", 52);
$("body").data("bar", { myType: "test", count: 40 });
$("body").data({ baz: [ 1, 2, 3 ] });
$("body").data("foo"); // 52
$("body").data(); // { foo: 52, bar: { myType: "test", count: 40 }, baz: [ 1, 2, 3 ] }
7. done和fail
相当于promise.then里的resolve和reject
$.post().done(function(){
console.log('执行完成');
})
.fail(function(){
console.log('执行失败');
});
8. $.extend()
var object1 = {
apple: 0,
banana: { weight: 52, price: 100 },
cherry: 97
};
var object2 = {
banana: { price: 200 },
durian: 100
};
// Merge object2 into object1
let a = $.extend( object1, object2 );
将object2的属性都合并到object1,并返回object1,和Object.assign是一样的?
9. 安装less-loader、css-loader、less、less-loader
npm install --save-dev css-loader
npm install style-loader --save-dev
npm install less-loader --save-dev
npm install less --save-dev
- 在webpack.config.js里配置
module.exports = {
module: {
rules: [
{
test: /\.less$/,
use: ["style-loader", "css-loader", "less-loader"]
}
]
},
10. 配置api
在app.js里写
var api = require('./routes/api');
app.use('/api', api);
然后在routes目录创建api.js
router.get('/notes',function(req,res,next){
Note.findAll({raw: true}).then(function(notes){
console.log(notes)
res.send({status: 0, data: notes})
})
})
这样发送get请求,url写'/notes'
,相当于'/api/notes'
,因为在app.js里配置了app.use('/api', api);
,所以在api.js里写的所有路径前都会加上一个/api/
11. 数据库
- 创建model目录,在model目录下安装
- 安装sequelize:
sudo cnpm install --save sequelize
- 安装sqlite3:
sudo npm install --save sqlite3
- 在model目录下创建一个note.js文件,写上sequelize官网的配置然后导出note
- 相关api
//找到所有备忘录
Note.findAll({raw: true}).then(function(notes){
res.send({status: 0, data: notes})
})
- 配置好note.js文件后,在model目录下执行
node note.js
,创建数据库 - 在api.js里导入note,用note里的api操作数据库
12. path
用path这个模块来包装路径,在需要用到路径的文件里写
let path = require('path')
path.join(__dirname, '../database/database.sqlite')
//dirname就是当前的路径
//相当于当前路径加上后面的路径
这样使用路径更安全
未完待续...