├── src
├── less
│ └── common.less
├── components
│ ├── index.js
│ └── header.vue
├── pages
│ ├── index
│ │ ├── logo.png
│ │ └── index.vue
│ ├── home
│ │ └── index.vue
│ ├── signout
│ │ └── index.vue
│ └── login
│ │ └── index.vue
├── css
│ └── common.css
├── app.vue
├── store
│ ├── index.js
│ └── user.js
├── template
│ └── index.html
├── main.js
└── config
│ └── routes.js
├── .babelrc
├── config
└── index.js
├── server.js
├── docs
├── 2.md
└── 1.md
├── gulpfile.js
├── package.json
├── webpack.config.js
└── README.md
/src/less/common.less:
--------------------------------------------------------------------------------
1 | * {
2 | padding: 0;
3 | margin: 0;
4 | }
--------------------------------------------------------------------------------
/src/components/index.js:
--------------------------------------------------------------------------------
1 | import header from './header'
2 | export default { header }
--------------------------------------------------------------------------------
/src/pages/index/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sijinglei/vue2-demo/master/src/pages/index/logo.png
--------------------------------------------------------------------------------
/src/css/common.css:
--------------------------------------------------------------------------------
1 | input::-webkit-outer-spin-button,
2 | input::-webkit-inner-spin-button{
3 | -webkit-appearance: none !important;
4 | margin: 0;
5 | }
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | "es2015",
4 | "stage-0"
5 | ],
6 | "plugins": [
7 | "transform-object-assign",
8 | "transform-vue-jsx"
9 | ]
10 | }
--------------------------------------------------------------------------------
/src/app.vue:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 | import user from './user'
4 |
5 | Vue.use(Vuex)
6 |
7 | export default new Vuex.Store({
8 | strict: process.env.NODE_ENV !== 'production', //在非生产环境下,使用严格模式
9 | modules: {
10 | user
11 | }
12 | })
--------------------------------------------------------------------------------
/src/template/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | vue2-demo
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/pages/home/index.vue:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 | 首页
8 | 退出
9 |
10 |
{{user.name}}欢迎回家
11 |
12 |
13 |
--------------------------------------------------------------------------------
/config/index.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | devTest: { //部署到测试服务器上
3 | remotePath: '/app/', //部署到服务器的路径
4 | host: '111.11.111.111', //ip地址
5 | user: 'root', //帐号
6 | pass: '88888888', //密码
7 | port: 22 //端口
8 | },
9 | devDist: { //部署正式服务器上
10 | remotePath: '/app/', //部署到服务器的路径
11 | host: '111.11.111.111', //ip地址
12 | user: 'root', //帐号
13 | pass: '88888888', //密码
14 | port: 22 //端口
15 | },
16 | publicPath: '/app/', //程序在网站根路径地址
17 | target: 'https://cnodejs.org/' //连接的服务器地址
18 | }
19 |
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | const Webpack = require("webpack")
2 | const WebpackDevServer = require('webpack-dev-server')
3 | const webpackConfig = require("./webpack.config")
4 | const config = require('./config/')
5 |
6 | var compiler = Webpack(webpackConfig)
7 | var server = new WebpackDevServer(compiler, {
8 | publicPath: config.publicPath,
9 | stats: {
10 | colors: true //显示不同的颜色区分打包的文件
11 | },
12 | proxy: { //代理服务器
13 | '*': {
14 | target: config.target,
15 | changeOrigin: true
16 | }
17 | }
18 | })
19 |
20 | server.listen(3000, (err) => {
21 | if (err) {
22 | console.log(err)
23 | return
24 | }
25 | console.log('http://localhost:3000' + config.publicPath)
26 | })
--------------------------------------------------------------------------------
/src/pages/signout/index.vue:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 | 返回
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/store/user.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | export const USER_SIGNIN = 'USER_SIGNIN' //登录成功
4 | export const USER_SIGNOUT = 'USER_SIGNOUT' //退出登录
5 |
6 | export default {
7 | state: JSON.parse(sessionStorage.getItem('user')) || {},
8 | mutations: {
9 | [USER_SIGNIN](state, user) {
10 | sessionStorage.setItem('user', JSON.stringify(user))
11 | Object.assign(state, user)
12 | },
13 | [USER_SIGNOUT](state) {
14 | sessionStorage.removeItem('user')
15 | Object.keys(state).forEach(k => Vue.delete(state, k))
16 | }
17 | },
18 | actions: {
19 | [USER_SIGNIN]({commit}, user) {
20 | commit(USER_SIGNIN, user)
21 | },
22 | [USER_SIGNOUT]({commit}) {
23 | commit(USER_SIGNOUT)
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import VueRouter from 'vue-router'
3 |
4 | import routes from './config/routes'
5 | import store from './store/'
6 | import components from './components/' //加载公共组件
7 |
8 | import './css/common.css'
9 | import './less/common.less'
10 |
11 | Object.keys(components).forEach((key) => {
12 | var name = key.replace(/(\w)/, (v) => v.toUpperCase()) //首字母大写
13 | Vue.component(`v${name}`, components[key])
14 | })
15 |
16 | Vue.use(VueRouter)
17 |
18 | const router = new VueRouter({
19 | routes
20 | })
21 | router.beforeEach(({meta, path}, from, next) => {
22 | var { auth = true } = meta
23 | var isLogin = Boolean(store.state.user.id) //true用户已登录, false用户未登录
24 |
25 | if (auth && !isLogin && path !== '/login') {
26 | return next({ path: '/login' })
27 | }
28 | next()
29 | })
30 |
31 | new Vue({ store, router }).$mount('#app')
--------------------------------------------------------------------------------
/src/components/header.vue:
--------------------------------------------------------------------------------
1 |
25 |
26 |
35 |
36 |
--------------------------------------------------------------------------------
/src/pages/index/index.vue:
--------------------------------------------------------------------------------
1 |
13 |
14 |
15 |
16 | {{user.name}}
17 |
18 |
19 | 你还未登录,请先登录
20 |
21 |
22 |
23 | 哈哈,恭喜你已经入坑Vue2
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/config/routes.js:
--------------------------------------------------------------------------------
1 | import App from '../app'
2 | /**
3 | * auth true登录才能访问,false不需要登录,默认true
4 | */
5 | export default [
6 | {
7 | path: '/',
8 | component: App,
9 | children: [
10 | {
11 | path: '/login', //登录
12 | meta: { auth: false },
13 | component: resolve => require(['../pages/login/'], resolve)
14 | },
15 | {
16 | path: '/signout', //退出
17 | component: resolve => require(['../pages/signout/'], resolve)
18 | },
19 | {
20 | path: '/home', //个人主页
21 | component: resolve => require(['../pages/home/'], resolve)
22 | },
23 | {
24 | path: '/', //首页
25 | meta: { auth: false },
26 | component: resolve => require(['../pages/index/'], resolve)
27 | },
28 | {
29 | path: '*', //其他页面,强制跳转到登录页面
30 | redirect: '/login'
31 | }
32 | ]
33 | }
34 | ]
--------------------------------------------------------------------------------
/docs/2.md:
--------------------------------------------------------------------------------
1 | ## 2.实现登录退出
2 |
3 | ### 1.页面访问入口html
4 | [src/template/index.html](../src/template/index.html)
5 |
6 | ### 2.程序入口文件
7 | [src/main.js](../src/main.js) 加载各种公共的css,less,字体图标,组件,权限验证,等
8 |
9 | ### 3.vuex
10 | [src/store/index.js](../src/store/index.js) 加载各种模块,实例化
11 | [src/store/user.js](../src/store/user.js) 创建用户状态模块
12 |
13 | ### 4.配置路由
14 | [src/config/routes.js](../src/config/routes.js) 按需加载模块
15 | [src/app.vue](../src/app.vue) 可以放置一些公共头部或底部
16 |
17 | ### 5.登录页面
18 | [src/pages/login/index.vue](../src/pages/login/index.vue) 将用户的数据存储在vuex中
19 | [src/component/index.js](../src/component/index.js) 加载各种公共组件
20 | [src/component/header.vue](../src/component/header.vue) 公共头部组件
21 |
22 | ### 6.个人中心
23 | [src/pages/home/index.vue](../src/pages/home/index.vue) 从vuex中读取用户的数据
24 |
25 | ### 7.退出登录
26 | [src/pages/signout/index.vue](../src/pages/signout/index.vue) 删除vuex中的用户数据
27 |
28 | ### 8.首页
29 | [src/pages/index/index.vue](../src/pages/index/index.vue) 根据用户登录,显示对应的内容
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | const gulp = require('gulp')
2 | const path = require('path')
3 | const config = require('./config/')
4 | const isEnv = process.env.NODE_ENV == 'production'
5 |
6 | /**
7 | * 清除生产目录文件
8 | */
9 | const del = require('del')
10 | gulp.task('clean', ['upload'], function (callback) {
11 | console.log('## 已经成功部署到服务器上')
12 | console.log('## 清除原来编译的代码')
13 | del(['.' + config.publicPath], callback)
14 | })
15 |
16 | /**
17 | * 编译代码
18 | */
19 | const webpack = require('webpack')
20 | const webpackConfig = require('./webpack.config')
21 | gulp.task('build', function (callback) {
22 | console.log('## 代码编译开始')
23 | webpack(webpackConfig, function (err, state) {
24 | console.log('## 代码编译完成')
25 | callback(err)
26 | })
27 | })
28 |
29 | /**
30 | * 编译代码,自动部署到服务器
31 | */
32 | const ftp = require('gulp-sftp')
33 | gulp.task('upload', ['build'], function (callback) {
34 | console.log('## 正在部署到服务器上')
35 | var dev = isEnv ? config.devDist : config.devTest
36 | gulp.src('.' + config.publicPath + '**')
37 | .pipe(ftp(Object.assign(dev, {callback})))
38 | })
39 |
40 | /**
41 | * 上传到测试服务器上
42 | */
43 | gulp.task('devTest', ['build', 'upload', 'clean'])
44 |
45 | /**
46 | * 上传到生产服务器上
47 | */
48 | gulp.task('devDist', ['build', 'upload', 'clean'])
49 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-demo",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "node server",
8 | "dev:dist": "cross-env NODE_ENV=production gulp devDist",
9 | "dev:test": "gulp devTest"
10 | },
11 | "author": "",
12 | "license": "ISC",
13 | "devDependencies": {
14 | "autoprefixer-loader": "^3.2.0",
15 | "babel-core": "^6.18.0",
16 | "babel-helper-vue-jsx-merge-props": "^2.0.1",
17 | "babel-loader": "^6.2.7",
18 | "babel-plugin-syntax-jsx": "^6.18.0",
19 | "babel-plugin-transform-object-assign": "^6.8.0",
20 | "babel-plugin-transform-vue-jsx": "^3.1.1",
21 | "babel-preset-es2015": "^6.18.0",
22 | "babel-preset-stage-0": "^6.16.0",
23 | "cross-env": "^3.1.3",
24 | "css-loader": "^0.25.0",
25 | "del": "^2.2.2",
26 | "file-loader": "^0.9.0",
27 | "gulp": "^3.9.1",
28 | "gulp-sftp": "^0.1.5",
29 | "html-webpack-plugin": "^2.24.0",
30 | "less": "^2.7.1",
31 | "less-loader": "^2.2.3",
32 | "style-loader": "^0.13.1",
33 | "url-loader": "^0.5.7",
34 | "vue-loader": "^9.7.0",
35 | "webpack": "^1.13.3",
36 | "webpack-dev-server": "^1.16.2"
37 | },
38 | "dependencies": {
39 | "vue": "^2.1.4",
40 | "vue-router": "^2.1.1",
41 | "vuex": "^2.0.0"
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/pages/login/index.vue:
--------------------------------------------------------------------------------
1 |
19 |
20 |
21 |
22 | 返回
23 |
24 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/docs/1.md:
--------------------------------------------------------------------------------
1 | ## 1.安装开发环境
2 | #### vs code https://code.visualstudio.com
3 | ```
4 | 开发时所用的编辑器,内置了终端,开发时使它执行命令运行程序
5 | ```
6 | #### Node.js https://nodejs.org
7 | ```
8 | JS服务器端的运行环境,内置npm包管理器,管理项目依赖的各种模块,编译代码,自动部署到服务器就全靠他了
9 | ```
10 |
11 | ### 2.安装全局模块
12 | #### webpack
13 | ```
14 | npm install -g webpack
15 | ```
16 | webpack是一款模块加载器兼打包工具,它能把各种资源,例如JS(含JSX)、coffee、样式(含less/sass)、图片等都作为模块来使用和处理
17 |
18 |
19 | #### gulp
20 | ```
21 | npm install -g gulp
22 | ```
23 | gulp是一个自动化构建工具,开发者可以使用它在项目开发过程中自动执行常见任务
24 |
25 | ### 3.创建项目
26 | ```
27 | 创建项目目录,并且在项目目录下执行命令,初始化package.json文件
28 | npm init
29 | ```
30 |
31 | ### 4.安装开发环境依赖模块 npm install --save-dev 模块名
32 | ```
33 | npm install --save-dev webpack webpack-dev-server html-webpack-plugin url-loader file-loader css-loader less less-loader style-loader autoprefixer-loader babel-core babel-loader babel-plugin-transform-object-assign babel-preset-es2015 babel-preset-stage-0 vue-loader babel-helper-vue-jsx-merge-props babel-plugin-syntax-jsx babel-plugin-transform-vue-jsx gulp gulp-sftp del cross-env
34 | ```
35 | ### 5.安装生产环境依赖模块 npm install --save 模块名
36 | ```
37 | npm install --save vue vue-router vuex
38 | ```
39 |
40 | ### 5.搭建开发环境
41 | + [config/index.js](../config/index.js) 配置项目开发时的信息
42 | + [webpack.config.js](../webpack.config.js) webpack打包配置
43 | + [.babelrc](../.babelrc) ES6编译配置
44 | + [server.js](../server.js) 设置代理服务器
45 | + [gulpfile.js](../gulpfile.js) 自动化打包,编译,压缩,部署服务器
46 | + [package.json](../package.json) 执行npm init 初始化项目,自定义命令,启动程序,自动部署
47 |
48 | ### 6.测试编译
49 | #### src/template/index.html
50 | ```html
51 |
52 |
53 |
54 |
55 |
56 | vue2-demo
57 |
58 |
59 |
60 |
61 |
62 |
63 | ```
64 | #### src/main.js
65 | ```javascript
66 | alert('test')
67 | ```
68 | ```
69 | 1.运行程序执行命令:npm run dev
70 | 2.然后打开网址:http://localhost:3000/app/
71 | 3.如果浏览器弹出test,说明我们的开发环境已经搭建通过。
72 | ```
73 | #### package.json自定义命令说明
74 | ```
75 | npm run dev 开发环境
76 | npm run dev:test 将代码打包到测试服务器
77 | npm run dev:dist 将代码打包到正式服务器
78 | ```
79 |
80 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const webpack = require('webpack')
3 | const HtmlWebpackPlugin = require('html-webpack-plugin')
4 | const config = require('./config/')
5 | const IS_ENV = process.env.NODE_ENV == 'production'
6 |
7 |
8 | var plugins = []
9 | if (IS_ENV) { //生产环境
10 | plugins.push(new webpack.DefinePlugin({
11 | 'process.env': { //设置成生产环境
12 | NODE_ENV: '"production"'
13 | }
14 | }))
15 | plugins.push(new webpack.optimize.UglifyJsPlugin({ //压缩代码
16 | compress: {
17 | warnings: false
18 | }
19 | }))
20 | }
21 |
22 | plugins.push(
23 | new HtmlWebpackPlugin({ //根据模板插入css/js等生成最终HTML
24 | filename: './index.html', //生成的html存放路径,相对于 path
25 | template: './src/template/index.html', //html模板路径
26 | })
27 | )
28 |
29 |
30 | module.exports = {
31 | entry: ['./src/main.js'], //编译入口文件
32 | output: {
33 | publicPath: config.publicPath, //服务器的路径
34 | path: path.resolve(__dirname + config.publicPath), //编译到app目录
35 | filename: '[name].js?[hash]' //编译后的文件名
36 | },
37 | module: {
38 | loaders: [
39 | {
40 | test: /\.js(x)*$/,
41 | exclude: /^node_modules$/,
42 | loader: 'babel'
43 | },
44 | {
45 | test: /\.vue$/,
46 | loader: 'vue'
47 | },
48 | {
49 | test: /\.css/,
50 | exclude: /^node_modules$/,
51 | loader: `style-loader!css-loader!autoprefixer-loader?{ browsers: ['last 100 versions'] }!`
52 | },
53 | {
54 | test: /\.less/,
55 | exclude: /^node_modules$/,
56 | loader: `style-loader!css-loader!autoprefixer-loader?{ browsers: ['last 100 versions'] }!less-loader`
57 | },
58 | {
59 | test: /\.(png|jpg)$/,
60 | exclude: /^node_modules$/,
61 | loader: 'url?limit=2000&name=[name].[ext]' //注意后面那个limit的参数,当你图片大小小于这个限制的时候,会自动启用base64编码图片
62 | },
63 | {
64 | test: /\.(eot|woff|svg|ttf|woff2|gif|appcache)(\?|$)/,
65 | exclude: /^node_modules$/,
66 | loader: 'file-loader?name=[name].[ext]'
67 | }
68 | ]
69 | },
70 | plugins,
71 | resolve: {
72 | extensions: ['', '.js', '.vue', '.jsx'], //后缀名自动补全
73 | alias: {
74 | vue: 'vue/dist/vue.js', //webpack打包时,需要设置别名
75 | store: path.resolve('src/store/'), //常用工具方法
76 | }
77 | },
78 | vue: {
79 | postcss: [
80 | require('autoprefixer')({
81 | browsers: ['last 100 versions']
82 | })
83 | ]
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## 前言
2 | ```
3 | 国庆在回家的路上,得知了vue2发布了正式版,
4 | 国庆回来后,在公司内两个项目便直接应用上了vue2,
5 | 一个是PC端的商户后台,一个是微信端商城,
6 | 都是基于Vue2、vue-router、vuex ......
7 | 在开发的过程中,遇到了一系列的问题,
8 | 比如页面后退数据还原,滚动条还原,
9 | 登录超时,获取列表数据,表单提交,
10 | 多台服务器自动化部署,最终后一个个解决了,
11 | 能够平稳的从react切换到vue2开发,vue的文档功不可没。
12 | ```
13 | github:[https://github.com/lzxb/vue2-demo](https://github.com/lzxb/vue2-demo)
14 |
15 | ## 源码说明
16 | ### 项目目录说明
17 | ```
18 | .
19 | |-- config // 项目开发环境配置
20 | | |-- index.js // 项目打包部署配置
21 | |-- src // 源码目录
22 | | |-- components // 公共组件
23 | | |-- header.vue // 页面头部公共组件
24 | | |-- index.js // 加载各种公共组件
25 | | |-- config // 路由配置和程序的基本信息配置
26 | | |-- routes.js // 配置页面路由
27 | | |-- css // 各种css文件
28 | | |-- common.css // 全局通用css文件
29 | | |-- iconfont // 各种字体图标
30 | | |-- images // 公共图片
31 | | |-- less // 各种less文件
32 | | |-- common.less // 全局通用less文件
33 | | |-- pages // 页面组件
34 | | |-- home // 个人中心
35 | | |-- index // 网站首页
36 | | |-- login // 登录
37 | | |-- signout // 退出
38 | | |-- store // vuex的状态管理
39 | | |-- index.js // 加载各种store模块
40 | | |-- user.js // 用户store
41 | | |-- template // 各种html文件
42 | | |-- index.html // 程序入口html文件
43 | | |-- util // 公共的js方法,vue的mixin混合
44 | | |-- app.vue // 页面入口文件
45 | | |-- main.js // 程序入口文件,加载各种公共组件
46 | |-- .babelrc // ES6语法编译配置
47 | |-- gulpfile.js // 启动,打包,部署,自动化构建
48 | |-- webpack.config.js // 程序打包配置
49 | |-- server.js // 代理服务器配置
50 | |-- README.md // 项目说明
51 | |-- package.json // 配置项目相关信息,通过执行 npm init 命令创建
52 | .
53 | ```
54 |
55 | ### 开发环境依赖模块说明
56 | #### webpack相关模块
57 | ```
58 | webpack // 用来构建打包程序
59 | webpack-dev-server // 开发环境下,设置代理服务器
60 | html-webpack-plugin // html 文件编译
61 | url-loader // 图片 转化成base64格式
62 | file-loader // 字体 将字体文件打包
63 | css-loader // css 生成
64 | less // css 预处理器less
65 | less-loader // css 预处理器less的webpack插件
66 | style-loader // css 插入到style标签
67 | autoprefixer-loader // css 浏览器兼容性问题处理
68 | babel-core // ES6 代码转换器
69 | babel-loader // ES6 代码转换器,webpack插件
70 | babel-plugin-transform-object-assign // ES6 Object.assign方法做兼容处理
71 | babel-preset-es2015 // ES6 代码编译成现在浏览器支持的ES5
72 | babel-preset-stage-0 // ES6 ES7要使用的语法阶段
73 | vue-loader // vue 组件编译
74 | babel-helper-vue-jsx-merge-props // vue jsx语法编译
75 | babel-plugin-syntax-jsx // vue jsx语法编译
76 | babel-plugin-transform-vue-jsx // vue jsx语法编译
77 | ```
78 |
79 | #### gulp相关模块
80 | ```
81 | gulp // 用来构建自动化工作流
82 | gulp-sftp // 将代码自动部署到服务器上
83 | del // 代码部署成功后,删除本地编译的代码
84 | ```
85 | #### 其他模块
86 | ```
87 | cross-env // 解决跨平台设置NODE_ENV的问题
88 | ```
89 | ### 生产模块依赖说明
90 | #### vue全家桶
91 | ```
92 | vue // 构建用户界面的
93 | vue-router // 路由
94 | vuex // 组件状态管理
95 | ```
96 |
97 | ### 页面说明
98 | ```
99 | /login // 登录,不需要登录可以访问
100 | /signout // 退出登录,需要登录后才可以访问
101 | /home // 个人中心,需要登录后才可以访问
102 | / // 首页,不需要登录可以访问
103 | * // 强制跳转到登录页面
104 | ```
105 |
106 | ### 运行程序
107 | ```
108 | npm install
109 | npm run dev
110 | http://localhost:3000/app/
111 | ```
112 |
113 | ## 开发教程
114 | [1.开发环境搭建](https://github.com/lzxb/vue2-demo/blob/master/docs/1.md)
115 | [2.实现登录退出](https://github.com/lzxb/vue2-demo/blob/master/docs/2.md)
116 |
--------------------------------------------------------------------------------