Vue全局API(上)

一、全局API

何为全局API? 通俗的说就是在构造器之外,Vue提供的一些API函数,可以使我们定义新的功能。

自定义指令 Vue.directive

通过例子来看:定义一个指令,让num的颜色变成红色。

    <div id="app">
        <div v-cui="color">{{ num }}</div>
        <button @click = "add">增加</button>
    </div>

传入一个函数

    Vue.directive('cui', function(el, binding, vnode){
            //console.log(el)//绑定了自定义指令‘cui’的节点
            //console.log(binding)//是一个对象,包含指令的很多信息。
            //console.log(vnode)//编译生成的虚拟节点

            el.style.color = binding.value;
    })

    var app = new Vue({
        el: "#app",
         data: {
             num: 10,
             color: 'red'
         },
         methods: {
             add(){
                 this.num++
             }
         }
    })

传入一个对象,分别是五个生命周期钩子函数

 <div id="app" v-cloak>
        <div v-cui="color">{{ num }}</div>
        <button @click = "add">增加</button>
       
    </div>
    <button onclick = 'unbind()'>解绑</button>
//五个生命周期钩子函数,我们可以在不同周期进行相应的操作
Vue.directive('cui', {
        bind: function () {
            console.log('第一次被绑定')
        },
        inserted: function(){
            console.log('被绑定元素插入到父节点')
        },
        update: function(){
            console.log('组件更新')
        },
        componentUpdated: function(){
            console.log('组件更新完成')
        },
        unbind: function(){
            console.log('组件解绑')
        }
    })
    //解绑函数需要定义在构造器之外
    function unbind(){
        app.$destroy()
    }

    var app = new Vue({
        el: "#app",
         data: {
             num: 10,
             color: 'red'
         },
         methods: {
             add(){
                 this.num++
                //  this.color = "green"
             }
         }
    })
  • bind:只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个执行一次的初始化操作。
  • inserted:被绑定元素插入父节点时调用。
  • update:被绑定于元素所在的模板更新时调用,而无论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新。
  • componentUpdated:被绑定元素所在模板完成一次更新周期时调用。
  • unbind:只调用一次,指令与元素解绑时调用。

二、extend扩张实例构造器

<div id="app">
        <nav-bar id="nav"></nav-bar>
</div>
    //扩张构造器
    var NavBar = Vue.extend({
        template: "<div><ul><a :href='url'><li>{{msg1}}</li></a><li>{{msg2}}</li></ul></div>",
        data(){
            return {
                msg1: '首页',
                url: 'https://baidu.com',
                msg2: '关于我'
            }
        }
    })

    //创建自定义构造器实例,并挂载
    new NavBar().$mount('#nav')//这里可以是id,类名,标签名

效果:

三、Vue.set

Vue.set的作用是在构造器外部操作构造器内部的数据、属性或方法。比如,在Vue构造器内部定义一个数num为10,在外部定义一个方法改变num的值。

<div>{{ num }}</div>
    //引用构造器外部数据
    var datas = {
        num: 10,
        stars: ['柳岩', '刘亦菲', '刘诗诗']
    }

    //三种方式改变num的值
    function add() {
        //1、 直接操作外部数据
        datas.num ++ 

        //2、 用Vue对象的方式添加
        app.num ++ 

        //3、 用Vue.set的方式改变
        Vue.set(datas, 'num', 20)
    }
    var app = new Vue({
        el: "#app",
        data: datas,
        methods: {
            add(){
                console.log(this.stars)
                this.stars[1] = '高圆圆'
            }
        }
    })

这时候你可能会产生疑问,为什么要用这么复杂的方式去改变num的值,当然了,单纯的去改变数的值,自然是没必要这么做的,不妨看下面的例子,我们通过问题来引入:

假设我们通过一个事件去改变数组中的某个元素,你会发现,值改变了,但是并没有更新视图。

<div id="#app">
    <ul>
        <li v-for = "star in stars">{{ star }}</li>
    </ul>
    <button @click = 'add()'>add</button>
</div>

通过点击事件,将‘刘亦菲’改成‘高圆圆’

//引用构造器外部数据
    var app = new Vue({
        el: "#app",
        data: {
            stars: ['柳岩', '刘亦菲', '刘诗诗']
        },
        methods: {
            add(){
                console.log(this.stars)
                this.stars[1] = '高圆圆'
                
            }
        }
    })

结果是数组的值变了,但是并没有更新视图。

这种问题是由于Javascript的限制,Vue不能自动检测以下方式变动的数组。

  • 当你利用索引直接设置一个项时,vue不会为我们自动更新。

但是,当我们在一个事件中同时改变一个数的值和数组中的某个元素,那么此时数组中的值也会相应的改变。原因是虚拟DOM,当我们通过事件改变num的值时,会改变虚拟DOM,触发视图的更新。如下:

    data: {
        num: 10,
        stars: ['柳岩', '刘亦菲', '刘诗诗']
    },
    methods: {
        add(){
            this.num ++ 
            this.stars[1] = '高圆圆'
            console.log(this.stars)
            //this.stars.push('赵丽颖')
        }
    }

但是我们在实际项目开发中,只需要改变数组中的某个元素,那么就需要Vue.set()了。

var datas = {
    stars: ['柳岩', '刘亦菲', '刘诗诗']
}

function add() {
        //改变数组中的元素
        Vue.set(app.stars, 1, '高圆圆')
}

var app = new Vue({
    el: "#app",
    data: datas
})

也可以在构造器实例中通过Vue.set()去改变,效果也是一样的。

<ul>
   <li v-for = "star in stars">{{ star }}</li>
</ul>
<button @click = 'add()'>add</button>
var app = new Vue({
    el: "#app",
    // data: datas,
    data: {
        stars: ['柳岩', '刘亦菲', '刘诗诗']
    },
    methods: {
    add(){
        // this.stars[1] = '高圆圆'
        // console.log(this.stars)
        Vue.set(app.stars, 1, "高圆圆")
        }
    }
})

四、生命周期

何为生命周期?对一个生物来说,生命周期便是从出生到死亡的过程,那中间一定还有很多的时间点,比如,少年、青年、中年、老年等,不同阶段可以做不同的事情。Vue中的生命周期也是如此,它包括从Vue实例的创建到销毁,以及中间经历的不同时间点。

Vue所有的生命周期钩子自动绑定在this上下文到实例中,因此可以访问数据,并对属性和方法进行运算。同时意味着不能使用箭头函数来定义一个生命周期方法。因为箭头函数绑定了父上下文,因此this与你期待的Vue实例不同。

还是通过代码来看吧:

<div id="app">
    <div>{{ num }}</div>
    <button @click = "add">add</button>
    <button onclick="app.$destroy()">销毁</button>
</div>
var app = new Vue({
    el: "#app",
    data: {
        num : 10
    },
    methods: {
        add(){
            this.num ++
        }
    },
    // 实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用
    beforeCreate:function(){
        console.log('1-beforeCreate 实例初始化之后');
    },
    created:function(){
        console.log('2-created 创建完成');
    },
    beforeMount:function(){
        console.log('3-beforeMount 挂载之前');
    },
    mounted:function(){
        console.log('4-mounted 被创建');
    },
    beforeUpdate:function(){
        console.log('5-beforeUpdate 数据更新前');
    },
    updated:function(){
        console.log('6-updated 被更新后');
    },
    activated:function(){
        console.log('7-activated');
    },
    deactivated:function(){
        console.log('8-deactivated');
    },
    beforeDestroy:function(){
        console.log('9-beforeDestroy 销毁之前');
    },
    destroyed:function(){
        console.log('10-destroyed 销毁之后')
    }

})

初次打开页面

点击按钮,更新组件

点击销毁按钮

Vue组件的生命周期这篇文章对生命周期钩子的解释还是比较通俗的。

1、beforeCreate

在实例初始化之后,数据观测和event/watcher时间配置之前被调用。

2、created

实例已经创建完成之后被调用。在这一步,实例已经完成以下的配置:数据观测,属性和方法的运算,watch/event事件回调。然而,挂载阶段还没开始,$el属性目前不可见。

3、beforeMount

在挂载开始之前被调用:相关的render函数首次被调用。

该钩子在服务器端渲染期间不被调用。

4、mounted

el被新创建的vm.$el替换,并挂在到实例上去之后调用该钩子函数。如果root实例挂载了一个文档内元素,当mounted被调用时vm.$el也在文档内。

该钩子在服务端渲染期间不被调用。

5、beforeUpdate

数据更新时调用,发生在虚拟DOM重新渲染和打补丁之前。

你可以在这个钩子中进一步第更改状态,这不会触发附加的重渲染过程。

该钩子在服务端渲染期间不被调用。

6、updated

由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子。

当这个钩子被调用时,组件DOM已经更新,所以你现在可以执行依赖于DOM的操作。然而在大多数情况下,你应该避免在此期间更改状态,因为这可能会导致更新无限循环。

该钩子在服务端渲染期间不被调用。

7、activated

keep-alive组件激活时调用。

该钩子在服务器端渲染期间不被调用。

8、deactivated

keep-alive组件停用时调用。

该钩子在服务端渲染期间不被调用。

9、beforeDestroy 【类似于React生命周期的componentWillUnmount】

实例销毁之间调用。在这一步,实例仍然完全可用。

该钩子在服务端渲染期间不被调用。

10、destroyed

Vue实例销毁后调用。调用后,Vue实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

该钩子在服务端渲染不会被调用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,165评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,720评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,849评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,245评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,596评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,747评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,977评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,708评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,448评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,657评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,141评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,493评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,153评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,890评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,799评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,685评论 2 272

推荐阅读更多精彩内容

  • 这篇笔记主要包含 Vue 2 不同于 Vue 1 或者特有的内容,还有我对于 Vue 1.0 印象不深的内容。关于...
    云之外阅读 4,992评论 0 29
  • 1.安装 可以简单地在页面引入Vue.js作为独立版本,Vue即被注册为全局变量,可以在页面使用了。 如果希望搭建...
    Awey阅读 10,916评论 4 129
  • Vue 实例 属性和方法 每个 Vue 实例都会代理其 data 对象里所有的属性:var data = { a:...
    云之外阅读 2,127评论 0 6
  • 柏奚 ■闭路褴褛 灵翮十一年,南羽骤发毒瘴,一夜死伤百里。生还者称夜见青色硕大莲花,蓬勃开放。 春末多雨,帝王车驾...
    閉路藍縷阅读 1,822评论 0 1
  • MySQL AB提供了几种类型的程序: MYSQL服务器和服务器启动脚本:1: mysqld是MySQL服务器2:...
    笑Skr人啊阅读 460评论 0 0