关键字:
指令、过滤器、修饰符
向元素中插入值 (02.基础v-xxx的学习.html)
- {{ msg }} 插值表达式
- v-cloak
- v-text
- v-html
- v-bind 绑定属性机制,简写
:
。 - v-on 事件绑定机制,简写
@
,语法:v-on:不带on的事件='注册的函数'
,举例:v-on:mouseover="showFn"
。 - 实例中的 this
- 跑马灯小练习
v-model 和 双向数据绑定 (03.v-model指令的学习.html)
v-model 是唯一一个可以实现双向数据绑定的指令
通常在表单控件中使用input(radio、text、address、email...)、select、checkbox、textarea
复习了 eval()
能够把字符串尽量转成js能够运行的代码,容易被注入病毒,正式开发中尽量少用。
Vue 中如何使用样式(04.Vue中的样式-class.html)
-
使用 class 样式
- 数组
<h1 :class="['red', 'thin']">这是个邪恶的h1</h1>
- 数组中使用三元表达式
<h1 :class="['red', 'thin', isactive ? 'active' : '']">这是个邪恶的h1</h1>
- 数组中嵌套对象
<h1 :class="['red', 'thin', {'active': isactive}]">这是个邪恶的h1</h1>
- 直接使用对象
<h1 :class="{red: true, thin: true, italic: true, active: isactive}">这是个邪恶的h1</h1>
- 数组
-
使用内联样式
- 直接在元素上通过
:style
的形式,书写样式对象
<h1 :class="{color: 'red', 'font-size': '40px'}">这是个善良的h1</h1>
- 经样式对象,定义到
data
中,并直接应用到:style
中
- 在data上定义样式
data: { styleObj1: { 'color': 'red', 'font-weight': 200 }, }
- 在元素中国,通过属性绑定的样式,将样式对象应用到元素中:
<h1 :style="styleObj1">这是个善良的h1</h1>
- 多个样式对象的使用
- 在data上定义样式
data: { styleObj1: { 'color': 'red', 'font-weight': 200 }, styleObj2: { 'font-style': 'italic', 'letter-spacing': '0.5em' } }
- 在元素中国,通过属性绑定的样式,将样式对象应用到元素中:
<h1 :style="[styleObj1, styleObj2]">这是个善良的h1</h1>
- 直接在元素上通过
v-for 和 key 属性 (05.v-for.html)
- 迭代数组:
<ul> <li v-for="item in list">{{item}}</li> </ul>
<ul> <li v-for="(item, index) in list">索引:{{index}}-->值:{{item}}</li> </ul>
<ul> <li v-for="(item, index) in data" :key='item.id'>id:{{item.id}}-->name:{{item.name}}</li> </ul>
- 迭代对象中的属性:
<p v-for="(val, key, index) in user">值:{{val}} --> 键:{{key}} --> 索引:{{index}}</p>
- 迭代数字:
<!-- 注意:如果使用 v-for 迭代数字的话,前面的 count 是从1开始的 --> <p v-for="count in 10">这是第{{ count }}次循环</p>
2.2.0+ 的版本里,挡在组件中使用v-for时,key现在是必须的。
当 Vue.js 用 v-for 正在更新已渲染的元素列表时,它默认使用就地复用策略。如果数据项的顺序被改变,
Vue将不是移动DOM元素来匹配数据项的顺序,而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每一个元素。
为了给Vue一个提示,以便它能跟踪每一个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一的 key 属性。
v-if 和 v-show 指令(06.v-if和v-show.html)(16-组件切换.html)
-
v-if:
- 每次都会重新删除或创建元素
- 有较高的切换性能消耗,如果元素涉及到频繁的切换,最好不要使用 v-if,推荐使用 v-show 。
-
v-show:
- 每次更新不会重新进行DOM的删除和创建操作,只是切换了元素的 display: none 样式
- 有较高的初始渲染性能消耗,如果元素可能永远也不会被显示出来,给用户看到,则推荐使用 v-if 。
-
v-else (注意:必须跟在v-if或者v-if-else的后面,不然失效)
- 如果if条件不成立显示当前的元素
-
v-else-if 要紧跟 v-if
品牌列表的案例(07.品牌列表的案例.html)
过滤器(07.品牌列表的案例.html)
概念:Vue.js 允许你自定义过滤器,可以用作一些常见的文本格式化,过滤器可以用在两个地方:mustache 插值和 v-bind 表达式。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符指示
- 过滤器的语法:
Vue.filter('过滤器的名称', function () {})
。 - 过滤器中的 function,第一个参数,已经被规定死了,永远都是 过滤器 管道符前面传过来的数据。
- 全局过滤器
Vue.filter()
要写在new Vue()
创建Vue实例之前。 - 私有过滤器
filters
。 - 过滤器调用的时候,采用的是就近原则,如果私有过滤器和全局过滤器名称一致了,优先调用私有过滤器。
全局过滤器、私有过滤器(07.品牌列表的案例.html)
- HTML元素
<td>{{ item.ctime | dataFormat('yyyy-mm-dd') }}</td>
- 全局过滤器
Vue.filter()
Vue.filter("dataFormat", function (ctime, pattern = "yyyy-mm-dd hh:mm:ss") {
const dt = new Date(ctime);
const year = dt.getFullYear();
const month = dt.getMonth() + 1;
const day = dt.getDate();
const houer = dt.getHours();
const minute = dt.getMinutes();
const second = dt.getSeconds();
let ds = "";
if (pattern && pattern.toLowerCase() === "yyyy-mm-dd") {
ds = `${year}-${month}-${day}`;
} else {
ds = `${year}-${month}-${day} ${houer}:${minute}:${second}`;
};
return ds;
});
- 私有
filters
定义方式:
const vm = new Vue({
el: "#app",
data: {...},
methods: {...},
filters: {
dataFormat: function (ctime, pattern = "yyyy-mm-dd hh:mm:ss") {
const dt = new Date(ctime);
const year = dt.getFullYear();
const month = dt.getMonth() + 1;
const day = dt.getDate();
const houer = dt.getHours();
const minute = dt.getMinutes();
const second = dt.getSeconds();
let ds = "";
if (pattern && pattern.toLowerCase() === "yyyy-mm-dd") {
ds = `${year}-${month}-${day}`;
} else {
ds = `${year}-${month}-${day} ${houer}:${minute}:${second}`;
};
return ds;
}
}
});
使用 ES6 字符串新方法
String.prototype.padStart(maxLenght, fillString="")
或者String.prototype.padEnd(maxLenght, fillString="")
来填充字符串
例子:
"1".padStart(2, 0) // "01"
事件修饰符(07.品牌列表的案例.html)
.stop => event.stopPropagation() // 阻止冒泡
.prevent => 调用 event.preventDefault() // 阻止默认行为
举例:
阻止 的默认跳转事件 @click.prevent="function"
html <a href="" @click.prevent="del(item)">删除</a> <!-- 也可以设置 href="javascript:;" 防止 a 标签跳转页面 --> <!-- <a href="javascript:;" @click="del(item)">删除</a> -->
按键修饰符、自定义按键修饰符(07.品牌列表的案例.html)
- Vue 提供的按键修饰符:
- enter / 13
- tab
- delete (捕获“删除”和“退格”)
- esc
- space
- up
- dowm
- left
- right
语法:
- 监听所有案件的抬起事件:
@keyup="fun"
, - 监听某个案件的抬起事件
@keyup.按键修饰符="fun"
或者@keyup.键盘码="fun"
。
举例:
<input type="text" v-model="name" @keyup.enter="add" />
<input type="text" v-model="name" @keyup.13="add" />
- 自定义全局按键修饰符:
<input type="text" v-model="name" @keyup.f2="add" />
// 113 是 F2 的键盘码。
Vue.config.keyCodes.f2 = 113;
自定义全局指令(07.品牌列表的案例.html)
注意:Vue中的所有指令,在调用的时候,都是以 v- 开头的。
通过 Vue.directive();
来定义全局指令。
其中 参数1:指令的名称。注意:在定义的时候,指令的名称前面,不需要加v-
前缀,但是在调用的时候,必须在指令名称前加上v-
前缀来进行调用
参数2:是一个对象,这个对象身上,有一些指令相关的钩子函数,这些钩子函数可以在特定的阶段,执行相关操作。
语法以及使用举例:
// 全局过滤器,所有的实例都共享
// 过滤器的语法: `Vue.filter('过滤器的名称', function () {})`
// 过滤器中的 function,第一个参数,已经被规定死了,永远都是 过滤器 管道符前面传过来的数据
// 过滤器 `Vue.filter()` 要写在 `new Vue()` 创建Vue实例之前
Vue.filter("dataFormat", function (ctime, pattern = "yyyy-mm-dd hh:mm:ss") {
const dt = new Date(ctime);
const year = dt.getFullYear();
const month = dt.getMonth() + 1;
const day = dt.getDate();
const houer = dt.getHours();
const minute = dt.getMinutes();
const second = dt.getSeconds();
let ds = "";
if (pattern && pattern.toLowerCase() === "yyyy-mm-dd") {
ds = `${year}-${month}-${day}`;
} else {
ds = `${year}-${month}-${day} ${houer}:${minute}:${second}`;
};
return ds;
});
使用:
<div>
{{item.ctime | dataFormat()}}
</div>
注册局部指令(07.品牌列表的案例.html)
举例:input 文本框自动获取焦点
const vm = new Vue({
el: "#app",
data: {
keyword: "",
...
},
methods: { // 自定义私有方法
...
},
filters: { // 自定义一个私有的过滤器
...
},
directives: { // 注册局部指令(自定义私有指令)
focus: {
// 指令的定义
inserted: function (el) {
el.focus()
}
}
}
});
<input type="text" v-model="keyword" v-focus></input>
钩子函数
一个指令定义对象可以提供如下几个钩子函数 (均为可选):
- bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
- inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
- update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
- componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
- unbind:只调用一次,指令与元素解绑时调用。
接下来我们来看一下钩子函数的参数 (即 el、binding、vnode 和 oldVnode)。
钩子函数参数
指令钩子函数会被依次传入以下参数:
- el:指令所绑定的元素,可以用来直接操作 DOM。
- binding:一个对象,包含以下 property:
- name:指令名,不包括 v- 前缀。
- value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2。
- oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
- expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"。
- arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"。
- modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。
- vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
- oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
除了 el 之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset 来进行。
指令函数的简写形式
directives: { // 注册局部指令
// focus: { // 指令的定义,完整写法
// inserted: function (el) {
// el.focus()
// }
// },
'fontSize': function(el){ // 注册指令 **简写** ,会同时注册到 `bind` 和 `updata` 钩子函数中去
const value = parseInt(binding.value) + "px";
el.style.fontSize = value;
}
}