vue生命周期及自定义指令

来源:互联网 发布:apache php 网站发布 编辑:程序博客网 时间:2024/04/30 13:36

一、生命周期

1.生命周期图示:

2.生命周期钩子函数

    1. beforeCreate

      在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。

  • 2.created

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

    数据观测指的是:Vue中的data选项。
    注意:在上图中,调用完created()方法后,会判断是否有“el”选项,若没有就调用vm.$mount(el)方法。如下:

    <code>     var app = new Vue({        // el: '#app',        template: '<h1>Hello Vue - {{value}}</h1>',        data: {            value: 1        }    }    document.onclick = function() {        app.$mount('#app');        console.log(app);    }</code>
  • 3.beforeMount

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

  • 4.mounted

    el 被新创建的 vm.elrootmountedvm.el 也在文档内。
    注意 mounted 不会承诺所有的子组件也都一起被挂载。

    “文档”指的是HTML。

  • 5.beforeUpdate

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

  • 6.updated
    由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
  • 7.beforeDestroy
    实例销毁之前调用。在这一步,实例仍然完全可用。
  • 8.destroyed

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

    注意:vue实例销毁共有两种方式:

    • 关闭浏览器,自动会销毁;
    • 调用vm.$destroy()的实例方法,完全销毁一个实例。

3.钩子函数应用

  • 1.created
    使用场景:当页面一打开,就需要向后端请求到数据并渲染到页面中。
    要满足上面所说的需求,那就需要在created()钩子函数内发送请求。

    <code>    <div id="app">        <ul>            <li v-for="data in news">{{data.title}}</li>        </ul>    </div>    <script src="js/fetch-jsonp.js" charset="utf-8"></script>    <script type="text/javascript">        var app = new Vue({             el: '#app',            data: {                url: 'https://3g.163.com/touch/jsonp/sy/recommend/0-10.html?hasad=1&offset=0&size=10',                news: []            },            created() {                //console.log(this.news);                // this.getNews(this.url);                //方法二:                fetchJsonp(this.url, {                    jsonpCallback: 'callback',                    jsonpCallbackFunction: 'miaov123'                })                    .then( response => {                        console.log(response);                        return response.json();                    } )                    .then( data => {                        console.log(data);                        this.news = data.news;                    } )            },            //方法一:            methods: {                // 通过JSONP发送请求,拿取数据                getNews(url) {                    var script = document.createElement('script');                    script.src = url;                    document.body.appendChild(script);                    window.miaov = (data) => {                        this.news = data.news;                    }                }            }        });    </script></code>

    说明:

    • fetch-jsonp.js是一个封装好的JSONP的框架,可以直接拿来用;
    • 由于”script.src=url”,这一步是一个异步非阻塞过程,在该步没有执行完成,就会执行后面的代码声明一个window上的函数。这样等到该过程执行完后端会返回一个“miaov(data)”函数调用的表达式时,js就能正确解析它;否则,若是同步阻塞,等到该过程完成得到“miaov(data)”函数调用,此时,js中“miaov”函数还没声明,那么就无法正确解析而会报错;
    • link/script/img等需要加载资源的标签,都是异步,通知机制是onload事件;
    • script标签在html中,引入其他文件时,执行是同步阻塞,在script标签中写入js代码,执行时是异步非阻塞。
    • window.miaov=(function(){…}),此代码是将一个名为”miaov”的函数挂在window对象上,但是该函数体里的代码的作用域还是在当下环境内,并没有变成全局。

  • 2.实现实时发送请求

    <code>     <div id="app">        <input type="text" v-model="keyword" />        <ul>            <li v-for="data in list">{{data[0]}}</li>        </ul>    </div>    <script type="text/javascript">        var app = new Vue({            el: '#app',            data: {                keyword: '',                list: []            },            watch: {                keyword() {                    //console.log(this.keyword);                    // 发送请求                    fetchJsonp('https://suggest.taobao.com/sug?code=utf-8&q=' + this.keyword, {                        jsonpCallback: 'callback',                        jsonpCallbackFunction:                                  'miaov123'                    }).then( response => {                        <!--得到请求对象,并把该对象解析成JSON对象数据-->                        // 解析数据的过程也是异步操作                        return response.json();                        //json方法的返回值也是promise对象                    } ).then( data => {                        this.list = data.result;                    } );                }            }           });</code>

    注意:

    • 1.用户在input中输入“keyword”时,“keyword”在不断变化,那么js就需要根据“keyword”的变化,发送“keyword”不同的请求给服务端。那么此时需要监控“keyword”来作出相应的动作(请求)。
    • 2.在vue中本来有两种方式去实现根据当前值的变化修改其他值,即watch和computed。但是computed属性不支持异步的写法,如下:

      <code>    computed: {        async a() {            var response = await fetchJsonp('https://suggest.taobao.com/sug?code=utf-8&q=' + this.keyword, {                jsonpCallback: 'callback',                jsonpCallbackFunction: 'miaov123'            })            var data = await response.json();//await代替then方法            return data;        }    }</code>

      即“async a”这种写法不支持。

二、自定义指令

有的情况下,你仍然需要对纯 DOM 元素进行底层操作,这时候就会用到自定义指令。

  • 1.注册自定义指令

    • 注册全局自定义指令
      Vue.directive(指令名称,{指令配置});
    • 注自定义册局部指令

      <code>    directives: {      focus: {        // 指令的定义---        inserted: function (el) {}      }    }</code>
      • 指令名称不需要使用v-前缀,但是在使用的时候需要添加
  • 2.指令中也提供一些配置,这些配置是一些钩子函数(生命周期函数是一个意思)

    • bind

    只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。

  • inserted
    被绑定元素插入父节点时调用 (父节点存在即可调用,不必存在于 document 中)。

该元素添加到页面,会调用此钩子函数
  • update
    所在组件的 VNode 更新时调用,但是可能发生在其孩子的 VNode 更新之前。指令的值可能发生了改变也可能没有。

指令中使用的数据发生变化,会调用此钩子函数。

  • componetnUpdated
    所在组件的 VNode 及其孩子的 VNode 全部更新时调用。
  • unbind
    只调用一次,指令与元素解绑时调用。
  • 3.钩子函数还可以接收一些参数,包括:

    • el

      指令所绑定的元素,可以用来直接操作 DOM 。

    • binding
      写法:v-name:args.modifiers=”value”;
      一个对象,包含以下属性:
        (1)name:指令名,不包括 v- 前缀。
        (2)value:指令的绑定值,例如:v-my-directive=”1 + 1”, value 的值是 2。
        (3)oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
        (4)expression:绑定值的字符串形式。例如 v-my-directive=”1 + 1” ,expression 的值是 “1 + 1”。
        (5)arg:传给指令的参数。例如 v-my-directive:foo,arg 的值是 “foo”。
        (6)modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar, 修饰符对象 modifiers 的值是 { foo: true, bar: true }。
    • vnode
      Vue 编译生成的虚拟节点。
    • oldVnode

      上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。