王羽彪 | 学习前端


  • 首页

  • 归档

  • 标签

'vuex'

发表于 2017-07-08

Vuex

Vuex是一个转为Vue.js程序开发的状态管理模式.用来几种管理所有组件的状态,并以响应的规则保证状态以一种可预测的方式发生变化.

  • Vue的官方调试工具

状态管理应用包含三个部分

  1. state, 驱动应用的数据源
  2. view, 以声明方式将state映射到视图
  3. actions, 响应在view上的用户输入导致的状态变化

全局单例模式管理,可以将组建构成一个巨大的’视图’,不管在树的哪个位置,任何组建都能获取状态或者触发行为!

在简单的页面下可以使用event bus($on,$off,$emit)

  1. 没一个Vuex应用的核心就是store,’store’基本上就是一个容器,包含着应用中的大部state。Vuex和单纯的全局对象有一下两点不同:
    • 状态储存响应式
    • 不能直接改变store中的state

store 最简单的store实现

1
2
3
4
5
6
const store = new Vuex.Store({
state:{count:0},
matations:{
increment(state){state.count++}
}
})

State 单一状态树

Vuex使用单一状态树 – 用一个对象包含了全部的应用层级状态.作为一个(唯一数据源存在)SSOT.

在Vue组件中获得Vuex状态

Vuex 的状态储存是响应式的,从store实例中读取状态最简单的是在计算属性(computed)中直接返回某个状态

1
2
3
4
5
6
7
8
9
10
11
12
const Counter = {
template:`<div>{{count}}</div>`,
computed(){
count(){
return store.state.count
}
}
}
//在创建Vue实例时注入组件中(Vue.use(Vuex))
const app = new Vue({sotre})

每当store.state.count变化的时候,都会重新求取计算属性,并且触发更新相关联的DOM.

注入后能够通过this.$store访问到

mapState 辅助函数

当组件需要获取多个状态的时候,将这些状态都声明为计算属性会有些重复和冗余,因此使用mapState()可以帮助我们生成计算属性

js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import {mapState} from 'vuex'
export default{
computed:mapState({
count:state=>state.count,
//传字符串参数'count'等同于'state=>state.count'
countAlias:'count',
//为了能够使用this获取局部状态,必须使用常规函数
countPlusLocalState (state){
return state.count+this.localCount
}
})
}

当映射的计算属性的名称与state的子节点名称相同时,可以给mapState传递一个数组

js
1
computed:mapState(['count'])

对象展开运算符

js
1
2
3
4
5
6
computed:{
localComputed(){},
...mapstate({
// ...
})
}

Getter

有时候我们需要从store中的state中派生出一些状态,例如对列表进行过滤并计数

js
1
2
3
4
5
computed: {
doneTodosCount () {
return this.$store.state.todos.filter(todo => todo.done).length
}
}

Vuex 允许在store中定义getters对象

js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
},
// Getters可以接收getters作为第二个参数
doneTodosCount: (state, getters) => {
return getters.doneTodos.length
}
}
})
//可以较为容易的在任何组件中使用它:
computed:{
donTodosCount(){
return this.$store.getters.doneTodosCount
}
}

mapGetters 辅助函数

js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { mapGetters } from 'vuex'
export default {
// ...
computed: {
// 使用对象展开运算符将 getters 混入 computed 对象中
...mapGetters([
'doneTodosCount',
'anotherGetter',
// ...
])
}
}
//将一个 getter 属性另取一个名字,使用对象形式:
mapGetters({
// 映射 this.doneCount 为 store.getters.doneTodosCount
doneCount: 'doneTodosCount'
})

Mutations

更改Vuex的sotre中的位移方法是提交matation。每个mutation都有一个字符串的type和一个handler().这个回调函数就是我们实际进行状态修改的地方,并且它会接收state作为第一个参数

js
1
2
3
4
5
6
7
8
9
10
11
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
// 变更状态
state.count++
}
}
})

需要在组件中调用相应的type调用store.commit方法:

1
2
3
4
5
6
7
8
9
10
mutations定义的方法可以传入第二个参数即荷载(payload)
```apple js
// ...
mutations: {
increment (state, n) {
state.count += n
}
}
store.commit('increment', 10)

大多数请概况下payload应该是一个Object,这样可以包含多个字段并且记录mutation会更易读

提交mutation的另一种风格

js
1
2
3
4
store.commit({
type: 'increment',
amount: 10 //payload
})

Mutations需要遵守的Vue的响应规则

  1. 最好在store中初始化好所有所需属性
  2. 当需要在对象上添加新属性时,你应该
    • 是用Vue.set(obj,'newProp',12)
    • 以新对象替换老对象:state.obj = {...state.obj,newProp:123}

mutations方法名称最好用常量替代
mutations 必须是同步函数
在组件中使用this.$store.commit('xxx')提交mutation,或者使用mapMutations()将组件中的methods映射为store.commit调用

js
1
2
3
4
5
6
7
8
9
10
11
12
13
import { mapMutations } from 'vuex'
export default {
// ...
methods: {
...mapMutations([
'increment' // 映射 this.increment() 为 this.$store.commit('increment')
]),
...mapMutations({
add: 'increment' // 映射 this.add() 为 this.$store.commit('increment')
})
}
}

Actions

Action类类似于mutation,不同在于:

- Action提交的是mutation,而不是直接变更状态
- Action可以包含任意异步操作
js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})

Action函数接收一个与store对象具有相同方法和属性的context对象。

可以用到结构赋值

js
1
2
3
4
5
actions:{
increment({commit}){
commit('increment')
}
}

通过store.dispatch()方法触发

js
1
store.dispatch('increment');
  1. 可以内嵌异步方法
  2. Actions同Mutation一样支持payload和对象方式进行发布
  3. 调用异步API和分发多从mutations

    购物车例子

    js
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    actions: {
    checkout ({ commit, state }, products) {
    // 把当前购物车的物品备份起来
    const savedCartItems = [...state.cart.added]
    // 发出结账请求,然后乐观地清空购物车
    commit(types.CHECKOUT_REQUEST)
    // 购物 API 接受一个成功回调和一个失败回调
    shop.buyProducts(
    products,
    // 成功操作
    () => commit(types.CHECKOUT_SUCCESS),
    // 失败操作
    () => commit(types.CHECKOUT_FAILURE, savedCartItems)
    )
    }
    }

组件中分发Action

在组件中使用this.$store.dispatch('xxx')分发action,或者使用mapActions()辅助函数将组件的methods映射为store.dispatch调用

js
1
2
3
4
5
6
7
8
9
10
11
12
13
import { mapActions } from 'vuex'
export default {
// ...
methods: {
...mapActions([
'increment' // 映射 this.increment() 为 this.$store.dispatch('increment')
]),
...mapActions({
add: 'increment' // 映射 this.add() 为 this.$store.dispatch('increment')
})
}
}

组合Actions

dispatch()可以处理被触发的action的回调函数返回的Promise,并且store.dispatch()返回的仍旧是Promise

js
1
2
3
4
5
6
7
8
9
10
actions:{
actionA({commit}){
return Promise((resolve,reject)=>{
setTimeout(() => {
commit('someMutation')
resolve()
}, 1000)
})
}
}

现在你可以:

1
2
3
store.dispatch('actionA').then(() => {
// ...
})

在另外一个 action 中也可以:

1
2
3
4
5
6
7
8
9
actions: {
// ...
actionB ({ dispatch, commit }) {
return dispatch('actionA').then(() => {
commit('someOtherMutation')
})
}
}

最后,如果我们利用 async / await 这个 JavaScript 即将到来的新特性,我们可以像这样组合 action:

假设 getData() 和 getOtherData() 返回的是 Promise

1
2
3
4
5
6
7
8
9
actions: {
async actionA ({ commit }) {
commit('gotData', await getData())
},
async actionB ({ dispatch, commit }) {
await dispatch('actionA') // 等待 actionA 完成
commit('gotOtherData', await getOtherData())
}
}

Modules (https://vuex.vuejs.org/zh-cn/modules.html)

项目结构

  1. 应用层级的状态应该集中到单个store对象中.
  2. 提交mutation是更改状态的位一方法,并且这个过程是同步的.
  3. 异步逻辑都应该封装到action里面.

对于大型应用,Vuex相关代码分割到模块中.下面是项目结构示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
├── index.html
├── main.js
├── api
│ └── ... # 抽取出API请求
├── components
│ ├── App.vue
│ └── ...
└── store
├── index.js # 我们组装模块并导出 store 的地方
├── actions.js # 根级别的 action
├── mutations.js # 根级别的 mutation
└── modules
├── cart.js # 购物车模块
└── products.js # 产品模块

插件

'vue-cli'

发表于 2017-07-05

Vue-cli是Vue的脚手架工具

帮助我们写好Vue.js基础代码的工具.

  1. 目录结构
  2. 本地调试
  3. 代码部署
  4. 热加载
  5. 单元测试
1
npm install -g cue-cli

webpack 环境搭建

  1. vue init webpack sell
  2. cd sell
  3. npm install
  4. npm start

目录文件

  1. build
  2. config
  3. node_modules 依赖包
  4. src源码
    • assets
    • components
  5. static 静态文件
  6. .babelrc babel编译配置
    • “preset” 预设插件
    • “plugins” 插件
    • “comments”:false false表示编译后代码不包含注释
  7. editorconfig
    • charset 编码
    • indent_style 缩进风格
    • indent_size
    • end_of_line 换行符
    • inset_final_newline
    • trim_trailing_whitespace true自动移除行尾多余空格
  8. .eslintignore
  9. .eslintrc.js eslint的配置文件
  10. .gitignore git忽略文件
  11. index.html 主html
  12. package.json 项目描述
    • “script” 配置脚本命令
  13. README.md

Webpack 打包

1
2
3
4
resolve = {
extensions:['','js','.vue']//自动识别后缀
}
slias //模板中用到fequire时 通过设置别名来缩短路径长度
  • module
    • preLoader
    • loaders
      • include 只针对指定目录编译
      • exclude 编译时不包含目录
      • url-loader query{limit 限制大小(超过后形成一个独立文件)}
    • eslint formatter 查看eslink错误原因
    • vue:{loader:}

webpack打包工具'

发表于 2017-07-01

npm包

1
2
3
4
5
webpack
$ npm install webpack webpack-dev-server html-webpack-plugin -D
babel
$ npm install babel-core babel-preset-es2015 babel-preset-stage-0 babel-loader babel-preset-react babel-plugin-transform-decorators-legacy -D
  1. 热替换/热加载,当修改代码时,大多情况下所改动的地方会实时反映到页面中,而这个过程并没有刷新页面。
    1
    webpack-dev-server --hot -inline

基本概念

  • 模块规范/CommonJS、AMD
  • 分支/chunks
  • 加载器/loader
  • 插件/plugins

分支

webpack擅长的是讲台资源的打包,如果希望异步加载,可以通过Code Splitting(裂开)的方式实现

1
2
3
4
require.ensure(['b'],function() {
var b = require('b')
})
//经过webpack打包后,或生成1.js,这里的名字可以配置的

加载器

1
2
3
4
5
module:{
loaders:[
{test:/.js$/,loaders:['babel-loader'],exclude:/node_modules/}
]
}

webpack

webpack是一个模块绑定器,其主要作用是将js文件捆绑在浏览器中,但也可以转换、捆绑、或者打包任何资源和有用的东西

安装

npm install --save-dev webpack

插件

  • common-chunks-webpack-plugin 生成entry文点共享的模块(e.g. vendor.bundle.js && app.bundle.js)
  • extract-text-webpack-plugin 从bundles提取css文本到一个独立的文件(e.g. app.bundle.css)
  • component-webpack-plugin 使用webpack组件
  • compression-webpack-plugin 准备生成压缩版本
  • i18n-webpack-plugin 为你的bundles加入i18n支持
  • html-webpack-plugin 为你的bundles加入i18n支持(index.html)

    file loaders

  • raw-loader 加载文件的原内容(utf-8)
  • val-loader 将代码当多模块执行并且视为js导出
  • url-loader 像file loader 但是当文件小于限制的大小的时候会返回一个数据地址
  • file-loader 将文件发送到输出文件夹并返回相对路径(url)

    JSON loaders 加载并转发JSON文件

    transpiling loaders(将一种源码转换为另一种源码,转译)

  • script-loader 在全局环境下执行一次js文件(如脚本标签),不需要解析
  • babel-loader 加载es2015以上版本并且使用Babel转译为ES5
  • traceur-loader 加载es2015以上版本并且使用Traceur转译为ES5
  • ts-loader 样js一样加载TypeScript
  • coffeScript 像js一样加载CoffeeScript

    templating loaders

  • html-loader 将HTML作为字符串导出,需要吧把静态资源当做参考
  • pug-loader 加载Pug模板并且返回一个函数
  • jade-loader 加载jade模板并且返回一个函数
  • markdown-loader 将Markdown转译为HTML
  • posthtml-loader 使用PostHTML加载并转换HTML文件
  • handlebars-loader 将Handlebars转译成HTML

    Styling loaders

  • style-loader 将导出的模板作为样式添加到DOM
  • css-loader 加载通过相对路径使用import导入的CSS文件并且返回CSS代码
  • less-loader 加载并编译LESS文件
  • sass-loader 加载并编译SASS文件
  • stylus-loader 加载并编译Stylus文件
  • postcss-loader 使用PostCSS加载并转换一个CSS/SSS文件

    Linting&&Testing loader

  • mocha-loader 用mocha测试(浏览器/node)
  • eslint-loader 使用ESLint为静态代码的解析(linting code)提供预加载
  • jsHint-loader 使用JSHint为静态代码的解析提供预加载
  • jscs-loader 使用JSCS为代码代码样式校验提供预加载

    framworks loaders

  • vue-loader
  • polymer-loader 处理HTML&&CSS使用预处理器和通过require()导入的Web组件像一级模块一样
  • angular2-template-loader 加载和转译Angular2组件
  • tag-loader Riot官方webpack处理器

    性能 Performance

    webpack使用异步的I/O接口,并具有多个缓存级别。这使webpack拥有快速和难以置信的增量编译速度

    Module Formats

    webpack支持es2015+,CommonJS和AMD模块开箱可用。它对你的代码中的AST执行聪明的静态分析。它甚至有一评估引擎来评估简单的表达。着可以让你即可使用大多数现有的库.

    Code Splitting

    webpack允你将你的代码库拆分成多个模块.模块在运行的时异步加载,这会减少你的初始加载时间

    Optimizations 优化

    webpack 可以许多优化,通过重复使用经常使用的模块进行重复数据的删除,最小化并让你完全控制最初加载的内容并且通过运行时进行代码拆分来减少js输出的大小.它也可以通过hashes让你的代码块缓存友好。

(https://www.npmjs.com/package/webpack)[官方文档]

class'

发表于 2017-06-03

'redux'

发表于 2017-05-25

取消订阅

1
2
3
4
5
6
7
8
9
//订阅方法执行后会返回一个取消订阅的函数,用于取消定于
let subscribe = (listener) => { //订阅仓库内的状态变化事件,当状态发生变化之后会调用对应的监听函数
listeners.push(listener);
return ()=>{
listeners.filter(l=>{
return listener!==l;
})
}
};

'mongoDB'

发表于 2017-05-20

Robomongo

如何启动数据库

  1. 新建一个空白目录(非C盘) 比如 d:\mongoData
  2. 启动服务器

    1
    $ mongod --dbpath=[filePath]
  3. 连接服务器,在bin目录下执行命令

    1
    $ mongo
  4. 如何停止数据库

    • 切换到admin数据库,并关闭数据库
      1
      2
      $ use admin
      $ db.shutdownServer
  5. 如何查看当前在哪个数据库下面

    1
    db

mongoose

  1. 加载mongoose模块

    1
    let mongoose = require('mongoose');
  • 客户端 是用来操作数据库的,对数据库中的数据进行增删改查
  • 数据库的连接地址格式: mongodb://
    1
    2

'cookie'

发表于 2017-05-14

'express总结'

发表于 2017-05-13

1.Express介绍

Express是一个简洁、灵活的node.js Web应用开发框架,是目前最流行的Node.js的Web开发框架,它提供一系列强大的功能,比如:

  • 模板解析(render())
  • 静态文件服务(express.static())
  • 中间件(app.use())
  • 路由控制(express.Router)

    2. 使用express

    本地安装
    1
    $ npm install express

获取、引用 通过变量app我们就可以调用express的各种方法

1
2
3
let express = require('express')
let app = express();
app.listen(port)

? express本质上是什么,是如何工作的呢?

3. get请求

根据请求路径来处理客户端发出的GET请求 语法

1
app.get(path,(req,res)=>{})

  • 第一个参数path为请求的路径
  • 第二个参数为处理请求的回调函数,有两个参数分别是
    • request 请求信息
    • response 响应信息
      1
      2
      3
      4
      5
      6
      7
      8
      9
      let express = require('express')'
      let app = express();
      app.get('/',(req,res)=>{
      res.end('welcome to Home!')
      })
      app.get('/list'/(req,res)=>{
      res.end('welcome to List');
      })
      app.listen(3000);

4. curl客户端使用方法

  • 可以用 postman APIs请求模拟发送
  • 指定请求头

    1
    $ curl -H 'content-type:application/json;charset=utf8' http://localhost:8888
  • 指定方法名

    浏览器的地址行不能发送出post请求

    1
    $ curl -X POST http://loaclhost:8000/user
  • 指定请求体

    1
    curl --data "name=zfpx&age=8" http://loaclhost:8000/user

    all

    app.all()可以匹配所有的HTTP动词 路由中的星号能匹配所有的路径

    1
    app.all(path,(req,res)=>{})

实例:

1
2
3
4
5
let express = require('express');
let app = express();
app.all('*',(req,res)=>{
send(404)
})

6. 获取请求参数

  • req.host 返回请求头里取的主机名(不包含port)
  • req.path URL的路径名
  • req.query

    7. 获得查询字符串

    1
    2
    3
    4
    // http://localhost:3000/?a=1&&c=3
    app.get('/',(req,res)=>{
    res.send(req.query)
    })

8. params路径参数

req.params 可以用来获取请求URL中的参数值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
app.get(/:aid/:name,(req,res)=>{
res.send(req.params.id + '' + req.params.name)
})
//http://localhost:3000/6/wang
//params = {aid:6,name='wang'}
```
## 9. 中间件
中间件就是处理HTTp请求的函数,用来完成各种特定的任务,比如检查用户是否登录,检测用户是否有访问权限等,它的特点是:
- 一个中间件处理完请求和响应可以把响应数据再传递给下一个中间件
- 回调函数next参数,表示接受其他中间件的调用,函数体中的next()表示将请求数据传递给下一个中间件
- 还可以根据路径来区分进行返回执行不同的中间件
```$xslt
let express = require('express');
let app = rexpress();
let path = require('path');
app.use((req,res,next)=>{
res.setHeader('Content-Type','text/plain;charset=utf8);
next()
})
app.get('/',(req,res)=>{
res.end('首页');
})
app.get('/list/,(req,res)=>{
res.end('这是列表页');
})
app.listen(3000)

10. send

send()想浏览器发送一个响应信息,并可以智能处理不同数据类型的,并在输出响应时会自动进行一些设置,比如HEAD信息, HTTP缓存处理不同类型的数据.语法:

1
res.send([resBody|status],[body])

  1. 实例一: 当参数为一个String时,Content-Type默认设置为’text/html’.

    1
    res.send('Hello World'); // Hello World
  2. 当参数为Array或Object时,Express会返回一个JSON

    1
    2
    res.send({user:'tobi'}) // {"user":"tobi"}
    res.send([1,2,3]) //[1,2,3]
  3. 当参数为一个Number时, 并且没有上面提到的任何一条在响应体力,Express会 帮你设置一个响应体,比如:200会返回字符串”OK”

    1
    2
    3
    res.send(200); //OK
    res.send(404); //NOT FOUND
    res.send(500); //Internal Server Error
  4. 可以查看statusCode所对应的状态类型

    1
    require('_http_server').STATUS_CODES

11. 模板

在nodejs中使用expres框架,它默认的是ejs和jade渲染模板

11.2使用模板

使用ejs模板 -> 默认指向views文件夹

1
2
3
4
5
//指定渲染模板文件的后缀名为ejs
app.set('view engine','html');
app.set('views',path.join(__dirname,'views'))
app.set('index');

模板使用html后缀

1
2
3
4
5
//指定渲染模板文件的后缀名为html
app.set('views','view');
app.set('view engine','html');
app.set('html','require('ejs').__express');

11.3渲染视图

语法:

1
res.render(view,{...locals},callback)

  • 参数view就是模板的文件名
  • 在渲染模板时将自定义的data对象和在中间件中定义的locals对象,使用Object.assign(obj1,locals)合并后的属性集作为模板变量值传入
  • callback 用来处理返回的渲染后的字符串

    11.4 模板原理

    1
    2
    3
    4
    5
    6
    let tmp1 = `<h1>{{name}}</h1><h1>{{age}}</h1>`
    let data = {name:'wang',age:18};
    let html = tmp1.replace(/\{\{(\w+)\}\}/g,function(input,group){
    return data[group];
    })
    console.log(html); //`<h1>wang</h1><h1>age</h1>`

12. 静态文件服务器

如果要在网页中加载静态文件(css,js,img),就需要另外指定一个存放静态文件的目录,当浏览器发出非HTML文件请求时,服务器端就会到这个目录下去寻找相关文件

1
2
app.use(express.static(path.join(__dirname,'/')))
app.use(express.static('public'))

13. 重定向

redirect 方法允许网址的重定向

1
res.redirect([status],url);

实例:

1
res.redirect('http://www.baidu.com')

14. POST 请求

post 方法根据请求路径来处理客户端发出的Post请求 语法:

1
app.post(path,(req,res)=>{})

示例:

1
2
3
4
5
let bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extented:true}));
app.post('/login',(req,res)=>{
console.log(req.body.username)
})

16. 中间件的原理

1
2
3
4
5
6
7
8
9
10
11
12
let app = (req,res) =>{
let index = 0;
function next(){
let fn = app.routes[index++];
if(typeof fn ==='function') fn(req,res,next);
}
next();
}
app.routes =[];
app.use = (fn){
app.routes.push(fn);
}

17.params原理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//path为路由的路径
let path = '/users/:name/:age
//客户端发送的url
let url = '/users/wang/18';
let paramKeys =[];
let regStr - path.replace(/:(\w+)/g,(matchedStr,group1){
paramKeys.push(group1)
return '(\\w+)';
})
console.log(regStr); // /users/(\w+)/(\w+)
let reg = new RegExp(regStr); // /\/users\/(\w+)\/(\w+)/
let result = url.match(reg);
//[ '/users/zfpx/8', 'zfpx', '8', index: 0, input: '/users/zfpx/8' ]
let params = {};
for(let i = 0;i<paramKeys.length;i++){
params[paramKeys[i] = result[i+1];
}
console.log(params); //{'name':'wang','age':18}

'express'

发表于 2017-05-13

express是后台框架

  • 帮我们解决了手动搭建服务,处理复杂的逻辑
  • express 是一个函数,执行后返回的是一个监听函数
  • get 要求路径必须绝对匹配到,use匹配开头即可
1
2
npm init -y
npm install express --save

postman 服务端APIs模拟请求工具

1
2
请求API命令行
$ curl -X POST http://localhost:8080/home

express 提供的属性

1
2
3
4
req.path
req.query
req.method
req.headers

路径参数params

  • :id 表示站位必须要有
    1
    app.get('/article/:id',callback)

listen

1
2
3
4
5
6
app.listen(3000);//可以直接使用app监听端口号,如果没有找到对应的逻辑 会出现cannot [request.method]/[pathname]
/*app.listen=function () {
let server = require('http').createServer(this);
server.listen(...arguments);
};*/

all

1
2
3
4
// all 代表所有匹配的方法,*代表所有路径都可以匹配到,一般用来配置404页面,放到所有路由最下面,否则会被截断
app.all('/*',function (req,res) {
res.end('404')
});

use 叫中间件 , 路由

use 叫中间件 , 路由

  • 默认不写路径热呢请求都能进行匹配

  • 中间件在路由最上面执行,先执行中间件 ,再执行路由
  1. 可以写路径,还可以不写路径,不写路径默认是/
  2. 可以拓展属性和方法 类似于 req.path req.query
  3. 可以决定是否向下执行next,若果调用next则可以向下执行
  4. 做权限判断

  5. 从中间件道路有的过程reg和res是同一个,而且中间件可以写多个
    1
    2
    3
    4
    5
    6
    app.use((req,res,next)=>{
    //next 是一个函数,如果调用则据需执行
    console.log('hello');
    res.end('66666'); //如果调用end代码不会继续执行
    next(); //如果要使用use扩展属性或者方法,一定调用next
    });

send()

  1. 可以自动发送json
  2. 可以自动处理编码类型
  3. 数字会转化成状态文本

用send取代end

express 提供了静态服务中间件

1
app.use(express.static('public')); //静态文件中间件可以配置多个

sendFile

  • 向客户端返回单一页面
    1
    2
    res.sendFile(path.resolve('./index.html'));
    res.sendFile('./index.html',{root:__dirname});

静态服务中间件

app.use(express.static(路径))

动态渲染ejs

  • ejs ->基于html,可以渲染动态数据

    1
    $ npm install ejs --save
  • jade

ejs –> 后端渲染``

  • <%js代码%>
  • <%=渲染的数据%>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    app.set('views','view'); //默认为views文件,需要手动更改
    app.set('view engine','html'); //更改渲染的引擎,默认为ejs
    app.engine('html',require('ejs').__express); //对设置后的引擎
    app.get('/',(req,res)=>{
    res.render('index.html', //会默认去views查找
    //param1:要渲染的模板
    // 渲染时采用什么数据
    {
    data:'666666!',
    arr:[1,2,3]
    })
    });

body-parser 第三方form数据解析插件

1
$npm install body-parser --save

'vue-webpack'

发表于 2017-05-10

webpack

1
npm install webpack webpack-dev-server --save-dev

babel

  • 通过.vue文件创建组件
    1
    npm install babel-core babel-loader babel-preset-es2015 babel-preset-stage-0 css-loader vue-loader --save-dev

plugin

1
npm install html-webpack-plugin vue-template-compiler --save-dev

vue

1
npm install vue vue-router --save

vue的使用方式

  • 直接使用vue写代码
  • 工程化的方式

##

1
2
npm install vue-cli -g
npm init webpack <filename>

  • 项目名默认
  • 描述默认
  • 作者默认
  • RUNTIME+compiler(默认第一个)
  • eslink(n)
  • karma+mocha n
  • e2e n

    安装全部依赖

    1
    cd <filename> && npm install

安装vuex

1
npm install vuex --save

##

1
https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd

12…5
王羽彪

王羽彪

技术 | javascript | html | 前端学习

47 日志
77 标签
© 2017 王羽彪
由 Hexo 强力驱动
主题 - NexT.Pisces