简介
MVVM设计模式:
- model: 数据模型(处理数据的业务逻辑)
- view: 视图(展现数据,与用户交互)
- view-model: 数据模型与视图的桥梁
Vue中的MVVM划分:
- model: 实例对象中的数据
- view: 被控制的区域
- view-model: Vue的实例对象
Vue中的数据单向传递的过程:
- model --> view-model --> view
Vue数据的双向绑定:
- 使用v-model来绑定数据
- 修改元素内容数据,model中的数据也随之改变
- 仅支持双向绑定的三个标签:
- input
- textarea
- select
指令
什么是指令?
- 指令就是Vue里自定义的一些属性,这些自定义的属性封装着一些方法,可以通过这些指令来完成一些任务
Vue数据绑定的特点:
- 数据绑定的特点是,当数据发生改变的时候,视图也会立即改变,反之亦然.并且只有三个标签才可以双向绑定
Vue数据绑定过程:
- 先从数据和视图进行绑定
- 生成绑定好的模型
- 交给浏览器渲染
v-once:
- 因为Vue数据绑定的特性,使用v-once绑定以后视图或数据只发生一次变动
v-cloak:
因为浏览器渲染时,会先渲染HTML标签,再将Vue绑定好的模板交给浏览器渲染,有时候网速较慢时就会看到原始页面,为了避免这个不足,v-cloak就可以把HTML标签先隐藏,等Vue模板渲染好以后直接显示出来Vue的view视图
```!
v-cloak必须要配合CSS才能有效果,一定要加上 [v-cloak] { display: none }
```
```
示例:
[v-cloak] {
display: none;
}
<div v-cloak>内容</div>
```
v-text与v-html:
- v-text: 把数据插入到标签中,会覆盖原有内容,不会解析HTML标签
- v-html: 把数据插入到标签中,会覆盖原有内容,会解析HTML标签
- 插值方式:把数据内容插到指定位置,不会修改标签内部原有内容
<p v-text="name">+++</p> // name <p v-html="name">+++</p> // name <p>+++{{ name }}</p> // +++name
v-if和v-show:
-
都是满足条件就渲染数据
-
v-if:
- 特点:
- 如果条件没有满足,就不会加载该元素
- 不仅仅可以填data内的值,还可以在v-if="" 引号中写表达式
<p v-if="age >= 18">- 有v-else与其配合,但是v-if一定要跟在v-if下面,中间不可以有别的标签存在
// 如果条件满足就渲染a,不满足就渲染b <p v-if="age >= 18"> {{a}} </p> <p v-else="age < 18"> {{b}} </p> - 注意点:
- 如果条件没有满足,就不会加载该元素
- v-if和v-else一定要连在一起,中间不可以添加元素
- 特点:
-
v-show:功能和v-if一样
-
两者区别:
- v-if: 只要条件不满足,元素就不会被创建
- v-show: 无论是否满足条件,元素都会被创建渲染,但是false状态下的数据 display = none
v-for
- 格式:
<p v-for="(value,key) in obj">{{ value }} : {{ key }}</p> let vue = new Vue({ el: "#app", data:{ obj: { name: "zs", age: 18, gander: "man", class : "3班" } } }) // 输出结果:创建了4个li标签,并通过 value , key添加到了标签中 - 注意点:
- 不仅仅可以遍历obj,in后面还可以遍历数组,数字,字符串,但是无论是遍历谁,都有value和index
v-bind
- 什么是v-bind:
- 给任意元素的任意属性绑定数据,但是添加类比较特殊,需要用特定的格式
- v-bind格式:
<input type="text" v-bind:value="name"> // 整体写法 <input type="text" :value="name"> // 简写 - v-bind和插值/v-text/v-html的区别:
- v-text/v-html/插值绑定 都是给元素绑定数据
- v-bind是给元素的属性绑定数据
- v-bind绑定类名:
- 格式:
- 因为vue是先从model中找数据渲染,所以绑定类名时要把类名放到数组中用单引号包起来,才会让vue去style中找数据
<p :class="['size','color','bgc']">我绑定了类名</p> - 也可以把类写到model中,来让vue渲染,格式如下:
<p :class="obj">我绑定了类名</p> let vue = new Vue({ el: "#app", data:{ obj: { size: true, color: false, bgc: true } } })
- 因为vue是先从model中找数据渲染,所以绑定类名时要把类名放到数组中用单引号包起来,才会让vue去style中找数据
- 注意点:
- 绑定类名时要么存在model中,以 类名: true/false 的形式来保存,要么就存在数组中,以单引号包裹起来保存
- 格式:
v-on
-
v-on的作用:
- 用于给元素添加事件监听的
-
v-on的格式:
- 完整版:
<button v-on:click="myFn()">我是按钮</button>- 简写版: 用@代表v-on
<button @click="myFn()">我是按钮</button> let vue = new Vue({ el: "#app", methods:{ myFn(){ alert("你成功了") } } }) -
v-on的修饰符:
- 修饰符是用来应对一些监听事件的特殊情况的解决办法
- .once: 监听事件只执行一次(由于监听的回调函数默认是只要触发就会一直执行,.once的修饰符就是让该事件只触发一次)
- .stop: 阻止事件冒泡
- .prevent: 阻止元素的默认行为(例如a标签点击以后会跳转页面)
- .self 当本身元素触发事件时再执行
- .capture 事件冒泡是从内向外,该修饰符可以让事件从外向内执行
- 修饰符的格式:
<button @click.once="myFn()">我是按钮</button> // 点击完按钮,弹了一次框以后,再点击按钮就不弹框了 - 修饰符是用来应对一些监听事件的特殊情况的解决办法
-
v-on的注意点:
- 如果用到了data内的数据,要加上this
-
v-on按键修饰符:
- 什么是按键修饰符:
- 监听键盘的一些事件,触发事件以后执行methods中的对应函数
<input type="text" @keyup.enter="myfn"> // 当按下enter键时,触发myfn函数- 默认支持监听哪些按键:
- enter
- tab
- delete(捕获删除和退格(backspace))
- esc
- up
- down
- left
- right
- 自定义设置键盘修饰符
// 先设置一个全局变量.赋予Vue Vue.config.keyCode.f2 = 113 // 再通过新定义的名字,来触发按钮 <input type="text" @keyup.f2="myfn"> // 当f2被按下的时候,触发myfn
- 什么是按键修饰符:
自定义全局指令
```
Vue.directive("指令名称",{
生命周期.function(ele){
ele.具体操作;
}
})
```
-
自定义指令时有不同的生命周期(称之为钩子函数)
-
bind: 当自定义的指令被绑定到元素上时触发
-
inserted: 当被绑定的元素被创建渲染时触发(被添加到父元素时被触发)
-
代码示例:
<div id="app"> <input type="text" v-focus> </div> // 定义了一加载好页面就把input聚焦的指令 Vue.directive("focus",{ inserted: function (ele) { ele.focus(); } }); let vue = new Vue({ el: "#app", })注意!: 定义自定义全局指令是在View-model上面定义的,并不是在model模型中定义!!
-
-
指令钩子函数会被传入以下参数:
- el:指令所绑定的元素,可以用来直接操作 DOM 。
- binding:一个对象,包含以下属性:
- name:指令名,不包括 v- 前缀。
- value:指令的绑定值
示例:
<p v-color="'red'">我是段落</p> Vue.directive("color",{ bind:function (el, obj) { el.style.color = obj.value; } }); // 改段代码使得P标签被渲染时可以动态设置参数
自定义局部指令
- 局部自定义变量和全局自定义变量的区别:
- 全局自定义变量是写在view-model外面------ 局部变量写在view-model中
- 全局自定义变量是directive-------------------局部自定义变量是directives
- 代码示例:
因为directives写在app2的实例中, 所以只有段落2颜色改变
<div id="app1">
<p v-color="'red'">我是段落1</p>
</div>
<div id="app2">
<p v-color="'purple'">我是段落2</p>
</div>
let vue2 = new Vue({
el: "#app2",
data:{
},
methods:{
},
directives:{
color:{
bind:function (el, obj) {
el.style.color = obj.value;
}
}
}
})
计算属性
- 计算属性和定义函数方法的区别:
- 计算属性的特点: 只要return的值没有发生改变,计算属性就只会被执行一次
- 函数方法的特点: 每次调用都会被执行
- 如何选择两个方法:
- 如果绑定的数据不经常改变的话,就使用计算属性
- 如果绑定的数据经常发生变化的话,就用methods里定义的函数
- 格式:
<p>{{ msg }}</p>
let vue = new Vue({
el: "#app",
data:{
// model,存储数据的
},
methods:{
// 专门用来保存事件监听回调函数的
},
directive:{
// 用来定义局部自定义指令的
},
computed:{
// 用来计算属性的
msg: function () {
let res = "abcde".split("").reverse().join("");
return res;
}
}
})
过滤器
全局过滤器
如何制定一个全局过滤器
- 通过Vue.filter("过滤器名称",处理数据函数)
使用过滤器:
// 从model中抽取name,交给过滤器formatStr处理数据
// 如果有两个过滤器,那么从左到右依次处理数据(name)
<p>{{ name | formatStr}}</p>
// 定义一个全局过滤器,value就是html中的name
// 过滤器处理完数据以后return 就是把值交给浏览器渲染
Vue.filter("formatStr",function (value) {
value = value.replace(/学院/g,"大学");
return value;
});
局部过滤器:
- 和自定义局部指令一样,写在view-model中
过渡动画
如何定义过度动画:
- 使用类名类定义过渡动画
- 配合css第三方库来使用过渡动画:animate
- 使用钩子函数操作DOM
- 配合js第三方库来使用过度动画:Velocity
1. 添加类名来定义过渡动画
- 把需要显示(v-show)或者渲染(v-if)的组件放到transition标签中
- 定义显示或者消失的状态
六个类名状态:
- 显示
- .v-enter : 表示显示前元素的状态
- .v-enter-to : 表示显示元素的目标状态
- .v-enter-active : 填写transition属性 -隐藏
- v-leave: 表示隐藏前元素的状态
- v-leave-to: 表示隐藏元素的目标状态
- v-leave-active : 填写transition属性
使用注意点:
- 一个transition组件,只支持一个元素的过度动画
- 自动触发过渡效果: 给元素对应的transition标签添加 appear属性
<transition appear> <div class="box" v-show="isShow"></div> </transition> - 当多个需要过渡动画的元素要执行不同的动画时,可以给transition定义一个name,把类名中的v-改成name中的参数,这样就可以指定不同的动画了
.one-enter{
opacity: 0;
}
.one-enter-to{
margin-left: 500px;
opacity: 1;
}
.one-enter-active{
transition: all 3s;
}
.two-enter{
opacity: 0;
}
.two-enter-to{
margin-top: 500px;
opacity: 1;
}
.two-enter-active{
transition: all 3s;
}
<transition appear name="one">
<div class="box" v-show="isShow"></div>
</transition>
<transition appear name="two">
<div class="box" v-show="isShow"></div>
</transition>
2. 使用钩子函数定义动画
- 未掌握
3. 配合css第三方库使用过渡动画:animate
- 在transition标签中使用 animated+动画名称
<transition
appear
enter-class=""
enter-to-class="animated jello">
<div class="box"></div>
</transition>
列表动画
- 遍历数据,批量创建li
<transition-group appear>
<li v-for="(person,index) in persons" :key="person.id">
<input type="checkbox">
<span>{{ person.name}}</span>
</li>
</transition-group>
let vue = new Vue({
el : "#app",
data:{
persons : [
{name:"yqy",id:1},
{name:"zs",id: 2},
{name:"管事新",id:3},
],
id: 4,
name:""
},
methods:{
add: function () {
let newPerson = {name: this.name, id: this.id};
this.id++;
this.persons.unshift(newPerson);
this.name = ""
},
del: function () {
}
}
})
注意点:
- 一个transition只能包裹一个标签
- 如果需要包裹很多标签的话,需要使用transition-group包裹
- transition-group默认把标签加载到'<span>'元素中,需要添加tag属性来指定把包裹的标签添加到什么元素里
- 例如
<transition-group appear tag="div">
<li v-for="(person,index) in persons" :key="person.id">
<input type="checkbox">
<span>{{ person.name}}</span>
</li>
</transition-group>
如图所示,当transition-group的tag属性设置为div后,包裹的li都被div所包裹
