Vue手记

什么是Vue

  • Vue.js 是一套构建用户界面的框架 只关注视图层 易于上手,还便于与第三方库或即有项目整合

  • MVC:(数据层,页面层,逻辑层)

  • MVVM模式:model-view-ViewModel

    1. model:负责纯javascript对象表示

    2. view:view负责显示

    3. 两者做到最大极限的分离

    4. viewModel:负责将model数据同步到view显示出来,还负责把view的修改同步到model

Vue选项


var vm = new Vue({

    el: "#app",//元素名字 列如:#id,.class  要控制的区域

    data: {

    //数据(需要注意的是,在组件中的data必须是函数 数据都需要return)

        message: "hello",

        name:'zz'

    },

    computed: {

        // 在computed中,可以定义一些属性,这些属性叫做计算属性,计算属性的本质就是一个方法,只不过在使用这些计算属性的时候,是把 方法名称 直接当作属性来使用的;并不会把 计算属性 当做方法去调用

        //* 注意1:计算属性在调用时候不要加(),直接把他当作一个属性去调用就好

        //* 注意2:只要计算属性(function)内部所用到的任何data数据发生了变化,就会立即重新计算这个属性的值

        // * 注意3:计算属性的求值结果,会被缓存起来,方便下次直接使用;如果 计算属性 方法中,data的任何数据没有发生改变,而你又在此调用,则返回的是缓存好的结果

        "result":function(){

        return this.name + this.message

        //返回结果: hello zz

        }

    },

    methods: {

        //这里可以自定义方法

    },

    watch: {

        //侦听器  当某个数据发生改变就会触发 让数据发生变更

        //监听的方法一般都会有两个参数,newVal,oldval

        //列如标签有一个 v-model='name'

        'name':function(newVal,oldval){

              //newVal:是新的数据  结果: zz

              //oldVal:是旧的数据  结果: undefined

        },

        //典型案列

        '$route.push':function(newVal,oldval){

            console.log(newVal ------ oldval)

            // 注册好了 跳转 登录页

            //newVal:当前跳转到的页面  结果:登录页

            //oldVal: 从上一个页面 跳转到当前页面的 页面 结果:注册页

        }

        // watch 最好用来监听非 DOM 元素的改变 列如:$route

    }

});

  • 总结:

    watch,computed,methods之间的对比

    1.computed:属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。主要当作属性来使用;

    2.methods:方法表示一个具体的操作,主要书写业务逻辑;

    1. watch:一个对象,键是需要观察的表达式,值是对应回调函数。主要用来监听某些特定数据的变化,从来进行某些具体的业务逻辑操作;可以看做是 methodscomputed的结合体;

Vue v-指令

  • v-bind:(缩写:) 数据绑定

    • 在使用==号以后 后面跟的就是一个js表达式
  • {{ }}:差值表达式 注意react里没有差值表达式一说而是jsx语法

  • v-on: (缩写@:)事件处理

  • v-for="(item, index) in array"(遍历 (元素,下标)) 要配合:key( String/Number )

  • v-model :双向数据绑定(只能运用到表单元素中...)

  • v-cloak :可以用来解决插值表达式闪烁问题

  • v-pre:表示该会跳过该标签及其子元素的编译

    v-指令区别

  • v-show 和 v-if

    1. v-if

    2. v-else-if

    3. v-else

    4. v-show

一般来说,v-if有更高的切换消耗 v-show有更高的初始渲染消耗。因此如果频繁切换使用v-show较好,如果运行时条件不大可能改变 v-if较好

如果一个元素一直都不会显示出来 并操作他 v-if更好

v-if特点:每次都会重新删除或创建元素

v-show:只会切换diplay:none/block

  • v-html 和 v-text

    1. v-html : 真正的HTML也可以是 标签

    2. v-text : 只是一串字符串

Vue 修饰符

  • 事件修饰符:

    1. v-on:click.stop:阻止冒泡的

    2. v-on:click.prevent:阻止默认行为

    3. v-on:click.once :只会执行一次

    4. v-on:click.capture:添加事件监听器时使用事件捕获模式

    5. @click.self:只当事件在该元素本身(比如不是子元素) 触发时触发回调

    • self 与 stop的区别

      1. self只取消当前事件本身的冒泡并不影响其他的冒泡

      2. stop则是取消所有的冒泡

  • 按键修饰符:

    1. v-on:keyup.enter:按回车触发

    2. 分别还有:.tab,.delete,.esc, .space

    自定义修饰符

    `Vue.config.keyCodes.f2 =113`  @Keyup.f2调用
    
  1. 修饰键:

    1. @keyup.alt.13:同时按下 alt+回车

    2. 分别还有: .ctrl .alt .shift .meta

    3. 修饰键与修饰符不同 修饰键单独按并不会触发 需要按修饰键+修饰符才会触发

  • 事件处理:

    1. @touchstart:也是类似点击事件 但是相比click他没有延迟 而click有300毫秒的延迟所以 touchstart相对来说会先执行

    2. @touchend:也比click快但是比start慢 也是点击事件

    3. @touchmove:在end之前 start之后 还是比click快 鼠标移动事件

Vue使用Class样式

  • 数组

<h1 :class="['red','thin']"> 这是一个样式运用方法 </h1>

  • 数组中使用三元表达式

<h1 :class="['red','thin', flag? 'active' : 'isactive' ]"> 这是一个样式运用方法 </h1>

data :{

    flag : true; //ture引用active, false则不用active

}

  • 数组中嵌套对象

<h1 :class="['red','thin',{ 'active' : flag }]"> 这是一个样式运用方法 </h1>

data:{

    flag : true; //ture引用active, false则不用active 类似三元表达式

}

  • 直接使用对象

<h1 :class="{red:true,thin:true,active:false,isactive:false }"> 这是一个样式运用方法 </h1>

<h1 :class="obj"> 这是一个样式运用方法 </h1>

//直接传对象 且只有true的被使用 或者可以直接写一个对象

data:{

    obj:{

        red:true,

        thin:true,

        active:false,

        isactive:false

    }

}

Vue使用内联样式-style

  • 直接在元素上通过 :style 的形式,书写样式对象

    <h1 :style='{color:'red', 'font-size':'40px'}'> 这是一个内联样式的H1</h1>

  • **将样式对象,定义到Data中,并直接引用到 :style

    data:{

        handleObj:{

            color:'red',

            'font-size':'40px',

            fontSize:40  // 两种写法罗峰写法 或者 字符串 直接数组则默认px

        }

    }

  • **在:style中通过数组,应用多个data上的样式对象

    <h1 :style="[handleObj,handleObj2 ]"> 这是一个内联样式的H1</h1>



  data:{

        handleObj:{

            color:'red',

            'font-size':'40px',

            fontSize:40  // 两种写法罗峰写法 或者 字符串 直接数组则默认px

        },

        handleObj2:{

            backgroundColor:'#0f6',

            background-color:'#0f6'

        }

    }

Vue 过滤器


    //过滤器的格式

    //  \ 术语叫做 管道符

  {{ name |  isname('Dad+1') | test('Nb')}}

  //过滤器的语法

    isname: 过滤器的名字

  Vue.filter("isname",function(name ,msg){

        //replace 第一个参数也可以写正则

        return name.replace( '弟弟','Dad') //只会改第一个弟弟

        return name.replace(/弟弟/g,'Dad')//全改

        return name.replace(/弟弟/g,msg)//第三种方法可以通过传参来更改

  })



  Vue.filter('test',function(name,msg){



        return name + '====='

  })



    //定义私有过滤器

    //私有的话 过滤器的名字变成方法名

    var vm = new Vue({

        data:{

            name:'就是一个弟弟就是一个弟弟就是一个弟弟,'

        },

        filters:{

            isname:function(name,msg){

                  //replace 第一个参数也可以写正则

                return name.replace( '弟弟','Dad') //只会改第一个弟弟

                return name.replace(/弟弟/g,'Dad')//全改

                return name.replace(/弟弟/g,msg)//第三种方法可以通过传参来更改

            }

        }

    })

过滤器调用的时候,采用的是就近原则,如果私有过滤器和全局过滤器一致了,这时候,会优先调用私有过滤器

自定义全局的指令


    //第一个参数在调用时候,必须在指令前加上v- 前缀来进行调用

    //第二个参数是一个对象,这个对象身上,有一些指令相关的函数,这些函数可以在特定的阶段,执行相关的操作

    Vue.directive('focus',{

        //每个函数中,第一个参数都是el,表示被绑定了指令的那个元素,这个el参数,是一个原生的Js对象

        bind:function(el){

            //每当指令绑定到元素上的时候,会立即执行这个bind函数, 只执行一次

            el.focus() //focus 获取焦点 input lode原生方法 但是在这里使用时不行的



            //在元素刚绑定了指令的时候,还没有插入到DOM中,这时候,调用focus方法没有作用

            //因为一个元素,只有插入Dom之后,才能获取焦点

        },

        inserted:function(el){

            //inserted 表示元素 插入到DOM中的时候,会执行inserted函数[触发一次]



            //一般来说从内存(JavaScript)渲染到数据 也就是 从model 渲染到 view 就要执行的话用bind 列如:样式 而js的事件操作 需要等Dom生成完毕才能执行 最好放在 inserted里

        },

        updata:function(el){

            //当vNode更新的时候,会执行updata,可能触发多次

        }



    })



    `自定义 私有指令`

    var vm = new Vue({

        dirctives:{

            focus:function(){

                //之后操作和全局一样

            },



            focus: function(){

                //如果想 bind 和 updata都重复操作 那么可以直接在function里写操作

                //等同于 bind 和 updata

            }

        }

    })

* Vue生命周期

  • 什么是生命周期:

    1. 从Vue实列创建,运行,销毁,会伴着各种函数,这些统称为 生命周期

    2. 生命周期钩子:就是生命周期的别名

  • 主要的生命周期函数分类

    • 创建期间的生命周期函数:

      • beforeCreate:实列刚在内存中被创建出来,此时,还没有初始化好 data 和 methods属性。

      • Created:实列已经在内存中创建OK,此时data和 methods已经创建OK,此时没有开始 编译模板

      • beforeMount:此时已经完成了编译的模板,但是还没有挂载到页面上

      • Mounted:此时,已经将编译好的模板,挂载到了页面指定的容器中显示了

    • 运行期间的生命周期函数:

      • beforeUpdate:状态更新之前执行此函数,此时data中的状态值是最新的,但是界面上显示的数据还是旧的,因为此时还没有开始重新渲染Dom节点

      • Update:实列更新完毕之后调用此函数,此时 data 中的状态值 和 界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了

    • 销毁期间的生命周期函数:

      • beforeDestroy:实列销毁之前调用,在这一步,实列容然可用

      • Destroyed:Vue 实列销毁后调用,调用后,Vue实列指示的所有东西都会解绑,所有事件监听器会被移除,所有的子实列也会被销毁

* Ajax

  • Ajax的原理简单来说通过xmlHttpRequest 对象来想服务器发异步请求,从服务器获得数据,然后用JavaScript来操作DOM而更新页面。这其中最关键的一步就是从服务器获得请求数据。要清楚这个过程和原理,必须对XMLHttpquerst有所了解

  • XMLHttprequest 是 Ajax的核心控制,它是在IE5中首先引入的,是一种支持异步请求的技术,简单说,也就是JavaScript可以及时向服务器提出请求和处理响应,而不阻塞用户,打到无刷新的效果。

* JSONP的实现原理

  • 由于游览器的安全限制,不允许AJAX访问 协议不同,域名不同,端口号不同的数据接口,游览器认为这种访问不安全

  • 可以通过动态创建Script标签的src属性,指向数据接口的地址,因为script标签不存在跨域限制,这种数据数据获取方式,称作JSONP(*注意:JSONP的实现原理,知晓,JSONP只支持GET请求)

  • 具体实现过程:

     *  先在客户端定义一个回调方法,预定义对数据的操作;
    
     *  再把这个回调方法的名称,通过URL传参的形式,提交到服务器的数据接口;
    
     *  服务器数据接口组织好要发送给客户端的数据 ,再拿着客户端传递过来的回调方法名称,拼接出一个调用这个方法的字符串,发送给客户端去解析执行
    
     *  客户端拿到服务器返回的字符串之后,当作Script脚本去解析执行,这样就能拿到JSON数据了
    

Axios


npm  install --save --save-exact axios vue-axios

  • axios的特点有哪些?

    1. Axios 是一个基于 promise 的 HTTP 库,支持promise所有的API

    2. 它可以拦截请求和响应

    3. 它可以转换请求数据和响应数据,并对响应回来的内容自动转换成 JSON类型的数据 安全性更高,客户端支持防御 XSRF

  • axios有哪些常用方法?

    1. axios.get(url[, config]) //get请求用于列表和信息查询

    2. axios.delete(url[, config]) //删除

    3. axios.post(url[, data[, config]]) //post请求用于信息的添加

    4. axios.put(url[, data[, config]]) //更新操作

  • 说下你了解的axios相关配置属性?

    1. url是用于请求的服务器URL

    2. method是创建请求时使用的方法,默认是get

    3. baseURL将自动加在url前面,除非url是一个绝对URL。它可以通过设置一个baseURL便于为axios实例的方法传递相对URL

    4. transformRequest允许在向服务器发送前,修改请求数据,只能用在'PUT','POST'和'PATCH'这几个请求方法

    5. headers是即将被发送的自定义请求头


// 添加请求拦截器

axios.interceptors.request.use(function (config) {

    // 在发送请求之前做些什么

    //Loading

    Indicator.open({

    text: '加载中...',

    spinnerType: 'double-bounce'

    });

    return config;

  }, function (error) {

    // 对请求错误做些什么

    return Promise.reject(error);

  });

// 添加响应拦截器

axios.interceptors.response.use(function (response) {

    // 对响应数据做点什么

    //响应到数据以后 close 关闭Loading

    Indicator.close();

    if(res.data.res_code === 1){

        return res.data.res_body

    }

    else{

        Toast({

            message: '提示:数据请求异常',

            position: 'bottom',

            duration: 3000

        });

    }

  }, function (error) {

    // 对响应错误做点什么

    return Promise.reject(error);

  });





// 请求数据

export const getHomeSwipe = ()=>{

    return ajax.get('/api/swiperimgs')

}

定义Vue组件

什么是组件: 组件的出现,就是为了拆分Vue实列的代码量的,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样的功能,就可以

什么是模块化:

  1. 文件作用域

  2. 通信规则

    • 加载 require

    • 导出

模块规范:

  1. 模块作用域

  2. 使用 require 方法用来加载模块

    • 作用

      执行被加载中的代码,得到被加载模块中的export 导出接口对象

  3. 使用 exports 接口对象来导出模块中的成员

    • 作用

      模块作用域:默认文件中所有的成员只在当前文件模块中有效

      对于希望可以被其他模块访问的成员,我们就需要吧这些公开的成员都挂载到 export 接口对象中就可以了

  • 模块化:是从代码逻辑的角度进行划分的;

  • 组件化:是从UI界面的角度进行划分的;

全局组件定义的三种方法

  • 使用Vue.extend 配合 Vue.component 方法:

    var login = Vue.extend({

        tamplate:` <h1> 登录 </h1>`

    })

    Vue.component('login',login)

  • 直接使用Vue.component 方法:

    Vue.component('register',{

        template:`<h1> 注册 </h1>`

    });

  • 将模板字符串,定义到script标签种:

    <script id="tmpl" type="x-tamplate">

        <div> <a href='#' > 登录  </a> |  <a href='#' > 注册  </a> </div>

    </script>

  • 创建私有组件:

    var vm = new Vue({

        components:{

            login:{

                template:·<h1>这是一个私有组件</h1>·

            }

        }

    })

在使用组件的时候 组件名列如myCol 那么渲染就要使用 <my-col></my-col>渲染

组件中 只允许有一个根元素

组件中的 data 必须一个是方法,这个方法内必须return一个对象才行

组件切换除了 v-if 以外 还可以是用 :IS="组件名"

* Vue 父子组件通信

  • 父组件通过props向子组件传值

    • 父组件,可以引用子组件的时候,通过属性绑定(v-bind:)的形式,把需要传值给子组件的数据,以属性绑定的形式,传递到子组件的内部,供子组件使用

//HTML模板

<div id="app">

    <col :parenMsg='msg'> </col>

</div>


    var vm = new Vue({

        el:'#app',

        data:{

            msg:'这是一个子组件所需要的值'

        },

        //子组件中,默然无法访问到 父组件中的 data 上的数据和 methods 中的方法

        components:{

            col:{

            //* 注意:子组件中的 data 数据,并不是通过父组件传递过来的,而是子组件自身私有的,比如:子组件通过 Ajax。请求回来的数据,都可以放到 data 身上

            `* 注意:在子组件中 data 数据时可读可写的,props绑定属性的参数是只读的`

                data(){

                    return{

                        name:'zz',

                        age:23

                    }

                },

            //把父组件传过来的  parentMsg属性,现在props数组中定义一下,这样才能使用这个数据

            //* 注意:组件中的所有 props中的数据,都是通过父组件传递给子组件的

                props:["parentMsg"],

                template:'<h1>收到了父组件的值了---{{parentMsg}}</h1>'

            }

        }

    })

  • 子组件通过调用事件向父组件传值

    • 子组件通过事件 this.$emit('第一参数为父组件的方法',第二个是要穿过去的参数对象')

<div id='app'>

      <!---父组件-->

      <col @func="show"></col>

</div>

<!---子组件-->

<template id='tmp'>

    <div>

        <h1>这是子组件</h1>

        <input type="button" value="触发父组件来传值" @click="childClick"/>

    </div>

</template>


  var vm = new Vue({

        data:{

            detail:{}

        },

        methods:{

            show(data){

                this.detail = data

            }

        },

        components:{

            col:{

              template:'#tmp',

              data(){

                    return{

                        msg:{

                            name:'zz',

                            age:23

                        }

                    }

              },

              methods:{

                  childClick(){

                        this.$emit('show',this.msg)

                  }

              }

            }

        }   

  })

Vue ref获取Dom元素和组件组件引用


<div id='app'>

    <Input type='button' value='获取元素' @click='getElement' ref='mybtn'>

    <h3 id='tmp' ref='tmp'>获取成功的 innerHTML</h3>

    <col ref='col'></col>

</app>


var vm = new Vue({

    el:'#app',

    data:{},

    methods:{

        getElement(){

            this.$refs.tmp.innerHtml//获取ref名为tmp的元素

            this.$refs.col.data// 组件上使用ref会吧整个组件vue实列存到ref 这样的话可以通过 $refs 来获取子组件里的data

        }

    },

    components:{

        col :{

            template:"<h1> 登录注册 </h1>",

            data:{

                name:'zz'

            },

            methods:{

                show(){

                    console.log('子组件的方法')

                }

            }

        },



    }

})

Vue动画

  • 使用transition

!需求:点击按钮让h3显示再按隐藏

1. 使用 transition 元素,把需要把动画控制的元素,包裹起来(transition元素是 vue 官方提供)

2. 自定义两组样式,来控制 transition 内部的元素实现动画

    /*v-enter 【这是一个时间点】 是进入之前,元素的起始状态,此时还没有开始进入*/

    /*v-leave-to 【这是一个时间点】是动画离开之后,离开的终止状态,此时,元素动画已结束*/

    v.enter,

    v-leave-to{

        opatity: 0;

    },

    v-enter-active,

    v-leave-active{

        .v-enter-active[入场动画的时间段],

        .v-leace-active[离场时间的时间段]{

            transition: all 0.4s ease

        }

    }


<transition>

    <h3 v-show='flag'>这是一个会动的标签</h3>

</transition>

Vue-Router

什么是路由

  • 后端路由: 对于普通的网站,所有的链接都是URL地址,所有的URL地址都对应服务器上对应的资源;

  • 前端路由: 对于单页用程序来说,主要通过URL中的hash(#号)来实现不同页面之间的切换,同时 hash 中有一个特点:HTTP请求不会包含hash相关的内容;所有单页面程序中的页面跳转主要用hash实现;

  • 在单页面程序中,这种通过hash改变来切换页面的方式,称作前端路由(区别于后端路由)

安装

  • CDN安装

    <script src="/path/to/vue.js"></script>

    <script src="/path/to/vue-router.js"></script>

  • Npm

    npm install vue-router

  • 如果在一个模块化工程中使用它,必须要通过 Vue.use() 明确地安装路由功能:

    import Vue from 'vue'

    import VueRouter from 'vue-router'



    Vue.use(VueRouter)

  • 构建开发版:

如果你想使用最新的开发版,就得从 GitHub 上直接 clone,然后自己 build 一个 vue-router


git clone https://github.com/vuejs/vue-router.git node_modules/vue-router

cd node_modules/vue-router

npm install

npm run build

vue-router中route 和router

  • $route 表示(当前路由信息对象)

    表示当前激活的路由的状态信息,包含了当前 URL 解析得到的信息,还有 URL 匹配到的 route records(路由记录)。路由信息对象:即$router会被注入每个组件中,可以利用它进行一些信息的获取。

  • $route.path

    字符串,对应当前路由的路径,总是解析为绝对路径,如 "/foo/bar"。

  • $route.params

    一个 key/value 对象,包含了 动态片段 和 全匹配片段,

    如果没有路由参数,就是一个空对象。
    
  • $route.query

    一个 key/value 对象,表示 URL 查询参数。

    例如,对于路径 /foo?user=1,则有 $route.query.user == 1,
    
    如果没有查询参数,则是个空对象。
    
  • $route.hash

    当前路由的 hash 值 (不带 #) ,如果没有 hash 值,则为空字符串。锚点

  • $route.fullPath

    完成解析后的 URL,包含查询参数和 hash 的完整路径。

  • $route.matched

    数组,包含当前匹配的路径中所包含的所有片段所对应的配置参数对象。

  • $route.name

    当前路径名字

  • $route.meta

    路由元信息

  • route object 出现在多个地方

    (1) 在组件内,即 this.$route

    (2) 在 $route 观察者回调内 router.match(location) 的返回值

    (3) 导航守卫的参数:


router.beforeEach((to, from, next) => {

  // to 和 from 都是 路由信息对象

})

watch: {

  $route(to, from) {

    // to 和 from 都是 路由信息对象

  }

}

$router对象

全局的路由实例,是router构造方法的实例。在 Vue 实例内部,你可以通过 $router 访问路由实例


const router = new Router({

  routes: [

    {

      path: "/",

      name: "首页",

      redirect: '/home'

    },

    {

      path: '/login',

      name: 'Login',

      component: Login

    },

    { path: '*', component: NotFoundComponent }

  ],

  linkActiveClass: "active-router",

  linkExactActiveClass: "exact-router"

})

路由实列方法 push


// 字符串

      this.$router.push('home')

// 对象

      this.$router.push({ path: 'home' })

// 命名的路由

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

// 带查询参数,变成 /register?plan=123

      this.$router.push({ path: 'register', query: { plan: '123' }})

push方法其实和<router-link :to="...">是等同的。注意:push方法的跳转会向 history 栈添加一个新的记录,当我们点击浏览器的返回按钮时可以看到之前的页面

路由实列方法 go


// 页面路由跳转 前进或者后退

this.$router.go(-1) // 后退

路由实列方法 replace


//push方法会向 history 栈添加一个新的记录,而replace方法是替换当前的页面,

不会向 history 栈添加一个新的记录

<router-link to="/05" replace>05</router-link>

// 一般使用replace来做404页面

this.$router.replace('/')

使用

  • CDN简单使用Vue-router
  1. Css

.myactive{

  /*如果不想麻烦 也可以吧class名直接改为 router-link-active 但是不推荐*/

}

  1. HTML

    <div id='#app'>

        <!-- router-link 默认渲染为一个a 标签-->

        <!-- tag是让 router-link 以什么标签进行渲染 但是都会绑定一个跳转的点击事件-->

        <!--如果在路由中,使用 查询字符串,给路由传递参数,则不需要修改路由的 path 属性-->

        <!--这种传参方式为 query传参方式 -->

        <router-link to='/login?id=10&name='zz'' tag='button'>登录</router-link>

        <template id='login'>

            <!--mine-->

            <router-link  to='/login/mine' tag='div'>我的</router-link>

            <router-view></router-view>

        </template>

        <router-link to='/register/12/zhao' tag='span'>注册</router-link>

        <!--这是 vue-router 提供的元素,专门用来当做占位符的,将来,路由规则,匹配到的组件,就会展示到这个 router-view 中去-->

        <router-view></router-view>

    </div>

  1. JavaScript

let login = {

    //在插值表达式中 this是可以省略掉的

    template:'<h1> 登录组件-----{{ $route.query.name }} </h1>',

    created(){

        this.$route.query.id //调用到id

        this.$route.query.name //调用到name

    }

}

let register = {

    template:'<h1> 注册组件-----{{ $route.query.name}}</h1>',

    created(){

        this.$route.query.id //调用到id

        this.$route.query.name //调用到name

    }

}

let mine = {

    template:'<h1> 这是一个login的子组件</h1>',

}

// 创建一个路由对象,当导入vue-router包之后,在 window 全局对象中,就有了一个 路由的构造函数,叫做VueRouter

//在new 路由对象的时候,可以为构造函数,传递一个配置对象

var routerObj = new VueRouter({

//route  这个配置对象中的 route 表示【路由匹配规则】的意思

    routes:{

        // 路由匹配规则

        //每个路由规则,都是一个对象,这个规则对象,身上有两个必须的属性

        // 属性1: 是path,表示监听 那个路由的地址

        //属性2:  component,表示,如果路由是前面匹配到的 path ,则展示 component属性对应的那个组件

        //注意:component 的属性值,必须是一个组件的模块对象,不能组件的应用名称

        {path:'/',component:login;}//默认跳转页面 

        {path:'/',redirect:'.login'}//默认页第二种方法,重定向,强制性的显示

        { path:'/login',

          component: login,

          children:{

            //子组件中不需要  / 如果加了/ 就说明你是要从根访问 在组件不加则是从父 /longin/mine 访问

            {path:'mine', component:mine;}

          }

        }

        {path:'register/:id/:name',component:register;}//第二种传参方法 path中设置 也叫params方式传参

    },

    linkActiveClass: 'myactive',//new  VueRouter 的一个属性点击时执行这个样式

})

var vm = new Vue({

    el:"#app",

    data:{},

    methods:{},

    router: routerObj //将路由规则对象,注册vm实列上,用来监听 URL 地址的变化 ,然后展示对应的组件

})

vue-Router实现默认页多组件


    <div id='#app'>

        <!--router-view name 指定要渲染的组件名-->

        <router-view name='header'></router-view>

        <router-view name='left'></router-view>

        <router-view name='main'></router-view>

    </div>


    //css仔细想 完成经典布局

    let header = {

        template:"<div class='header_css'>这是一个头部</div>"

    }

    let left= {

        template:"<div class='left_css'>这是一个左侧</div>"

    }

    let main = {

        template:"<div class='main_css'>这是一个主体</div>"

    }



    var router = new VueRouter({

        routes:[

            {

                path:'/',

                components:{ //需要注意的是 一个页面要个组件是 components

                    'default':header, //默认的

                    "left":left,

                    "main":main

                }

            }

        ]

    })



滚动行为

使用前端路由,当切换到新路由时,想要页面滚动到顶部,或者时保持原先的滚动位置,就像重新加载页面那样,vue-router就能做到

ps:这个功能只在支持 history.pushState 的浏览器中可用

当创建一个 Router 实例,你可以提供一个 scrollBehavior 方法:


const router = new VueRouter({

    routes: [...]

    scrollBehavior(to,from,savedPosition){

        // return 期望滚动到哪个的位置

    }

})

scrollBehavior 方法接收 to 和 from 路由对象,第三个参数 savedPosition 当且仅当 popstate 导航(通过浏览器的 前进\后退 按钮触发)时才可用

路由懒加载

当打包构建应用时,javascript包会变得非常大、影响页面加载,如果我们能把不同路由对应得组件分割成不同得代码块,然后当路由访问的时候才在家对应组件,这样更加高效

结合Vue的异步组件和webpack的代码分割功能,轻松实现路由组件的懒加载。

首先,可以将异步组件定义为返回一个Promise的工厂函数


const Foo = () => Promise.resolve({// 组件定义对象})

第二,在webpack2中,我们可以使用动态 import语法来定义代码分块import('./Foo.vue')

ps: 如果使用的时babel,你将需要添加 sybtax-dynamic-import 插件,才能使Babel可以正确的解析语法

结合这两者,这就使如何定义一个能够被webpack自动代码分割的异步组件


const Foo = () => import('./Foo.vue')

在路由配置中什么都不需要改变,只需要像往常一样使用


Foo:const router = new VueRouter({

        routes: [{

            path: '/foo', component: Foo

        }]

    })

把组件按组分块

有时候我们想把某个路由下的所有组件都打包在同个异步块中,只需要使用命名 chunk,一个特殊的注释语法来提高chunk name(需要webpack>2.4)

const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')

webpack 会将任何一个异步模块与相同的块名称组合到相同的异步块中

nrm的安装使用

作用:提供一些最常用的npm包镜像地址,能够让我们快速切换安装包的服务器地址;

什么是镜像:原包刚一开始只是存在国外的npm服务器,但是由于网络原因,经常访问不到,这时候,我们有在国内,创建一个和官网完全一样的npm服务器,只不过,数据都是从人家那里拿过来的,使用方式完全一样;

1.运行npm i nrm -g 全局安装npm

2.使用npm ls查看当前所有可用的镜像源地址以及当前所使用的镜像源地址;

3.使用nrm use npmnrm use taobao切换不同的镜像源地址

注意:nrm只是单纯的提供了几个常用的下载包URL地址,并能够让我们在这几个地址之间很方便的进行切换,但是,我们每次装包的时候,使用的 装包工具都是npm

Webpack

  • 在网页中会引用那些常见的静态资源:

    • js

      • .js .jsx .conffe .ts(TypeScript)
    • css

      • .css .less .sass(更新以后叫 scss 基本上和less 只是语法不同)
    • Images

      • .jpg .png .git .bmp .svg .webp
    • 字体文件(Fonts)

      • .svg .ttf .eot .woff .woff2
    • 模板文件

      • .ejs .jade .vue【这是在webpack中定义组件的方式】
  • 网页引入静态资源多了以后有什么问题??

    1. 网页加载速度慢,因为 我们要发起很多的二次请求;

    2. 要处理错综复杂的依赖关系

  • 如何解决上述问题

    1. 合并,压缩,精灵图,图片Base64编码

    2. 可以使用requireJs 或 webpack解决各个包之间的复杂依赖关系

  • 什么是webpack/gulp

    1. webpack他是基于Node.js开发的模块化打包工具

    2. gulp基于流的自动化构建工具,流,一个操作的输出结果作为另一个操作的输入

  • 如何完美实现上述的2种方案

    1. 使用Gulp可以进行html,css,img的压缩打包,是自动化构建工具,可以将多个js文件或是css压缩成一个文件,并且可以压缩为一行,以此来减少文件体积,加快请求速度和减少请求次数;并且gulp有task定义处理事务,从而构建整体流程,它是基于流的自动化构建工具

      • 优点:

        • 小巧 灵活 方便去做一些灵活任务的处理

        • 它能自动化地完成 前端代码的测试、检查、合并、压缩、格式化、浏览器自动刷新、部署文件生成,并监听文件在改动后重复指定的这些步骤

    2. Webpack是前端构建工具,实现了模块化开发和文件处理。他的思想就是“万物皆为模块”,它能够将各个模块进行按需加载,不会导致加载了无用或冗余的代码。所以他还有个名字叫前端模块化打包工具

      • 借助于webpack这个前端自动化构建工具,可以完美实现资源的合并,打包,压缩,混淆等诸多功能;

      • webpack打包的过程 见笔记

[图片上传失败...(image-3cca2e-1553654416703)]

  • webpack安装的两种方式:

    1. 运行npm i webpack -g 全局安装webpack,这样就能在全局使用webpack的命令

    2. 在项目跟目录中运行npm i webapck --save-dev 安装到项目依赖中

  • 初步使用webpck打包构建列表隔行变色案列

    import $ form 'jquery'

    $('#list li:even').css('backgroundColor','#0f6');

    $('#list li:odd').css('backgroundColor','pink');

1. 运行`npm init`初始化项目,使用npm管理项目中的依赖包

2. 创建项目基本的目录结构

3. 使用`npm i jquery --save`(ES6写法)安装jquery类库(`const $ = require("jquery")第二种方法`)

4. 创建`main.js`并书写各行变色的代码逻辑:

5. 直接在页面上引用`main.js`会报错,因为游览器不认识`import`这种高级的js语法,需要使用webpack进行处理,webpack默认会把这种高级的语法转换为低级的游览器能识别的语法;

6. 运行`webpack 入口文件路径 输出文件路径`对`main.js`进行处理;

  //webpack 3x 版本

  webpack src/js/main.js dist/bundle.js

之后webpack 进入webapck笔记

什么是Vuex

概念:vuex是 vue 配套的公共数据管理工具,它有把一些共享的数据,保存到vuex中,方便整个程序中的任何组件直接获取或修改我们的公共数据;

Vuex是为了保存组件之间共享数据而诞生的,如果组件之间有要共享的数据,可以直接挂载到vuex中,而不必通过 父子组件之间传值了,如果组件的数据不需要共享,此时,这些不需要共享的私有数据,没有必要放到vuex中;

只有共享的数据,才有权利放到vuex中; 组件内部私有的数据,只要放到组件 data 中即可;

props 和 data 和 vuex的区别

Vuex 是一个全局的共享数据存储区域,就相当于一个数据的仓库

使用Vuex


import Vuex from 'vuex'

Vue.use(Vuex)

// 如果在模块化构建系统中,请确保在开头调用了 Vue.use(Vuex)

const store = new Vuex.Store({

  state: {

    // state 可以想象成 组件中的 data ,专门用来存储数据的

    // 如果在 组件中,想要访问,store 中的数据,只能通过 this.$store.state.*** 来访问

    count: 0

  },

  mutations: {

    // 注意:如果要操作 stroe 中的 state 值,只能通过 调用  mutations 提供的方法,才能操作定义的数据,不推荐直接操作 state 中的数据,应为万一导致了数据的紊乱,不能快速定位到错误的原因,因为每个组件都有可能操作数据的方法;

    // mutations 里的方法第一个参数固定是state

    // 在组件中调用mutations中的方法,要使用 this.$store.commit('方法名')

    // 传参方法 this.$store.commit('方法名','传参值'),注意mutations内部方法只能有2个参数 如果要传多个就传一个对象

    increment (state,a) { //a 接收参数值

      state.count++

    },

    getters: {

    //注意:这里的getters,只负责对外提供数据,不负责修改数据,如果想要修改 state 中的数据,请去找 mutations

        doneTodos: state => {

          return '当前count值是:'+ state.count

        }

    //getters就相当于是 store 的计算属性, 只要 state 中的数据发生了变化,那么正好 getters 也引用了这个数据,那么就会立即触发 getters 来重新求值

    }

  }})

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,588评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,456评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,146评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,387评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,481评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,510评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,522评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,296评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,745评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,039评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,202评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,901评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,538评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,165评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,415评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,081评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,085评论 2 352