| vue-router 路由插件
| vue-validator 表单校验插件
| vue-resource ajax插件

vue-cli3 脚手架

一、安装

    $ npm install -g @vue/cli            // 最新版本3.0

    $ vue create hello-world            // 创建项目 vue create --help

        注意 如果安装sass选择手动

        1、> default (babel, eslint)
         > Manually select features

        2、选择预解释器
        >    (*) CSS Pre-processors                // 空格选择

        // 如果安装2.0的模板
        $ vue init webpack my-project        // vue init webpack-simple#1.0 mynewproject

    $ cd hello-world

    $ yarn serve     // 启动服务

    $ yarn build  // 打包

    // 安装插件
    $ vue add router
    $ vue add vuex


二、package.json

    script: {
        "serve": "vue-cli-service serve --mode test231",
    }

    --mode        指定环境模式 (默认值:production)
    --dest        指定输出目录 (默认值:dist)
    --modern      面向现代浏览器带自动回退地构建应用
    --target      app | lib | wc | wc-async (默认值:app)
    --name        库或 Web Components 模式下的名字 (默认值:package.json 中的 "name" 字段或入口文件名)
    --no-clean    在构建项目之前不清除目标目录
    --report      生成 report.html 以帮助分析包内容
    --report-json 生成 report.json 以帮助分析包内容
    --watch       监听文件变化

    环境变量设置
    script: {
        "serve": "FOO=bar vue-cli-service serve --mode test231",
    }

    vue.config.js中获取
    console.log(process.env.FOO);        // bar


三、vue.config.js 配置

    'use strict'
    module.exports = {

        // 修改webpack配置的方式, 该对象会对webpack-merge合并
        configureWebpack: {
          optimization: {
            splitChunks: false
          }
        },
        // 修改 Loader选项
        chainWebpack: config => {
            config
                .plugin('html')
                .tap(args => {
                    // 防止 Cyclic dependency 错误
                    args[0].chunksSortMode = 'none'
                    return args
                })
        },
        // 配置代理
        devServer: {
            // mock
            // 在这里定义mock需要重启server,改为在 utils/mock 中定义
            // https://webpack.js.org/configuration/dev-server/
            before: function (app) {
                app.get('/api/version', function (req, res) {
                    res.json({
                        data: 'V1.0.0',
                        message: '',
                        status: 0,
                    });
                });
            },

            // 反向代理配置
            // https://github.com/chimurai/http-proxy-middleware#proxycontext-config
            proxy: {
                '/api': {
                    target: 'http://172.13.3.232:12080',
                    // ws: true,
                    changeOrigin: true,
                    autoRewrite: true,
                    pathRewrite: {
                        '^/api/': '/'
                    }
                },    
            },
            disableHostCheck: true
        }
    }


四、public目录、css样式

    public目录存放静态资源

    cli支持Sass、Less、Stylus预处理器


二、main.js 入口文件

    import Vue from 'vue'
    import chat from './components/chat.vue';

    new Vue({
        el: '#app',
        render: h => h(chat)         // 调用其它.vue文件必须这么写
    })

    render: h => h(chat) 相当于

    render: (function (h) {  
          return h(App);
    });  


三、不需要代码校验

    在webpack.base.conf.js里面删掉下面:

    preLoaders: [
        {
            test: /\.vue$/,
            loader: 'eslint',
            include: projectRoot,
            exclude: [/node_modules/, /ignore_lib/]
        },
        {
            test: /\.js$/,
            loader: 'eslint',
            include: projectRoot,
            exclude: [/node_modules/, /ignore_lib/]
        }
    ]


https://cli.vuejs.org/zh/

vue-router 路由

一、安装

    $ npm install vue-router --save-dev


二、引用路由:

    import Vue from 'vue'
    import VueRouter from 'vue-router'
    Vue.use(VueRouter)

    const routes = [
        { path: '/foo', component: Foo },        // 一个路由对应一个组件
        { path: '/bar', component: Bar }
    ]
    const route = new Router(    
        mode: 'history',
        routes,
    })

    let vm = new Vue({
        el: '#app',
        route,
        components: { App },
        template: '<App/>'
    })


三、使用路由

    html:

        <div id="app">
            <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
            <router-link to="/foo">Go to Foo</router-link>

            <!-- 加载路由视图 -->
            <router-view></router-view>
        </div>

     router.js

        import Vue from 'vue'
        import VueRouter from 'vue-router'
        import login from './components/login'

        // 将路由插件加载到Vue中
        Vue.use(VueRouter);

        // 路由映射配置
        const routes = [
            { 
                path: '/login', 
                component: login
            },
            {
                path: '/*',
                redirect: '/404'        // 重定向
            }
        ]

        // 创建路由实例
        const router = new VueRouter({
            routes        // 将定义的配置当参数注入路由
        })

        // 创建和挂载根实例
        const app = new Vue({
            router
        }).$mount('#app')


四、动态路由参数

    const router = new VueRouter({
        routes: [
            // 动态路径参数 以冒号开头
            { path: '/user/:id', component: User }
        ]
    })

    // 路由参数  /user/:username     匹配/user/haha    $route.params 来取参数  { username: 'haha' }
    mounted(){
        let usernmae = this.$route.params.username;
    }

    1、router-link 参数

        <router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>

    2、this.$router.push中参数

        router.push({ name: 'user', params: { userId: 123 }})


五、路由跳转

    1、$router.push(location): js内加路由跳转

        // 字符串
        router.push('home')

        // 对象
        router.push({ path: 'home' })

        // 命名的路由
        router.push({ name: 'user', params: { userId: 123 }})

        // 带查询参数,变成 /register?plan=private
        router.push({ path: 'register', query: { plan: 'private' }})

    2、router.replace(): 与push很像,不同的是replace不会向history添加到新记录

    3、router.go(n): 指定向后跳几步,与window.history.go(n)相同,history历史记录跳转

    4、<router-link to="home">home</router-link>            // 编辑出来是<a>标签


五、<router-view> 渲染路由视图组件

    <router-view></router-view>

    支持多个渲染:
    <router-view></router-view>
    <router-view name="a"></router-view>
    <router-view name="b"></router-view>

    const router = new VueRouter({
        routes: [
            {
                path: '/',
                components: {
                    default: Foo,
                    a: Bar,
                    b: Baz
                }
            }
        ]
    })


六、捕获所有路由或 404 Not found路由

    {
        path: '*',
        redirect: function () {
                return '/admin';
        }
    }


七、History模式

    1、hash: 使用 URL hash 值来作路由。支持所有浏览器,包括不支持 HTML5 History Api 的浏览器。

    2、history: 依赖 HTML5 History API 和服务器配置。查看 HTML5 History 模式. (url不会带hash “#“)

    3、abstract: 支持所有 JavaScript 运行环境,如 Node.js 服务器端。如果发现没有浏览器的 API,路由会自动强制进入这个模式

    export default new VueRouter({
        mode: 'history',
        routes: [...]
    })            


八、路由钩子

    1、beforeEach、afterEach 路由跳转前后的钩子

        var auth = {
            loggedIn: function () {
                return localStorage.getItem(KEY_OF_LOGGEDIN) === 'true'; 
            }
        }

        router.beforeEach((to, from, next) => {
            if (to.matched.some(record => record.meta.requiresAuth)) {
                if (!auth.loggedIn()) {
                    next({
                        path: '/login',
                        query: {redirect: to.fullPath},
                    });
                } else if (auth.requiresAlterPassword()){
                    next({
                        path: '/firstLogin'
                    });
                } else {
                    next();
                }
            } else {
                next();
            }
        });

    2、to: 要进入目录的路由对象

    3、from: 要离开的路由对象

    4、next: function, 用该方法来resolve这个钩子

        next({
            path: '/login',        // 跳转的
            query: {redirect: to.fullPath},                // to.fullPath是当前的路径
        });


九、meta 定义路由的时候可以配置meta字段

    1、设置meta属性,可以通过它来设置不需要判断登录的路由,在beforeEach的时候进行处理

        {
            path: '/firstLogin',
            name: 'firstLogin',
            meta: {
                requiresAuth: false
            },
            component: (resolve) => require(['../views/firstLogin.vue'], resolve),
        }

    2、matched来访问meta属性


十、路由对象

    1、$route.path: 当前路由的路径,总是解析为绝对路径,如 "/foo/bar"

    2、$route.params: 获取动态路由的参数

    3、$route.query:  URL 查询参数, 例如,对于路径 /foo?user=1,则有 $route.query.user == 1

    4、$route.hash: 路由的 hash 值 (带 #) ,如果没有 hash 值,则为空字符串。

    5、$route.matched: 

    6、$route.name: 路由的名称

vue-resource ajax插件

一、它提供了两种方式来处理HTTP请求: 

    使用Vue.http或this.$http

    使用Vue.resource或this.$resource


二、特点: 支持拦截器

    拦截器是全局的,拦截器可以在请求发送前和发送请求后做一些处理。

    拦截器在一些场景下会非常有用,比如请求发送前在headers中设置access_token,或者在请求失败时,提供共通的处理方式。


三、使用方式: 

    1、拦截器  使用inteceptor

    Vue.http.interceptors.push((request, next) => {
        // 请求发送前的处理逻辑
        next((response) => {
            // 请求发送后的处理逻辑
            // 根据请求的状态,response参数会返回给successCallback或errorCallback
            return response
        })
    })


四、请求类型

    get(url, [options])
    head(url, [options])
    delete(url, [options])
    jsonp(url, [options])
    post(url, [body], [options])
    put(url, [body], [options])
    patch(url, [body], [options])

    <script>
        var demo = new Vue({
            el: '#app',
            data: {
                gridColumns: ['customerId', 'companyName', 'contactName', 'phone'],
                gridData: [],
                apiUrl: 'http://211.149.193.19:8080/api/customers'
            },
            ready: function() {
                this.getCustomers();
            },
            methods: {
                getCustomers: function() {
                    // get请求
                    // then方法只提供了successCallback,而省略了errorCallback。
                    // catch方法用于捕捉程序的异常,catch方法和errorCallback是不同的,errorCallback只在响应失败时调用,而catch则是在整个请求到响应过程中,只要程序出错了就会被调用。

                    this.$http.get(this.apiUrl)
                        .then((response) => {
                            // Vue实例方法,设置gridData属性赋值,并触发视图更新
                            this.$set('gridData', response.data)
                        })
                        .catch(function(response) {
                            console.log(response)
                        })
                }
            }
        })
    </script>

5、options对象

    发送请求时的options选项对象包含以下属性: 

    参数             类型                                    描述
    url             string                      请求的URL

    method        string                请求的HTTP方法,例如: 'GET', 'POST'或其他HTTP方法
    body            Object                 FormData string    request body
    params        Object                请求的URL参数对象
    headers        Object                request header
    timeout        number                单位为毫秒的请求超时时间 (0 表示无超时时间)
    before        function(request)    请求发送前的处理函数,类似于jQuery的beforeSend函数
    progress     function(event)      ProgressEvent回调处理函数
    credientials    boolean      表示跨域请求时是否需要使用凭证
    emulateHTTP        boolean      发送PUT, PATCH, DELETE请求时以HTTP POST的方式发送,并设置请求头的X-HTTP-Method-Override
    emulateJSON        boolean      将request body以application/x-www-form-urlencoded content type发送

| https://router.vuejs.org/zh-cn/
| https://vuex.vuejs.org/zh-cn/
| https://github.com/dai-siki/vue-image-crop-upload 头像上传组件
| http://www.cnblogs.com/pandabunny/p/5417938.html // vue引用jquery
| http://router.vuejs.org/zh-cn/installation.html // 路由插件
| http://yuche.github.io/vue-strap/ // vueStrap
| http://bootstrap-table.wenzhixin.net.cn/zh-cn/ // bootstrap Table
| https://github.com/PanJiaChen/vue-element-admin
| https://github.com/opendigg/awesome-github-vue?f=tt&hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io // vue项目汇总