vue过滤器、自定义指令以及生命周期
vue过滤器自定义指令生命周期vue过滤器
一、什么是过滤器?
用来格式化数据的一个函数vue 1.x 版本借鉴了 angular , 提供 10 个过滤器, 包括有: 日期 小数点位数保留 货币 大小写 等Vue 2.x 废弃了这 10个过滤器,但是它提供了自定义过滤器的方式
二、使用方式
全局定义过滤器
语法:
Vue.filter(‘过滤器名字’,function(value){value==谁调用fil过滤器 指向谁return//具体操作 })
案例1:<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="/npm/vue/dist/vue.js"></script></head><body><div id="app"><ul><li>{{msg | rep}}</li></ul></div></body><script>Vue.filter("rep", (value) => {var str = value.replace(/大傻子/g, "小傻瓜");return str;})var vm = new Vue({el: "#app",data: {msg: "你好,请问你是大傻子吗?是大傻子吧"},</html>
局部定义过滤器
案例:<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="/npm/vue/dist/vue.js"></script></head><body><div id="app"><ul><li>{{msg | rep}}</li><p>{{time | getTime("yyyy-mm-dd")}}</p></ul></div></body><script>Vue.filter("rep", (value) => {// return "hahah" + valuevar str = value.replace(/大傻子/g, "小傻瓜");return str;})var vm = new Vue({el: "#app",data: {msg: "你好,请问你是大傻子吗?是大傻子吧",time: new Date()},filters: {getTime(val, tj) {var time = new Date(val);var y = time.getFullYear();var m = time.getMonth() + 1;var d = time.getDay();var h = time.getHours();var mm = time.getMinutes();var s = time.getSeconds();console.log(tj)if (tj == "yyyy-mm-dd") {return `${y}-${m}-${d}`} else {return `${y}-${m}-${d} ${h}:${mm}:${s}`}}}})</script></html>
过滤器要想获得我们的数据,要通过一个叫做 ”管道符 | “的来获取数据过滤器是对已经有的数据进行格式化,也就是必须先有数据,再去格式化
自定义指令
简述
Vue框架给我们提供了许多指令,例如v-if 、v-else、 v-html、v-show、v-text、v-model、v-bind等等,这些指令都是固定的,并不能任意满足我们。Vue除了提供了默认内置的指令外,还允许开发人员根据实际情况自定义指令,称为“自定义指令”,它的作用价值在于当开发人员在某些场景下需要对普通DOM元素进行操作的时候。
注册自定义指令
全局注册局部注册
注册全局指令
语法:
Vue.directive( id, [definition] )
第一个参数为自定义指令名称(指令名称不需要加 v- 前缀,默认是自动加上前缀的,使用指令的时候一定要加上前缀),第二个参数可以是对象数据,也可以是一个指令函数。
// 1. 声明全局指令Vue.directive(指令名称,{配置对象成员 })// 配置对象:inserted(m){m:代表使用该指令的html标签dom对象,可以通过m进行原始dom操作实现业务需求}
注意:
私有指令directives关键字 与el、data等都是并列的
简单案例:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="/npm/vue/dist/vue.js"></script></head><body><div id="app"><input type="text" v-focus></div></body><script>Vue.directive("focus", {inserted: function(el) {el.focus()}})var vm = new Vue({el: "#app",data: {}})</script></html>
这个简单案例当中,我们通过注册一个 v-focus 指令,实现了在页面加载完成之后自动让输入框获取到焦点的小功能。
注册局部指令
通过在Vue实例中添加 directives 对象数据注册局部自定义指令。
简单举例:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="/npm/vue/dist/vue.js"></script></head><body><div id="app"><input type="text" v-focus></div></body><script>var vm = new Vue({el: "#app",data: {msg: "这是bind钩子函数"},directives: {focus: {inserted: function(el) {el.focus()}}}})</script></html>
钩子函数
一个指令定义对象可以提供如下几个钩子函数 (均为可选):
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。update:所在组件的 VNode更新时调用。componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。unbind:只调用一次,指令与元素解绑时调用。
<div id="app"><input type="text" v-test></div><script src="vue.js"></script><script>// 注册全局自定义指令Vue.directive('test', {// 第一个钩子函数 bind 指令第一次绑定到元素上bind: function(el, binding) {console.log('bind') // bind},// 第二个钩子函数 inserted 指令所在的元素插入到父节点inserted: function(el, binding) {console.log('inserted') // inserted},// 第三个钩子函数 update 数据发生变化 update: function(el, binding) {console.log('update')},// 第四个钩子函数 componentUpdated 更新完毕componentUpdated: function(el, binding) {console.log('componentUpdated')},// 第五个钩子函数 unbind 解绑unbind: function(el, binding) {console.log('unbind')}})new Vue({el: '#app'})</script>
参数
el:指令所绑定的元素,可以用来直接操作 DOMbinding:
一个对象,包含以下属性:name: 指令名,不包括 v- 前缀value: 指令的绑定值,例如:v-my-directive=“1 + 1” 中,绑定值为 2oldValue: 指令绑定的前一个值,仅在 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 }
简单举例:
<div id="app"><div class="txt" v-test:aaa.trim="100+2"></div></div><script src="vue.js"></script><script>Vue.directive('test', {inserted: function(el, binding) {el.innerText = binding.valueconsole.log(el) // 绑定的元素: <div class="txt"></div>console.log(binding.name) // 指令名字: testconsole.log(binding.value) // 值: 102console.log(binding.expression) // 表达式: 100+2console.log(binding.arg)// 指令参数: aaaconsole.log(binding.modifiers) // 指令修饰符: {trim: true}}})new Vue({el: '#app'})</script>
vnode:Vue 编译生成的虚拟节点oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用
注意
除了 el 之外,其它参数都应该是只读的,切勿进行修改。建议在给指令的命名时采用小驼峰式的命名方式,比如changeBackgroundColor,在使用的时候采用烤串式写法 v-change-background-color
简单举例:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="/npm/vue/dist/vue.js"></script></head><body><div id="app"><input type="text" v-demo:bgcolor="bgColor" v-demo:fsize="fSize"></div><script>Vue.directive("demo", {inserted(el, binding) {//设置背景颜色if (binding.arg == "bgcolor") {el.style.background = binding.value}//设置字体大小if (binding.arg == "fsize") {el.style.fontSize = binding.value}}})new Vue({el: '#app',data: {bgColor: 'blue',fSize: '18px'}})</script></body></html>
生命周期
首先对Vue生命周期官方给出的图进行详细解释:
什么是生命周期?
简而言之:从生到死的过程,从Vue实例创建-运行-销毁的过程
Vue实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、销毁等一系列过程
生命周期方法?
Vue从生到死的过程中伴随着各种各样的事件,这些事件会自动触发一些方法.这些方法我们统称为生命周期方法
生命周期钩子 = 生命周期函数 = 生命周期事件
beforeCreate : 创建实例之前创建的钩子created : 实例创建完成后执行的钩子beforeMounted : 将编译完成的HTML挂载到对应虚拟DOM时触发的钩子,此时页面没有内容mounted : 将编译好的HTML挂载到页面完成后执行的事件钩子beforeUpdata :DOM更新之前的钩子upDated : DOM更新之后的钩子beforeDestroy : 实例销毁之前执行的钩子destroyed : 实例销毁完成执行的钩子
创建期间生命周期方法beforeCreate:created:beforeMountmounted运行期间生命周期方法beforeUpdateupdated销毁期间的生命周期方法beforeDestroydestroyed
beforeCreate
beforeCreate是发生在实例初始化之后,创建实例之前的钩子事件。
在这个过程中会创建一个Vue实例,此时实例上只有一些生命周期函数和默认的事件,此时data和methods上的方法和数据均不能访问:
var vm = new Vue({el: '#app',data() {return {test: 'hello vue'}},beforeCreate() {console.log('beforeCreate');console.log(this.$data);console.log(this.$el);console.log(this);}})
打印结果:
created
这是实例创建完成后的钩子,此时我们可以读取data的值,并可以对其进行操作,把方法、计算属性也都挂载到了实例。但是依旧不能访问el,不能获取到DOM元素。
在这个钩子函数中,我们可以进行数据请求,并把请求到的数据储存在data中。但是请求的数据不宜过多。
var vm = new Vue({el: '#app',data() {return {test: 'hello vue'}},created() {console.log('created');console.log(this.$data);console.log(this.$el);console.log(this);}})
打印结果:
beforeMount
在这个钩子中,首先会判断el的挂载方式,挂载方式有两种:el:’#app’ 和 vm.$mount(’#app’),然后判断是否有指定的template选项,如果有就将template编译到render函数中,没有则将el外部的HTML作为template 编译。
这个过程将template进行渲染保存到内存当中,但是还未挂载在页面上。
var vm = new Vue({// el: '#app',data() {return {test: 'hello vue'}},beforeMount() {console.log('beforeMount');console.log(this.$data);console.log(this.$el);console.log(this);}})vm.$mount('#app')
打印结果:
mounted
在这个钩子中,会将实例挂载到DOM上,我们可以操作页面上的DOM,一般会在此钩子函数中做一些数据请求获取数据,进行数据初始化。 mounted在整个实例中只执行一次。
var vm = new Vue({// el: '#app',data() {return {test: 'hello vue'}},mounted() {console.log('mounted');console.log(this.$data);console.log(this.$el);}})vm.$mount('#app')
打印结果:
beforeUpdate
在此钩子中,data中的数据已经进行了更新,但是页面数据并没有进行更新
var vm = new Vue({// el: '#app',data() {return {test: 'hello vue'}},beforeUpdate() {console.log('beforeUpdata');console.log(this.test);debugger}})vm.$mount('#app')vm.test = 'hello javascript'
打印结果:
updated
将data中的最新数据渲染出DOM,并将最新的DOM挂载页面,此时data数据与页面数据一致:
var vm = new Vue({// el: '#app',data() {return {test: 'hello vue'}},updated() {console.log('updated');console.log(this.test);}})vm.$mount('#app')vm.test = 'hello javascript'
打印结果:
beforeDestroy
实例销毁之前调用,此时组件的data、计算属性、过滤器等都还处于可用的状态,销毁还并未执行。
destroyed
组件已经完全销毁,组件中的数据、方法、计算属性、过滤器等都已经不可用。
我们可以进行手动的销毁组件:vm.$destory()
代码详解:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Vue生命周期方法</title><!--引入vue框架--><script src="js/vue.js"></script></head><body><div id="app"><p>{{msg}}</p></div><script>let vm = new Vue({el:'#app',data:{msg:"IT程序员的日常"},methods:{say:function () {console.log("IT程序员的日常");}},beforeCreate:function () {/*执行beforeCreate的时候,表示Vue刚刚出生,还没有任何内容,data/methods都没有初始化*///console.log(this.msg);//this.say();//console.log(this.say);},created:function () {/*执行created的时候,表示Vue实例已经初始化好了部分内容,data/methods* 想在Vue实例中最早访问到data/methods,只有在这个方法才能访问*///console.log(this.msg);//this.say();// console.log(this.say);},beforeMount:function () {/*执行beforeMount,表示已经根据数据编译好了模板,但是还没有渲染到界面上*/// console.log(document.querySelector("p").innerText);// console.log(document.querySelector("p").innerHTML);},mounted:function () {/*执行mounted,表示已经根据数据编译好了模板,已经将模板有渲染到界面上,此时可以对界面进行其他操作了*/console.log(document.querySelector("p").innerText);console.log(document.querySelector("p").innerHTML);},beforeUpdate:function(){/*主要data中的数据发生了变化就会执行* 执行beforeUpdate时候,data的数据已经是最新的了,但是没有更新界面上的数据** */// console.log(this.msg);// console.log(document.querySelector("p").innerText);// console.log(document.querySelector("p").innerHTML);},updated:function () {/*主要data中的数据发生了变化就会执行* 执行updated时候,data的数据已经是最新的了,界面上的数据也已经更新** */console.log(this.msg);console.log(document.querySelector("p").innerText);console.log(document.querySelector("p").innerHTML);},beforeDestroy:function(){/*执行beforeDestroy的时候,表示Vue实例即将销毁,但是还未销毁,实例中的数据等都可以使用* 最后能使用Vue实例的地址* */},destroyed:function () {/** 执行destroyed的时候,表示vue实例完全销毁,实例中的任何内容都不能被使用了* */}})</script></body></html>