大致思路:
- 前端:整体使用瀑布流布局,拥有对便利贴的增删改查功能,对标签的拖拽功能等。使用 MVC 设计模式,实现 js 的模块化。
- 后端:使用 express (基于nodejs)实现后端,使用 sequelize (Node的ORM框架Sequelize操作数据库)作为本次的数据库。
流程:
准备工作
因为本次使用到 express 所以在一开始就安装 express
- npm 初始化
npm init -y
- 安装 express ,并通过 express 生成器创建应用骨架,本次使用到 ejs 模板
npm i express --save
npm install express-generator
express -f -e // 生成 ejs 模板引擎,并且在非空目录下 -f
- 安装依赖
npm install
注:由于本次使用 webpack (自动化构建工具,实现LESS,CSS,JS编译和压缩代码)打包,使用 less (可嵌套,定义函数的 CSS)编写样式代码,使用到 sequelize (Node的ORM框架Sequelize操作数据库)作为数据库,使用到 passport (oAuth2实现第三方登录)实现第三方登录等等,需要安装的模块不一一介绍,缺少哪一项通过 npm i module --save
本地安装即可。
- 在 src 目录下创建 webpack.config.js (主要打包该目录下文件)
webpack相关
// 引入所需模块
var webpack = require('webpack')
var path = require('path') // 输出文件的目标路径,进行路径拼接防止出错
var ExtractTextPlugin = require('extract-text-webpack-plugin') // 插件,使webpack更加方便
var autoprefixer = require('autoprefixer') // 自动补全 css3 前缀
module.exports = {
entry: path.join(__dirname, "js/app/index.js"),
output: {
path: path.join(__dirname, "../public"),
filename: "js/index.js"
},
module: {
rules: [{
test: /\.less$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: ["css-loader", "less-loader", "postcss-loader"]
}) //把 css 抽离出来生成一个文件
}]
},
resolve: {
alias: {
jquery: path.join(__dirname, "js/lib/jquery-2.0.3.min.js"),
mod: path.join(__dirname, "js/mod"),
less: path.join(__dirname, "less")
}
},
plugins: [
new webpack.ProvidePlugin({
$: "jquery"
}),
new ExtractTextPlugin("css/index.css"),
new webpack.LoaderOptionsPlugin({
options: {
postcss: [
autoprefixer(),
]
}
})
]
};
- 基本工作准备完成,现在开始写前端代码。
- js 模块可以分为:便签生成、便签管理、便签的瀑布流布局、消息提醒和事件中心等五大部分
- 便签的生成
包含初始化(便签id、用户username),设置颜色,位置,绑定事件等(包括添加,编辑,删除) - 瀑布流布局:
- 各单位等宽不等高
- 第n个放置在前一行中高度最小的下方
- 每添加一个单位就要更新这一行的高度以确定最小高度
var WaterFall = (function(){
var $ct
var $items
// 渲染函数
function render($c){
$ct = $c
$items = $ct.children() // 获取到所有子元素
var nodeWidth = $items.outerWidth(true), // 获取到外轮廓的宽度加margin
colNum = Math.floor($(window).width()/nodeWidth), // 获取多少列
colSumHeight = [] // 总高度
for(var i=0;i<$items.length;i++){
if(i<colNum){
$($items[i]).css({
'left': i*nodeWidth,
'top': '0'
})
colSumHeight.push($($items[i]).outerHeight(true))
}else{
var minH=Math.min.apply(null,colSumHeight)
var indexH=colSumHeight.indexOf(minH)
$($items[i]).css({
'left': indexH*nodeWidth,
'top': minH
})
colSumHeight[indexH]+=$($items[i]).outerHeight(true)
}
}
}
$(window).on('resize', function(){
render($ct)
})
return {
init: render
}
})()
module.exports = WaterFall // 使用方式 WaterFall.init()
$noteHead.on('mousedown', function(e){
var evtX = e.pageX - $note.offset().left,
evtY = e.pageY - $note.offset().top
$note.addClass('draggable').data('evtPos', {x:evtX, y:evtY})
// 设置标签为可移动,并且记录其位置
}).on('mouseup', function(){
$note.removeClass('draggable').removeData('evtPos')
})
// 标签移动记录其位置;标签随鼠标移动
$('body').on('mousemove', function(e){
$('.draggable').length && $('.draggable').offset({
top: e.pageY-$('.draggable').data('evtPos').y,
left: e.pageX-$('.draggable').data('evtPos').x
})
})
- 消息提醒模块
使用fadeIn()
和fadeOut()
的淡入淡出效果。 - 便签管理模块
包含初始加载,添加便签等。 - 事件中心
作为统一调配其他模块。类似于发布订阅模式。
前端最后一步写入口文件 app/index.js
引入其他模块,并做相应处理。
- 使用 sequelize(Node的ORM框架Sequelize操作数据库) 创建数据库,并连接
数据库使用 sqlite3 一款轻型的数据库
创建 models ,note.js 写入 sequelize 代码
具体参考 sequelize官方文档
此时需要创建 database 文件夹作为数据库存储。
-
处理 ajax 请求(该router是后端定义文件)
约定接口(约定请求方式、请求和相应数据等):
- 获取所有的note: GET:
/api/notes
req:{}
res:{ status: 0, data:[{},{}]}
{status: 1,errorMsg:'失败的原因'}
- 创建一个note:POST:
/api/notes/add
req:{note: 'hello world'}
res:{ status:0}
{status: 1,errorMsg:'失败的原因'}
- 修改一个note:POST:
/api/notes/edit
req:{note: 'new note',id:100}
- 删除一个note:POST:
/api/notes/detele
req:{id:n}
- 获取所有的note: GET:
- 第三方登录
阮一峰 oauth 2.0文章
OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。 ---- 百度百科
如果需要giuhub的第三方登录就需要去该方申请
登录giuhub,然后Setting > Developer setting > OAuth applications > Register a new application ,然后填入基本的 app 信息,就会得到 Client ID/Client Secret 。
在通过 passport-github 实现第三方登录,配置如下:
var GitHubStrategy = require('passport-github').Strategy;
// 配置基本信息
passport.use(new GitHubStrategy({
clientID: GITHUB_CLIENT_ID,
clientSecret: GITHUB_CLIENT_SECRET,
callbackURL: "http://127.0.0.1:3000/auth/github/callback"
},
function(accessToken, refreshToken, profile, cb) {
User.findOrCreate({ githubId: profile.id }, function (err, user) {
return cb(err, user);
});
}
));
router.get('/logout', function(req, res){ // 注销
req.session.destroy();
res.redirect('/');
})
app.get('/auth/github', // 登录
passport.authenticate('github'));
app.get('/auth/github/callback', // 登录回调函数
passport.authenticate('github', { failureRedirect: '/login' }),
function(req, res) {
// Successful authentication, redirect home.
res.redirect('/');
});
并且在 app.js 添加 session 中间键(此时需要安装 session 模块 npm install express-session
)
小工具
node 端调试工具
npm install -g node-inspector // 安装调试工具
node-inspector // 启动调试软件(默认占用8080端口)
/* 注意提示调试网址,通过该网址进行调试
还需要开启服务器 node --debug bin/www
刷新服务器网址,再刷新调试网站即可。
*/