Vue

Vue介绍

什么是Vue.js

  1. vue.js是目前最火的一个框架,React是最流行的一个框架(React除了开发网站,还可以开发手机App)
  2. Vue.js是前端的主流框架之一,和Angular.js、React.js一起,并称为前端三大主流框架
  3. Vue.js是一套构建用户界面的框架,只关注视图层,它不仅易于上手,还便于与第三方库或既有项目整合。(Vue有配套的第三方类库,可以整合起来做大型项目的开发)
  4. 前端的主要工作?主要负责MVC中的V这一层;主要工作就是和界面打交道

为什么要学习流行框架

  1. 企业为了提高开发效率;
  2. Vue.js能够帮助我们减少不必要的DOM操作;提高渲染效率;双向数据绑定的概念【通过框架提供的指令,前端程序员只需要业务逻辑,不再关注DOM是如何渲染的了】
  3. 增强自己就业时候的竞争力:人无我有,人有我优

框架和库的区别

  1. 框架:是一套完整的解决方案;对项目的侵入性比较大,项目如果更换框架,则需要重新架构整个项目。如:node中的express
  2. 库(插件):提供某一个小功能,对项目的侵入性比较小,如果某个库无法完成某些需求,可以很容易切换到其他库实现需求

Node(后端)中的MVC与前端中的MVVC之间的区别

  • MVC是后端的分层开发概念

  • MVVM是前端的视图层的概念,主要关注于视图层分离,也就是说:MVVM把前端的视图层,分为了三部分:Model, View, VM ViewModel

  • MVVM

    • Model层:职能单一,只负责操作数据库,执行对应的sql语句,进行数据的CRUD(creat、read、update、delete)。M保存的是每个页面中单独的数据
    • View层:每当用户操作了界面,如果需要进行业务的处理,都会通过网络请求,去请求后端的服务器,此时,我们的这个请求,就会被后端的项目入口模块监听到。V就是每个页面中的HTML结构
    • VM是MVVM思想的核心:因为VM是M和V之间的调度者。每当V层想要获取后保存数据的时候,都要由VM做中间的处理
    • 取数据:M->VM->V;存数据:V->VM->M
  • 前端页面中使用MVVC的思想,主要是为了让我们开发更加方便,因为MVVM思想突出贡献了数据的双向绑定。注意:数据的双向绑定是由VM提供的


Vue的使用

简介




    vue
    
    
    
    


    

{{msg}}

v-cloak v-text v-html

代码实例:




    vue
    
    
    
    
    


    

{{msg}}

{{msg2}}
143

结果如下:


在这里插入图片描述

使用v-on指令定义Vue中的事件

v-on相当于jquery中的click(原生js中的onclick)

  1. :会弹出hello;如果是自己在methodes中定义的方法,用引号将方法名引起来



    vue
    
    
    


    

ps:v-bind绑定属性(缩写:":");v-on:绑定事件(缩写:"@")

案例:跑马灯效果

暂略

事件修饰符

  1. .top 阻止冒泡
  2. .prevent 阻止默认事件,比如a标签的跳转,表单的submit
  3. .capture 添加事件侦听器时使用事件捕获模式,默认是冒泡机制,从内而外,如果是用捕获机制,从外而内
  4. .self 只当事件在该元素本身(比如不是子元素,也不是父元素,即:冒泡或捕获不会触发)触发时触发回调
  5. .once 事件只触发一次

事件修饰符可以串联:@click.prevent.once:只阻止一次默认行为(代码的先后顺序无关)

.self与.stop的区别:.self只阻止自己的冒泡(比如:子元素产生的冒泡自己不执行,但是依旧将其继续向上冒泡),而.stop阻止所有的冒泡

用法:在事件后面加.修饰符

eg:利用修饰符阻止冒泡




    阻止冒泡
    
    
    


    

v-model实现双向数据绑定

只有这个属性可以实现双向数据绑定




    数据的双向绑定
    
    
    


    

{{ msg }}

效果图:修改第二个文本框内的内容时,其他的内容会跟着自动修改

在这里插入图片描述

案例:计算器




    数据的双向绑定
    
    
    


    

在vue中使用样式

使用class样式

  1. 数组:

    这是一个h1

    ,其中,red是一个样式类,thin也是一个样式类。h1后面的冒号是v-bind的缩写,注意:类名必须用引号,列表也必须用引号
  2. 数组中使用三元表达式:

    这是一个h1

    ,但是代码不易读
  3. 数组中使用嵌套对象:

    这是一个h1

    ,其中,isactive是一个布尔类型变量
  4. 直接使用对象:这是一个h1,true表示使用该样式,也可以写成变量的形式,如:这是一个h1,其中,flag是data中的一个属性。注意:类名不用引号也可以。以上代码中也可以将{...}写在data区域中,如:

这是一个h1

...... var vm = new Vue({ el:'#app', data:{ classObj:{'red':flag,' italic':flag, 'active':flag, thin:flag}, } })

使用内联样式

  1. 直接在元素上通过:style的形式,书写样式,如:

    这是一个h1

    ,如果属性里面有短横线,就不能省略引号,如果要省略,就必须写成驼峰法
  2. 将样式对象,定义到data中,并直接引用到:style中。在data上定义:data:{ h1Style:{color: 'red', 'font-size':'40px'}},在元素中,通过属性绑定的形式,将样式对象应用到元素中

    这是一个h1

  3. :style中通过数组,引用多个data上的样式对象,

    这是一个h1

    ,其中,列表中的每一个style对象都在data中有定义h1Style:{xxx}

v-for指令的四种使用方式

  1. 迭代数组(包括对象数组)
  • 索引:{{i}}---姓名:{{item.name}}---年龄:{{item.age}}

以上代码可以创建多个li标签;如果用不到索引值,i可以省略,此时小括号也可以省略

  1. 迭代对象中的属性
{{val}}---{{key}}---{{i}}---

ps:迭代对象属性时,第三个参数为索引,第一个为值,第二个为键

  1. 迭代数字

这是弟{{i}}个p标签

注意:用v-for迭代数组,从1开始

v-for的使用注意事项:在2.2.0+的版本里,当在组件中使用v-for时,key是必须的

案例:添加列表项




    数据的双向绑定
    
    
    


    

{{item.id}}:{{item.name}}

效果图如下:


在这里插入图片描述

v-if和v-show

二者都是控制元素的显示与隐藏

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

v-show的特点:每次不会重新进行DOM的删除和创建操作,只是切换了元素的display:none属性;

因此,v-if有较高的切换性能消耗,v-show有较高的初始渲染消耗

如果元素涉及到频繁的切换,最好不要使用v-if;如果元素可能永远都不会给用户显示出来,最好用v-if

代码示例:利用v-if和v-show切换元素的显示与隐藏




    数据的双向绑定
    
    
    


    

这是用v-if控制的元素

这是用v-show控制的元素

品牌管理案例:知识点的综合运用及新增知识点讲解

在vue中,使用事件绑定机制,为元素制定处理函数的时候,如果加了小括号,就可以给函数传参了


过滤器

vue.js允许自定义过滤器,可被用做一些常见的文本格式化,过滤器可以用在两个地方:mustachc插值和v-bind表达式。过滤器应该被添加在javascript表达式的尾部,由“管道”符指示

过滤器的调用时候的格式:{{ name | nameope }} :在使用name的值之前,先调用nameope对其进行处理,并把处理的结果当成内容进行渲染,nameope即过滤器的名称

过滤器中的function,第一个参数已经固定死了,永远是过滤器管道符前面传过来的数据,参数名可以自己随便取,也可以设置默认参数

如果要对过滤器传参,就在过滤器(上面例子的nameope处)加小括号传参即可,但是应注意:过滤器的第一个参数永远是管道符前面的数据,因此传过的来的参数至少在第二个形参位置

过滤器还可以多次连续调用:如:{{msg | msgFormat1 | msgFormat2}}:把原始数据交给第一个过滤器处理,第一个过滤器处理后的数据再交给第二个过滤器处理,第二个过滤器处理后在拿去使用

ps:字符串的replace方法,第一个参数除了可以是字符串之外,还可以是正则表达式

模板字符串:

`$(y)-$(m)-$(d)`    //其中,y,m,d都是变量

全局过滤器

所谓全局过滤器,就是所有的vm实例都能够共享

全局过滤器的定义写在vue对象的同一级别

全局过滤器的定义:Vue.filter("过滤器的名称", function(){}),function表示要对传过来的数据进行什么样的处理

私有过滤器

私有过滤器写在vue对象的内部,与data同级别

定义方法:

filters:{   //在内部定义过滤器
    dateFormate:function(data, pattern){
        ......
    }
}

过滤器调用的时候是采用就近原则:如果私有过滤器和全局过滤器名称一致,优先调用私有过滤器(指在管那个标签的vue中定义的私有过滤器)

字符串的padStart方法

字符串.padStart(maxlength, fillstring):第一个参数为指定的宽度,第二个参数为填充字符,如果宽度不足,就在字符串的开头用该字符填充

与padstart方法相匹配的有padEnd()方法,用法与padstart一样,但是在字符串末尾填充

ps:数字.toString(),可以将数字转换成字符串格式

自定义按键修饰符

用法示例:


//任意按键被点击时,调用add方法

如何指定某个固定键?格式如下:


//绑定了enter键,当点击enter键时,才调用add

常用按键别名:

  1. enter
  2. tab
  3. delete:获取删除和退格键
  4. esc
  5. up
  6. down
  7. left
  8. right
  9. space

如果是其他键,直接将对应的键盘码替换别名即可;为了方便,常将键盘码“起别名”

自定义全局按键修饰符

Vue.config.keyCodes.f2=113,

然后就可以将“f2”与enter,esc等按键一样直接用别名,注意:113是f2的键盘码

在vue中,所有的指令都以v-开头

自定义指令

自定义全局指令

使用Vue.directive()定义全局(与vue对象的定义处于同一级)的指令,在使用的时候,直接将v-指令名放在标签中即可

其中:

  1. 参数一:指令的名称,注意:在定义的时候,指令的前面不需要加v-前缀,但是在调用的时候,必须在指令的前面加上v-前缀进行调用
  2. 参数二:是一个对象,这个对象身上,有一些指令相关的函数,这些函数可以在特定的阶段,执行相关的操作

示例:

Vue.directive('focus',{
    bind:function(el){
    //el就是绑定到的元素,注意,在每个函数中,第一个餐具是,永远是el,这个el参数,是一个原生的js对象
    //在元素刚绑定指令的时候,还没有插入到DOM中去,这时候调用focus方法没有用
    el.focus(),
    },
    inserted:function(el){el.focus()
    //由于inserted方法只要父节点存在即可调用,不必插入document,所以可以在此处写focus,让页面一刷新,绑定的元素就自动获取焦点
    },
    updated:funcion(){}
})
  1. bind:只调用一次,指令第一次绑定到元素时调用,用这个函数可以定义一个在绑定时执行一次的初始化操作
  2. inserted:被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于document中)。通常而言,对于行为,一般写在inserted中,防止行为不生效;而如样式之类的一般写在bind中即可
  3. updated:做在的组件的VNode更新时调用,但是可能发生在其孩子的VNode更新之前,指令的值可能发生了改变也可能没有,但是你可以通过比较更新前后的值来忽略不必要的模板更新;可能触发多次
  4. componentUpdated:被绑定元素所在模板完成一次更新周期时调用。
  5. unbind:只调用一次, 指令与元素解绑时调用。

以上函数均被称为钩子函数,后两者一般用得较少

含参案例:


其中,v-focus和v-color都是自定义指令,v-focus自动获得焦点,v-color设置字体颜色,可以传参,此处传的参数为“blue”,注意:外面的引号中还有引号,如果只有一个引号,就当变量

钩子函数的参数

  1. el:指令绑定的元素,可以用来直接操作DOM

  2. binding:一个对象,包括以下属性

    • name: 指令名,不包括 v- 前缀。
    • value: 指令的绑定值, 例如: v-my-directive="1 + 1", value 的值是 2。
    • oldValue: 指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
    • expression: 绑定值的表达式或变量名(即字符串格式)。 例如 v-my-directive="1 + 1" , expression 的值是 "1 + 1"。
    • arg: 传给指令的参数。例如 v-my-directive:foo, arg 的值是 "foo"。
    • modifiers: 一个包含修饰符的对象。 例如: v-my-directive.foo.bar, 修饰符对象 modifiers 的值是 { foo: true, bar: true }。

自定义私有指令

写在vue对象中,格式如下:其他和全局相同

var vm = Vue({
    ......
    directives:{
        'fontWeight':{
            bind:function(){},
            inserted:function(){},
            ...
        }
    }
})

函数简写

大多数情况下,我们可能想在bind和update钩子上做重复动作,并且不想关心其他的钩子函数,可以这样写:

Vue.directive('color-switch',function(el,binding){
//注意:这个function等同于将代码写到了bind和update中去
    el.stylee.backgroundColor = biding.value
})

Vue实例的生命周期

  • 什么是生命周期:从Vue实例创建、运行、到销毁,总是伴随各种各样的事件,这些事件,统称为生命周期

  • 生命周期钩子:就是生命周期事件的别名,也就是生命周期函数

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

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

      • beforeCreate:实例刚在内存中被创建出来,此时,还没有初始化好data和methods属性
      • created:实例已经在内存中创建了,此时data和methods已经创建好,此时还没有开始编译模板。如果要使用各个属性与方法,最早的时间即是此时
      • beforeMount:此时已经完成了模板的编译,但是还没有挂载到页面中。在beforeMount执行的时候,页面中的元素,还没有被真正的替换过来,只是之前写的一些模板字符串,此时,页面还是旧的
      • mounted:此时,已经将编译好的模板,挂载到了页面指定的容器中显示,此时,页面上的东西就是最新的了。如果要通过某些和的ODM节点,最早要在mounted中运行。只要执行了mounted,就表示这个vue实例已经初始化完毕了,此时,组建已经脱离了创建阶段,进入到了运行阶段
    • 运行期间的生命周期函数:

      • beforeUpdate:当数据被更新,状态更新之前执行此函数,此时data中的状态值是最新的,但是节目和显示的数据还是旧的,因为此时还没有开始重新渲染DOM节点
      • updated:实例更新完毕之后调用此函数,此时data中的和界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了
      • 以上两事件会根据data数据的改变,有选择的触发,0次到多次
    • 销毁期间的生命周期函数:

      • beforeDestroy:实例销毁之前调用,在这一步,实例仍然完全可用。还没真正执行销毁过程
      • destroyed:Vue实例销毁后调用,调用后,Vue实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁

这些方法,都可以在methods中重写,但是要注意其各个函数的执行时机(比如beforeCreate函数在调用时,data和methods都还未被初始化好)

主要分为:创建前后、挂载前后、更新前后、销毁前后

vue-resource发起get、post、jsonp请求




    vue-resource
    
    
    
    
    

    
    
    
    


    

JSONP的实现原理:

  1. 由于浏览器的安全级别限制,不允许AJAX访问协议不同、域名不同、端口号不同的数据借口,浏览器认为这种访问不安全

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

  3. 具体实现过程:

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

vue中的动画

动画的四个时间点两个阶段:

  1. 进入阶段:v-enter(此时透明度为0)到v-ener-to(此时透明度为1),称做v-enter-active
  2. 离开阶段:v-leave(此时透明度为1)到v-leave-to(此时透明度为0),称做v-leave-active

因为v-enter和v-leave-to的透明度一样,所以可以写为一组,同理,中间的两个时间点也可以写做一组

使用过渡类名




    动画
    
    
    


    
    
    
    
    

这是一个h3

效果图:点击时会淡入淡出

在这里插入图片描述

如何修改v-前缀:使用transition标签中的name属性,eg:name='my',就表示以后所有的前缀不再是v-而是my-,也可以用此法实现多组动画样式

使用第三方类实现动画

第三方类库:animate.css

视频中的代码是这样的,但是自己的效果没有出来。。。问题尚未解决




    组件
    
    
    
    
    
    



    

这是一个h3

钩子函数实现半场动画

所谓半场动画,就是只有进入的动画,或者只有退出的动画,用之前的两种无法做出这种效果

可以在属性中声明javascript钩子(也可以被称为动画的生命周期函数)

前四个是进入,后四个是离开


案例:利用钩子函数实现小球的半场动画




    组件
    
    
    
    
    
    



    

效果图:


在这里插入图片描述

明明每次动画后都只是将小球隐藏了,但是为什么每次点击按钮的时候,小球还是从0,0位置出现?

答:因为一轮动画完成后,当我们重新点击按钮,又是一轮新的动画,此时会执行beforeEnter,就会重置小球的位置

使用transition-group元素实现列表动画




    组件
    
    
    
    
    
    


    
  • {{item.id}}---{{item.name}}

效果图:


在这里插入图片描述

vue组件

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

组件化和模块化的区别:

  1. 模块化是从代码逻辑的角度进行划分的;方便代码分层开发,保证每个功能模块的职能单一
  2. 组件化是从ui界面的角度进行划分的;前端的组件化,方便ui组件 使用

定义vue组件

注意:无论是哪种方式创建的组件,组件的template属性指向的模板内容,必须有且只有一 个根标签

全局组件定义的三种方式

全局组件在任意Vue控制的区域内都可以使用

  1. 使用Vue.extend配合Vue.componenet方法
var login_obj = Vue.extend({
    template:'

登录

' }); Vue.component('login',login_obj);//将login_obj组件对象注册为名为login的组件

案例:




    组件
    
    


    

如果取消中间变量,则可以写成:

Vue.component('register',Vue.extend({
    template:'

注册

' }));

第一个参数是组件的名称,将来在引用组件的时候,就是一个标签形式来引入它
第二个参数:Vue.extend创建的组件,其中,template就是组件将来要展示的内容

  1. 直接使用Vue.component方法,给它传一个字面量的对象

还是使用标签的形式引用自己的组件

Vue.component('register',{
    template:'

注册

' });
  1. 将模板字符串,定义到script标签中

同时,需要使用Vue.component来定义组件

Vue.component('account',{
    template:'#tmpl'
});

案例:




    组件
    
    


    
    
    

效果:


在这里插入图片描述

实例内部私有组件的定义

ps:凡是私有的,都只能在自己的控制区域使用

定义:

var vm = new Vue ({
    el:'#app',
    data:{},
    methods:{},
    components:{
        组件名:{
            template:"

这是私有的组件,也是一个HTML字符模板即可

" } } })

案例:




    组件
    
    


    

效果图:


在这里插入图片描述

当然,也可以将模板提到自己的控制区外单独定义




    组件
    
    


    
    

效果图:


在这里插入图片描述

其他定义组件的方法

1. 通过对象字面量的形式
var login = {   //login就是一个组件模板对象
    template:'

23

' } Vue.component('mylogin',login) //定义全局 2.也可以用上面的login对象定义私有的组件 var vm=new Vue({ el:... data:{...} methods:{...} components:{ mylogin:login //注意:此处还可以就写一个login,其他的啥都不写,此种方法说明,此处定义了一个变量,这个变量会被解析为属性,它的属性名和变量名相同(即属性值和变量名相同) } })

组件中的data




    组件
    
    


    

效果图:


在这里插入图片描述

组件中的data为什么要是一个function

案例:data中返回一个外部定义的对象




    组件
    
    


    
    

效果图:


在这里插入图片描述

此种方法的弊端,当有多个模板实例的时候,返回的是同一个对象,所以他们共享这个对象的属性

所以在return时,一定要是一个新的对象,写成形如:return { count: 0} 的形式就能保证每一个实例对象的data都是独有的,不共享

不同组件间的切换

利用v-if和v-else实现组件的切换




    组件
    
    


    

    


效果图:


在这里插入图片描述

当点击登录或注册文字时,下方的显示文字会切换

利用:is实现组件的切换




    组件
    
    


    
登录 注册
----------分隔符----------

效果图:点击最上方的文字是,最下面的文字会切换


在这里插入图片描述

组件的切换动画

  1. 直接使用transition标签将组件包裹起来,如

    

  1. 加上两个节点和两个阶段的样式
.v-enter,.v-leave-to {}
.v-enter-active, .v-leave-active {}

ps:在transition标签中,可以指定模式,例如:这是子组件...{{finfo}}' props:['下面的自定义属性名'] } } })

  1. 使用v-bind或简化指令,将数据传递到子组件中

案例:




    组件
    
    
    
    


    

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

方法也是数据的一种,因此父组件也能够把方法传给子组件,利用父组件把方法传递给子组件,子组件就能够将自己的数据以参数的形式给该方法,从而让父组件获得该数据




    组件
    
    
    
    


    

使用this.$refs来获取元素和组件




    组件
    
    
    
    


    

哈哈,这是一个H3

效果图:


在这里插入图片描述

路由

什么是路由

  1. 后端路由:对于普通的网站,所有的超链是url地址,所有的url地址都对应服务器上对应的资源
  2. 前端路由:对于单页面应用程序来说,主要通过url中的hash(#)来实现不同页面之间的切换,同时,hash有一个特点:HTTP请求中不会包含hash相关的内容;所以,单页面程序中的页面跳转主要用hash实现,即不会和服务器有交互
  3. 在单页面应用程序中,这种通过hash改变来切换页面的方式,称作前端路由(区别于后端路由)

在vue中使用vue-router

使用方法:

  1. 导包
  2. 路由是为了组件的切换,所以应该创建子组件
  3. 创建一个路由对象,定义路由规则
  4. 路由要展示,在页面上要有容器——router-view.
  5. 官方建议使用去往某个路由

案例:当点击跳转不同的url时,显示不同的组件,并且被激活的链接采用不同的样式类




    路由的基本使用
    
    
    
    
    
    


    
登录 注册

效果图:


在这里插入图片描述

在路由规则中定义参数

  1. 在规则中定义参数:{path:/register:id, component:register},使用query的方式访问

案例:

案例:

```html



    在路由规则中定义参数
    
    
    
    


    
登录 注册

效果图:


我们也可以看到 ,在$route对象的query中,有id和name两个属性,所以我们在login组件中直接取出并展示在了页面上

  1. 通过this.$route.params来获取路由中的参数
var register = Vue.extend({
    template:'

注册组件---{{this.$route.params.id}}

' })

案例:




    在路由规则传参方式2
    
    
    
    


    
登录 注册

效果图:


使用children属性实现路由嵌套




    路由的嵌套
    
    
    
    


    
account

效果图:


利用命名视图实现经典布局




    命名视图-经典布局
    
    
    
    


    

效果图局部:


名称案例

使用@keyup监听按键的松开以实现对数据变动的监听




    名字拼接
    
    
    
    


    
+ =

使用watch监听文本框数据的变化




    命名视图-经典布局
    
    
    
    


    
+ =

效果图:


watch的优点:可以监听看不到的数据的改变,比如路由的改变,就无法使用keyup进行监听,而watch就可以

watch监听路由地址的改变

路由地址:$route.path




    路由的基本使用
    
    
    
    


    
登录 注册

当路由地址改变的时候,就会弹出弹窗

计算属性

案例:利用计算属性实现名字的拼接




    命名视图-经典布局
    
    
    
    


    
+ =

watch、computed、methods的对比

  1. 计算属性和watch都是function
  2. 在计算属性内部,无论如何都要return一个值,而watch中没有return值
  3. methods也是一个function,但是这个fucntion里面更重视业务逻辑的处理,表示一个具体的操作
  4. watch可以看作是computed和methods的结合体,更方便监听一些虚拟的

你可能感兴趣的:(Vue)