双向绑定
既能将程序中的变化,自动更新到页面上,又能将页面上发生的变化,更新回程序中的变量中
问题:传统的绑定方式,用户在页面上输入新内容,程序的变量也不会改变,无法获得用户输入的新值
原因:12种的指令和绑定语法都知识单向绑定
(1)单向绑定:只能将程序的变化,更新到页面上,页面发生变化,无法更新到程序变量中(model-view)
解决:只要希望自动获得界面上修改内容时,都用双向绑定
(model-view) ,(view-model)
使用:<表单元素 v-model:value="变量">
原理:只要表单元素的value属性改变,newVue({})立刻将更新内容更新到变量中
双向绑定原理: v-model其实就是自动给元素绑定oninput或onchange事件。
(1). oninput事件是用户只要在文本框中输入新内容就会立刻触发
(2). onchange事件是用户切换选择select元素或单选按钮或复选框时自动触发!
不同类型的表单元素,双向绑定原理不同
1.文本框或文本域
特点:都是一个框,用户在框内输入文字.每次用户修改框内的文字时,都会修改元素的value
双向绑定时:<input v-model:value="变量">
<textarea v-model:value="变量">
2.单选按钮
特点:value是固定备选值,用户在不同radio之前切换选中状态时,改变的是checked属性值
所以:想要双向绑定获得当前选中的radio值,应该绑定checked属性:
<input type="radio" value="固定值" v-model:checked="变量">
从Model->View时: v-model会用当前变量的值和当前input的value属性值做比较。
i. 如果变量的值==当前input的value属性值,则当前radio选中!。
ii. 如果变量的值!=当前input的value属性值,则当前radio不选中!
2). 从View->Model时: 如果当前radio被选中,v-model才将input的value属性值自动更新回data中的变量里。
3.select 元素
特点:每个select包含多个option元素,所有备选值value,都分布在option,但是备选value是写死的
根据每次选择不同的option时,select元素会把选中的option的value值修改到select的值value值
原理:
1). 首屏加载时,Model->View,先获得v-model绑定的变量的值。用变量的值和每个option的value值做比较。哪个option的value值等于变量的值,则选中哪个option。
2). 当用户切换选择了不同的option时,option先将自己的value交给select的value。v-model再把select的新value,自动更新回data中的变量中。
4.复选框 checkbox
特点: 没有value属性 用户选与不选这个复选框 修改的是checked属性 而且,checked属性在表示是否选中时,是bool类型的true或false。
b. 所以,双向绑定时,应该用v-model绑定checked属性,且变量值应该为bool类型。
c. 如何:
<input type="checkbox" v-model:checked="bool类型变量"
d. 原理:
1). Model->View: 如果变量值为true,则当前checkbox为选中。否则如果变量值为false,则当前checkbox不选中
2). View->Model: 只要用户改变了checkbox的选中状态,v-model都会自动将当前checkbox的选中状态更新到data中的变量中。
所有v-model:属性=""中的":属性"都可省略 <表单元素 v-model="变量"> v-model自己就会根据当前所在的表单元素的不同选择对应属性绑定。
绑定样式
1.绑定内联样式:
不好的做法:将整个style属性,看做一个大的字符串,用一个变量绑定
问题: 很难只修改其中某一个css属性值。只能整体替换
好的做法:把style看成一个对象来绑定,每个CSS属性都是对象中的一个属性
原理: data中的变量值会成为css属性值,style后的{}会被编译为HTML规范的style字符串。
3). 强调: 属性值要加单位!!!
4). 好处: 非常便于修改其中某一个css属性的值!
5). 问题: 如果刚好别的元素也想修改这几个css属性,但是属性值各不相同,变量名冲突
6). 示例: 通过修改style修改飞机的的位置:
更好的做法:style="一个变量",在data中将变量定义为一个对象
优点: 即使多个元素刚好都要修改同一个css属性值时,因为不同元素绑定的对象不同,所以不同的对象内,是可以包含相同属性名的!就可以避免多个元素之间的css属性互相干扰.
示例: 使用对象方式板顶style,并控制飞机移动
2.绑定class
(1)不好的方式: 将整个class看做一个大的字符串来绑定
问题: 极其不便于修改其中某一个class
(2)好的方式: 对象语法
a. 直接在HTML中使用匿名对象:
1). 如何:
<元素 :class="{ class名1:变量1, class名2:变量2,... }"
data:{
变量1:true或false, //开关,是否启用一个class
变量2:true 或false //开关,是否启用一个class
}
2). 原理: new Vue()会从data中取出每个变量的bool值放到HTML中变量的位置上。如果哪个class的变量值为true,则这个class就会出现在最终编译后的页面元素上。如果哪个class的变量值为false,则这个class不会出现在最终编译后的页面元素上。
问题: 如果多个元素都需要使用同一个样式类,但是启用禁用状态各不相同 就会出现命名冲突
解决: 用有名称的对象来解决
自定义指令
除了官方提供的13种指令之外,根据自身需要为Vue添加的新的自定义指令
如何:
(1). 添加自定义指令:
a. Vue.directive("指令名", {
//回调函数: 会在当前标有这个自定义指令的元素被添加到页面上之后,自动调用该回调函数。
//当自动调用回调函数时,会自动将当前带有自定义指令的元素对象传入inserted函数内
inserted(当前dom元素对象){
//对当前DOM元素对象执行一些初始化操作
}
})
b. 结果: 在当前页面的内存中的Vue类型中,就多了一种自定义指令
c. 强调:
i. 定义指令名时,一定不要加v-前缀
ii. 如果指令名包含多个英文单词,比如my focus,应该-分割多个英文单词,比如my-focus,不应该用驼峰命名
(2). 如何使用自定义指令: 同使用官方指令完全一样!
html中: <元素 v-指令名></元素>
强调: 但是在使用指令时,却必须加v-前缀!
当new Vue()扫描到一个元素上带有不认识的v-开头的指令时,new Vue()就会在内存中,vue大家庭中,查找有没有同名的自定义指令!一旦找到同名的自定义指令,则自动调用指令中的inserted()函数,对当前带有指令的DOM元素执行初始化的DOM操作。
计算属性
有些值,需要根据其他属性值经过复杂的计算才能获得
自己不保存属性值,而是需要根据其他变量的值动态计算获得自己的属性值的特殊属性,就叫计算属性
如何:
(1). new Vue({
el:"#app",
data:{ ... },
methods:{ ... },
computed:{
计算属性名(){
复杂的计算过程
return 返回值
}
}
})
(2). 使用计算属性时:
<元素>{{计算属性名}}</元素>
强调:千万不要加()
原理:
(1). 首次new Vue()扫描到计算属性时,会自动执行计算属性的函数,获得返回值。new Vue()会立刻将本次计算的返回值缓存起来,反复使用。
(2). 下一次new Vue()再次扫描到同名的计算属性时,不会重复调用函数重复计算,而是自动从缓存中获取计算结果,直接使用!——避免重复计算,效率高!
(3). 除非当计算属性依赖的另一个变量值发生变化,才重新调用一次计算属性的函数,计算出新的结果,再次缓存起来反复使用!
computed中的计算属性与methods中的函数有什么差别:
(1). methods中普通函数的计算结果不会被缓存,导致反复计算——效率低
(2). computed中的计算属性值会被缓存,反复使用,不会反复计算——效率高
如何选择:
(1). 如果一个操作更倾向做一件事儿,而不太关心返回的结果时——优先选择methods
(2). 如果一个操作更倾向于使用操作的返回值时,而不太关心过程——优先选择computed。
过滤器
可以对变量的原始值进行加工后再显示出来 的函数
为什么: 程序中很多变量值是不能直接给人看的,必须经过加工才能显示给人看。比如:
(1). 性别: 程序中保存的是1和0,人希望看到的是男和女
(2). 时间: 程序中保存的是毫秒数,人希望看到的是年月日时分秒
如何:2步
(1). 为Vue大家庭添加过滤器函数:
Vue.filter("过滤器名称", function(变量的原始值){
← return 加工后的新值
})
(2). 在HTML中使用过滤器:
<元素>{{变量 | 过滤器名称}} </元素>
连接
5. 原理: 当new Vue()扫描到|过滤器语法时,就去Vue大家庭中查找有没有同名的过滤器。如果找到同名的过滤器,就自动调用过滤器函数。而且会将|前的变量的原始值自动传给过滤器函数的参数。在过滤器函数内对原始值进行加工后。过滤器函数返回加工后的新值。new Vue()再把新值显示到元素的内容位置
过滤器也可以传参数:
(1). 如何: 2步
a. 定义过滤器时:
Vue.filter("过滤器名",function(变量的原始值, 自定义形参, ...){
})
1). 第一个形参永远时变量的原始值
2). 自定义的其它形参必须从第二个位置开始写
b. 使用过滤器时:
<元素>{{变量 | 过滤器名(实参值1, ..., ...)}}</元素>
1). 调用时,自定义的第一个实参值,要放在过滤器第一个实参值位置,但是却是传给过滤器中第二个形参的
2). 调用时,变量的原始值总是默认传给过滤器的第一个形参。
过滤器也可以连用:
(1). 如何: <元素>{{变量 | 过滤器1 | 过滤器2 | ... }}</元素>
(2). 强调: 后一个过滤器接到的不是原始的变量值,而是前一个过滤器加工后的中间产物
(3). 示例: 为性别翻译后的结果追加性别图标