beforeMount -> 마운트됨" 프로세스 이해."/> beforeMount -> 마운트됨" 프로세스 이해.">

>웹 프론트엔드 >JS 튜토리얼 >Vue2.0 라이프사이클을 이해하는 하나의 기사

Vue2.0 라이프사이클을 이해하는 하나의 기사

青灯夜游
青灯夜游앞으로
2020-07-09 14:52:192014검색

Vue2.0 라이프사이클을 이해하는 하나의 기사

인터넷에는 vue 수명주기에 대한 많은 기사가 있습니다. 내 기사의 출처는 실제로 공식 웹사이트에 설명된 문장에 대한 나의 생각과 이해입니다. "el은 새로 생성된 vm.$el로 대체됩니다." , 따라서 Vue 수명 주기에서 "생성 -> 마운트 전 -> 마운트" 프로세스를 이해하면 기사의 더 많은 내용이 포함될 수 있습니다.

beforeCreate --> Created

이 단계에서는 이벤트가 초기화되고 데이터 관찰이 수행됩니다.

created

vue 인스턴스는 생성된 후 호출됩니다. 이때 데이터 관찰(데이터 관찰자), 속성 및 메소드의 작동, 감시/이벤트 이벤트 콜백 구성이 완료되었습니다.

메서드에서 메서드를 호출하고, 데이터의 데이터에 액세스 및 수정하고, 반응형 변경을 트리거하여 DOM 렌더링을 업데이트하고, watch에서 해당 메서드를 트리거하고, 재계산을 위해 관련 속성을 계산할 수 있습니다.

일반적으로 생성 시 인스턴스 데이터를 초기화하기 위해 ajax 요청이 이루어집니다.

이때 vm.$el은 보이지 않습니다.

created --> beforeMount

이 과정에서

먼저 인스턴스에 el 옵션이 있는지 확인하고 그렇지 않은 경우 계속해서 컴파일합니다. , vm.$mount(el) 가 호출될 때까지 계속되지 않습니다(el은 마운트된 DOM 노드입니다). b. 다음으로 인스턴스에 템플릿이 있는지 확인하고, 그렇다면 다음과 같이 컴파일합니다.

 c. 템플릿이 없으면 DOM 요소(즉, el 및 해당 내부 요소에 해당하는 DOM 요소)를 컴파일용 템플릿으로 추출합니다. *참고: el에 해당하는 DOM 요소는 body/html 요소일 수 없습니다. 나중에 vue 인스턴스가 마운트될 때 el에 해당하는 DOM 요소와 그 내부 요소가 템플릿에 의해 렌더링된 새 DOM으로 대체되기 때문입니다.

 

d

. 인스턴스 객체에 rander 함수가 있으면 이를 통해 직접 렌더링 작업이 수행됩니다.

우선순위: rander 함수 > 템플릿 > external html

이 시점에서 rander 함수가 처음으로 호출됩니다.

이 과정에서 $el은 인스턴스의 el 옵션에 해당하는 DOM 요소로 초기화되므로 그래서 beforeMount 중에 vm.$el을 사용하여 마운트된 DOM 요소의 html을 가져옵니다.

beforeMount

beforeMount가 호출되면 이때 $el이 보입니다.

beforeMount --> 마운트

이 과정에서

el은 새로 생성된 vm.$el로 대체

되고 인스턴스가 마운트됩니다. 즉, 인스턴스의 el 옵션은 템플릿 렌더링으로 생성된 DOM 요소로 대체되고, 페이지의 마운트 지점은 렌더링된 vue 인스턴스 코드 세그먼트로 대체됩니다.

Mounted

이때 DOM에 인스턴스가 마운트되었으며, DOM API를 통해 인스턴스에 있는 DOM 노드를 얻을 수 있습니다. 콘솔에서 vm.$el을 인쇄하고 이전 마운트 지점과 콘텐츠가 새 DOM으로 대체되었는지 확인하세요.

밤을 통해 이 두 가지 과정을 살펴보겠습니다.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/vue/2.5.13/vue.min.js"></script>
</head>
<body>
<div id="app">
    <a id=&#39;ela&#39; href="">{{message}}</a>
</div>
</body>
<script>
    var app = new Vue({
        el: '#app',
        data: function () {
            return {
                message: 'hello'
            };
        },
        template: '<p id="elp">{{message}}</p>',
        beforeMount: function () {
            console.group('beforeMount 挂载前状态===============》');
            let state = {
                'el': this.$el,
                'data': this.$data,
                'message': this.message
            }
            let a = document.getElementById('ela');
            let p = document.getElementById('elp');
            console.log(this.$el);
            console.log(state);
            console.log(a);    // <a id=&#39;ela&#39; href="">{{message}}</a>
            console.log(p);     // null
        },
        mounted: function () {
            console.group('mounted 挂载结束状态===============》');
            let state = {
                'el': this.$el,
                'data': this.$data,
                'message': this.message
            }
            let a = document.getElementById('ela');
            let p = document.getElementById('elp');
            console.log(this.$el);
            console.log(state);
            console.log(a);    // null
            console.log(p);     // <p id="elp">father</p>
        }
</script>
</html>

template/rander 옵션을 사용하여 콘솔에서 명확하게 볼 수 있습니다. 마운트가 완료된 후 el이 새로 생성된 vm.$el로 대체됩니다.

마운트하기 전에는 초기 el과 가상 DOM의 형태로 존재합니다. 이때 템플릿의 내용은 템플릿으로 사용되며 인쇄된 p 태그는 null입니다. , 템플릿에 의해 렌더링된 새 DOM은 원본 el을 대체합니다. 원본 el에 해당하는 DOM은 존재하지 않으며 인쇄된 a 태그는 null입니다.

beforeUpdate 및 업데이트

데이터 개체의 데이터가 업데이트되면 beforeUpdate 후크가 트리거됩니다. 이때 뷰 레이어는 업데이트되지 않았습니다. beforeUpdate에 대해 주의할 사항이 몇 가지 있습니다.

a. beforeUpdate를 트리거하려면 업데이트된 데이터를 템플릿에서 직접 또는 간접적으로 사용해야 합니다.

b. 촉발되다! 즉, 생성 및 beforeMount 중에 데이터를 변경하면 업데이트 프로세스가 트리거되지 않습니다.

 c. beforeUpdate에서 데이터 값이 다시 수정되면 beforeUpdate 후크가 다시 트리거되고 업데이트 프로세스가 두 번 수행됩니다.

업데이트되면서 뷰 레이어가 업데이트되었습니다. (위 코드에 두 개의 후크 추가)

mounted: function () {
    this.message = 'first';
//     this.show = false;        // 由于模板中没有用到show,所以show的改变不会触发beforeUpdate
},
beforeUpdate: function () {
    console.group('beforeUpdate 更新前状态===============》');
    let elp = document.getElementById('elp').innerHTML;
    console.log('message:' + this.message);
    console.log('DOM:' + elp);
},
updated: function () {
    console.group('updated 更新完成状态===============》');
    let elp = document.getElementById('elp').innerHTML;
    console.log('message:' + this.message);
    console.log('DOM:' + elp);
}

这里需要注意一点:view层我们需要通过innerHTML获取对应元素节点中的内容,而不能直接获取元素节点。直接获取元素节点,在控制台打印出来的view层中的数据都是更新之后的状态,不能打印出实时的正确的值,这应该和Chrome控制台的输出有关。

针对第三条,我们看一下下面的代码演示:

mounted: function () {
    this.message = 'first';
},
beforeUpdate: function () {
    console.group('beforeUpdate 更新前状态===============》');
    let elp = document.getElementById('elp').innerHTML;
    console.log('message:' + this.message);
    console.log('DOM:' + elp);
    this.message = 'second';    // 此时在beforeUpdate中再次修改了message的值
},
updated: function () {
    console.group('updated 更新完成状态===============》');
    let elp = document.getElementById('elp').innerHTML;
    console.log('message:' + this.message);
    console.log('DOM:' + elp);
}

 

这里我们可以清楚的看到进行了两次更新流程,但是对打印的结果有些疑问:第一次将message的值改为first,并且以first来渲染更新DOM,那么第一次调用updated时,message和DOM中的值都应该是first,而此时打印出来的时second。我理解的是,在第一次执行updated时,DOM就已经完成了第二次渲染更新,具体的过程还需要通过之后对源码的学习去理解。这里各位有不同的理解或者更详细的解释,可以在评论区留言,共同学习。

在这里,我们可以在beforeUpdate中加定时器去修改message的值,就可以等待第一次数据改变,DOM更新渲染完成后,进行第二次数据改变。

beforeUpdate: function () {
    console.group('beforeUpdate 更新前状态===============》');
    let elp = document.getElementById('elp').innerHTML;
    console.log('message:' + this.message);
    console.log('DOM:' + elp);
    var that = this;
    setTimeout(function(){
      that.message = 'second';
    });
//    this.message = 'second';    // 此时在beforeUpdate中再次修改了message的值
},

这里可以清楚看到两次数据改变时,数据和view层的更新状态。

beforeDestroy 和 destroyed

beforeDestroy:实例在销毁之前调用,此时实例仍然可用。

beforeDestroy -> destroyed: Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

destroyed:vue实例销毁后调用。

结尾:关于vue生命周期就总结完毕,有错误的地方烦请指出,会及时修改!

위 내용은 Vue2.0 라이프사이클을 이해하는 하나의 기사의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 cnblogs.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제