Python全栈(六)项目前导之9.Vue自定义组件和生命周期函数

一、给组件添加属性和单一根元素

1.自定义组件添加属性

原始的html元素一般都有自己的一些属性,我们自己创建的组件,也可以通过props属性来添加自己的属性。这样在使用创建的组件的时候就可以传递不同的参数了。
测试:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue模板语法</title>
</head>
<body>
    <div id='app'>
        <book-list v-bind:books="books"></book-list>
    </div>
</body>
</html>


<script src="https://cdn.jsdelivr.net/npm/vue"></script>


<script>
    Vue.component('book-list',{
        // 给组件添加属性
        props:['books'],
        //  多行代码时用``包含(不是单引号)
        template:`
            <table>
                <tr>
                    <th>序号</th>
                    <th>标题</th>
                </tr>
                <tr v-for="(book,index) in books">
                    <td>{{index + 1}}</td>
                    <td>{{book.title}}</td>
                </tr>
            </table>
        `,
    })
    new Vue({
        el:'#app',
        data:{
            books:[
                {
                    'title':'Python',
                    'id':1
                },
                {
                    'title':'Java',
                    'id':2
                },
                {
                    'title':'PHP',
                    'id':3
                },
            ],
        },
    })
</script>

显示:
vue add attribute to component
在创建的组件中,不能直接使用Vue对象中的数据,需要将数据绑定到新建组建的prop属性中,并且在使用新创建的组件需要属性绑定到相应的数据才能正常引用数据。

2.单一根元素

自定义的组件中可以出现多个html元素,但是根元素只能有一个,其余的元素必须包含在这个根元素中。
比如以下是一个组件中模板的代码:

template:`
	<h3>{{ title }}</h3>
	<div v-html="content"></div>
`

会报错,可以改成:

template:`
	<div>
		<h3>{{ title }}</h3>
		<div v-html="content"></div>
	</div>
`

在新建组建的模板中添加多个标签并进行测试:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue模板语法</title>
</head>
<body>
    <div id='app'>
        <book-list v-bind:books="books"></book-list>
    </div>
</body>
</html>


<script src="https://cdn.jsdelivr.net/npm/vue"></script>


<script>
    Vue.component('book-list',{
        // 给组件添加属性
        props:['books'],
        //  多行代码时用``包含(不是单引号)
        template:`
        <table>
            <tr>
                <th>序号</th>
                <th>标题</th>
            </tr>
            <tr v-for="(book,index) in books">
                <td>{{index + 1}}</td>
                <td>{{book.title}}</td>
            </tr>
        </table>
        <div>返回顶部</div>
        `,
    })
    new Vue({
        el:'#app',
        data:{
            books:[
                {
                    'title':'Python',
                    'id':1
                },
                {
                    'title':'Java',
                    'id':2
                },
                {
                    'title':'PHP',
                    'id':3
                },
            ],
        },
    })
</script>

与之前显示相同,即模板中的根元素有2个时是不能正常显示的,只能有一个根元素。
将它们放入一个根元素后再测试:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue模板语法</title>
</head>
<body>
    <div id='app'>
        <book-list v-bind:books="books"></book-list>
    </div>
</body>
</html>


<script src="https://cdn.jsdelivr.net/npm/vue"></script>


<script>
    Vue.component('book-list',{
        // 给组件添加属性
        props:['books'],
        //  多行代码时用``包含(不是单引号)
        template:`
        <div>
            <table>
            <tr>
                <th>序号</th>
                <th>标题</th>
            </tr>
            <tr v-for="(book,index) in books">
                <td>{{index + 1}}</td>
                <td>{{book.title}}</td>
            </tr>
            </table>
            <div>返回顶部</div>
        </div>        
        `,
    })
    new Vue({
        el:'#app',
        data:{
            books:[
                {
                    'title':'Python',
                    'id':1
                },
                {
                    'title':'Java',
                    'id':2
                },
                {
                    'title':'PHP',
                    'id':3
                },
            ],
        },
    })
</script>

显示:
vue one root element
此时可以正常显示,即要满足单一根元素原则。

二、子组件事件和传递事件到父组件

子组件中添加事件跟之前的方式是一样的,如果发生某个事件后想要通知父组件,可以使用this.$emit函数来实现。
测试如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue模板语法</title>
</head>

<body>
    <div id='app'>
        <book-list v-for="book in books" v-bind:book="book" @check-changed="check"></book-list>
        <div v-for="book in bookcomponent">{{book.title}}</div>
    </div>
</body>

</html>


<script src="https://cdn.jsdelivr.net/npm/vue"></script>


<script>
    Vue.component('book-list', {
        props: ['book'],
        template: `
        <div>
            <span>{{book.title}}</span>
            <input type="checkbox" @click="onCheck">
        </div>        
        `,
        methods:{
            onCheck:function(){
                this.$emit('check-changed',this.book)
            }
        }
    })
    new Vue({
        el: '#app',
        data: {
            books: [{
                    'title': 'Python',
                    'id': 1
                },
                {
                    'title': 'Java',
                    'id': 2
                },
                {
                    'title': 'PHP',
                    'id': 3
                },
            ],
            bookcomponent: []
        },
        methods:{
            check:function(book){
                // indexOf()函数返回元素的下标,大于等于0则表明数组中存在该元素
                var index = this.bookcomponent.indexOf(book)
                if(index >= 0){
                    this.bookcomponent.splice(index,1)
                }
                else{
                   this.bookcomponent.push(book)
                }
            }
        }
    })
</script>

显示:
vue subcomp pass event to supercomp
indexOf()函数返回元素在数组中的下标,如果值大于等于0,则说明该数组中存在该元素。
显然,上面子组件被选择后,会同步显示到父组件中,其中的时间流和数据流的流转原理如下:
vue subcomponent pass event to supercomponent
其中,红色标示①→④表示事件流,即点击复选框触发的事件的流转;
蓝色标识⑤→⑩标识数据流,即父组件从子组件获取数据并即时同步的过程;
子组件触发的事件通过与数据流的交织传递最终到父组件,并达到需要的效果。
注意:
因为html中大小写是不敏感的,所以在定义子组件传给父组件事件名称的时候,尽量避免使用checkChanged这种驼峰命名法,而是使用check-changed这种规则。

扫描二维码关注公众号,回复: 10484427 查看本文章

三、自定义组件v-model

一个组件上的v-model默认会利用value属性和input事件,并且像单选框、复选框等类型的输入控件可能会将value特性用于不同的目的,这时候我们可以在定义组件的时候,通过设置model选项来实现不同的处理方式。
模拟一个计步器,测试如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue模板语法</title>
</head>

<body>
    <div id='app'>
        <stepper v-model:value="stepcount"></stepper>
    </div>
</body>

</html>


<script src="https://cdn.jsdelivr.net/npm/vue"></script>


<script>
    Vue.component('stepper', {
        props: ['count'],
        model:{
            // 触发v-model事件的情况
            event:'count-changed',
            prop:'count'
        },
        template: `
        <div>
            <button @click="sub">-</button>
            <span>{{count}}</span>
            <button @click="add">+</button>
        </div>
        `,
        methods:{
            sub:function(){
                this.$emit('count-changed',this.count - 1) 
            },
            add:function(){
                this.$emit('count-changed',this.count + 1) 
            }
        }
    })
    new Vue({
        el: '#app',
        data: {
            stepcount:0
        },
        methods:{

        }
    })
</script>

显示:
vue custom v-model
说明:
在自定义的组件中,

  • props定义的属性是给组件外部调用组件的时候使用的;
  • model中定义的prop:'count'是告诉后面使用v-model的时候,要修改哪个属性;
  • event:'count-changed'是告诉v-model,后面触发哪个事件的时候要修改属性。
    数据流和时间流传递原理如下:
    vue custom v-model principal
    其中,红色表示事件流,蓝色表示数据流;
    通过数据与事件的相互作用,达到了自定义组件中v-model的目的。

四、Vue插槽

1.插槽的定义和简单使用

我们定义完一个组件后,可能在使用的时候还需要往这个组件中插入新的元素或者文本,这时候就可以使用插槽来实现。
测试如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue模板语法</title>
</head>

<body>
    <div id='app'>
        <navigation-link :url="url">百度一下</navigation-link>
    </div>
</body>

</html>


<script src="https://cdn.jsdelivr.net/npm/vue"></script>


<script>
    Vue.component('navigation-link',{
        props:['url'],
        template:`
        <a v-bind:href="url">
            <slot></slot>
        </a>
        `
    })
    new Vue({
        el: '#app',
        data: {
            url:'https://www.baidu.com'
        },
        methods:{

        }
    })
</script>

显示:
vue slot test
即在新建的组件中插入的内容(百度一下)是通过插入到插槽标签中实现的。
不仅是文本,插槽可以包含任何模板代码,包含HTML语句,例如:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue模板语法</title>
</head>

<body>
    <div id='app'>
        <navigation-link :url="url">
            <span class="fa fa-user">不懂你就</span>
            百度一下
        </navigation-link>
    </div>
</body>

</html>


<script src="https://cdn.jsdelivr.net/npm/vue"></script>


<script>
    Vue.component('navigation-link',{
        props:['url'],
        template:`
        <a v-bind:href="url">
            <slot></slot>
        </a>
        `
    })
    new Vue({
        el: '#app',
        data: {
            url:'https://www.baidu.com'
        },
        methods:{

        }
    })
</script>

显示:
vue slot html test
如果没有包含一个元素,则该组件起始标签和结束标签之间的任何内容都会被抛弃。
即在自定义组件时,如果没有包含slot元素,在HTML中的自定义组件中插入任意的文本或HTML元素都是不会被渲染到网页的,如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue模板语法</title>
</head>

<body>
    <div id='app'>
        <navigation-link :url="url">
            <span class="fa fa-user">不懂你就</span>
            百度一下
        </navigation-link>
    </div>
</body>

</html>


<script src="https://cdn.jsdelivr.net/npm/vue"></script>


<script>
    Vue.component('navigation-link',{
        props:['url'],
        template:`
        <a v-bind:href="url">
        </a>
        `
    })
    new Vue({
        el: '#app',
        data: {
            url:'https://www.baidu.com'
        },
        methods:{

        }
    })
</script>

显示:
vue slot component no slot
显示空白,即没有元素被渲染出来。
如果在模板中的标签中定义了文本,则在HTML正文中的定义出的组件中的文本的优先级更大,会显示出来,如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue模板语法</title>
</head>

<body>
    <div id='app'>
        <navigation-link :url="url">百度一下</navigation-link>
    </div>
</body>

</html>


<script src="https://cdn.jsdelivr.net/npm/vue"></script>


<script>
    Vue.component('navigation-link',{
        props:['url'],
        template:`
        <a v-bind:href="url">
            <slot>小度小度</slot>
        </a>
        `
    })
    new Vue({
        el: '#app',
        data: {
            url:'https://www.baidu.com'
        },
        methods:{

        }
    })
</script>

百度一下的优先级更高,会显示,与之前测试的效果一致。

2.定义多个插槽

我们还可以通过给插槽命名来实现多个插槽,测试如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue模板语法</title>
</head>

<body>
    <div id='app'>
        <navigation-link :url="url">
            <template v-slot:first>第一个插槽</template>
            <template v-slot:second>第二个插槽</template>
            <template v-slot:third>第三个插槽</template>
        </navigation-link>
    </div>
</body>

</html>


<script src="https://cdn.jsdelivr.net/npm/vue"></script>


<script>
    Vue.component('navigation-link',{
        props:['url'],
        template:`
        <a v-bind:href="url">
            <slot name="first"></slot>
            <br>
            <slot name="second"></slot>
            <br>
            <slot name="third"></slot>
        </a>
        `,
        data:function(){
            return {
                name:'Python'
            }
        }
    })
    new Vue({
        el: '#app',
        data: {
            url:'https://www.baidu.com',
            name:'Corley'
        },
        methods:{

        }
    })
</script>

显示:
vue slot name multi test
如果有部分未命名,则为默认插槽,测试如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue模板语法</title>
</head>

<body>
    <div id='app'>
        <navigation-link :url="url">
            <template v-slot:first>第一个插槽</template>
            <template v-slot:second>第二个插槽</template>
            <template>默认插槽</template>
            <template v-slot:third>第三个插槽</template>
        </navigation-link>
    </div>
</body>

</html>


<script src="https://cdn.jsdelivr.net/npm/vue"></script>


<script>
    Vue.component('navigation-link',{
        props:['url'],
        template:`
        <a v-bind:href="url">
            <slot name="first"></slot>
            <br>
            <slot name="second"></slot>
            <br>
            <slot name="third"></slot>
            <br>
            <slot></slot>
        </a>
        `,
        data:function(){
            return {
                name:'Python'
            }
        }
    })
    new Vue({
        el: '#app',
        data: {
            url:'https://www.baidu.com',
            name:'Corley'
        },
        methods:{

        }
    })
</script>

显示:
vue slot partname multi test

3.插槽的作用域

子组件中调用父组件属性测试:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue模板语法</title>
</head>

<body>
    <div id='app'>
        <navigation-link :url="url">{{name}}</navigation-link>
    </div>
</body>

</html>


<script src="https://cdn.jsdelivr.net/npm/vue"></script>


<script>
    Vue.component('navigation-link',{
        props:['url'],
        template:`
        <a v-bind:href="url">
            <slot>小度小度</slot>
        </a>
        `
    })
    new Vue({
        el: '#app',
        data: {
            url:'https://www.baidu.com',
            name:'Corley'
        },
        methods:{

        }
    })
</script>

显示:
vue slot invoke superattribute test
很明显,定义的子组件可以访问到父组件中的属性。
在定义的组件中增加name属性进行测试:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue模板语法</title>
</head>

<body>
    <div id='app'>
        <navigation-link :url="url">{{name}}</navigation-link>
    </div>
</body>

</html>


<script src="https://cdn.jsdelivr.net/npm/vue"></script>


<script>
    Vue.component('navigation-link',{
        props:['url'],
        template:`
        <a v-bind:href="url">
            <slot>小度小度</slot>
        </a>
        `,
        data:function(){
            return {
                name:'Python'
            }
        }
    })
    new Vue({
        el: '#app',
        data: {
            url:'https://www.baidu.com',
            name:'Corley'
        },
        methods:{

        }
    })
</script>

与前者效果相同。
可以看到,自定义的组件的插槽只能访问到父组件中的属性,而不能访问到自己的属性。
在定义组件时绑定测试如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue模板语法</title>
</head>

<body>
    <div id='app'>
        <container>
            <template v-slot:header="headerProps">
                顶部{{headerProps.navs}}
            </template>
            <template  v-slot:footer="footerProps">
                底部{{footerProps.contact}}
            </template>
        </container>
    </div>
</body>

</html>


<script src="https://cdn.jsdelivr.net/npm/vue"></script>


<script>
    Vue.component('container',{
        props:['url'],
        template:`
        <div>
            <div>
                <slot name='header' :navs="navs"></slot>
            </div>
            <div>
                <slot name='footer' :contact="contact"></slot>
            </div>
        </div>
        `,
        data:function(){
            return {
                navs:['网页','咨询','视频'],
                contact:'xxx'
            }
        }
    })
    new Vue({
        el: '#app',
    })
</script>

显示:
vue slot scope test
可以总结:
默认情况下,slot可以直接使用父组件中的数据;
要想slot使用自定义组件中的数据,需要slot标签进行绑定(v-bind)。

五、生命周期函数

1.Vue生命周期定义

生命周期函数代表的是Vue实例或者是Vue组件,在网页中各个生命阶段所执行的函数。
Vue生命周期可以类比Python中的对象。
生命周期函数可以分为三个阶段:

  • 创建阶段
  • 运行阶段
  • 销毁阶段

在生命周期的各个阶段需要执行的函数可以从下图(官方提供)得出:
vue lifecycle

2.创建阶段

创建期间的函数有beforeCreatecreatedbeforeMountmounted

beforeCreate

Vue或者组件刚刚实例化,data、methods都还没有被创建。
beforeCreate()方法测试:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue模板语法</title>
</head>

<body>
    <div id='app'>
        
    </div>
</body>

</html>


<script src="https://cdn.jsdelivr.net/npm/vue"></script>


<script>
    new Vue({
        el: '#app',
        data:{
            username:'Corley'
        },
        methods:{
            hello:function(){
                return 'hello worid'
            }
        },
        beforeCreate(){
            console.log('*************'),
            console.log(this.name),
            console.log(this.hello),
            console.log('*************')
        }
    })
</script>

显示:
vue lifecycle beforecreate

created

此时data和methods已经被创建,可以使用了,但模板还没有被编译。
created()方法测试:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue模板语法</title>
</head>

<body>
    <div id='app'>
        
    </div>
</body>

</html>


<script src="https://cdn.jsdelivr.net/npm/vue"></script>


<script>
    new Vue({
        el: '#app',
        data:{
            username:'Corley'
        },
        methods:{
            hello:function(){
                return 'hello worid'
            }
        },
        created(){
            console.log('*************'),
            console.log(this.username),
            console.log(this.hello),
            console.log('*************')
        }
    })
</script>

显示:
vue lifecycle created

beforeMount

created的下一阶段,此时模板已经被编译了,但是并没有被挂在到网页中。
beforeMount()方法测试:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue模板语法</title>
</head>

<body>
    <div id='app'>
        <p id='username'>{{username}}</p>
    </div>
</body>

</html>


<script src="https://cdn.jsdelivr.net/npm/vue"></script>


<script>
    new Vue({
        el: '#app',
        data:{
            username:'Corley'
        },
        methods:{
            hello:function(){
                return 'hello worid'
            }
        },
        beforeMount(){
            console.log('*************'),
            console.log(document.getElementById('username').innerText),
            console.log('*************')
        }
    })
</script>

显示:
vue lifecycle beforemount
即在调用beforeMount()方法时还是原生的HTML代码,未挂载到网页。

mounted

模板代码已经被加载到网页中,此时创建期间所有事情都已经准备好了,网页开始运行。
mounted()方法测试如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue模板语法</title>
</head>

<body>
    <div id='app'>
        <p id='username'>{{username}}</p>
    </div>
</body>

</html>


<script src="https://cdn.jsdelivr.net/npm/vue"></script>


<script>
    new Vue({
        el: '#app',
        data:{
            username:'Corley'
        },
        methods:{
            hello:function(){
                return 'hello worid'
            }
        },
        mounted(){
            console.log('*************'),
            console.log(document.getElementById('username').innerText),
            console.log('*************')
        }
    })
</script>

显示:
vue lifecycle mounted

3.运行阶段

运行期间的函数有beforeUpdateupdated

beforeUpdate

在网页网页运行期间,data中的数据可能会进行更新。
在这个阶段,数据只是在data中更新了,但是并没有在模板中进行更新,因此网页中显示的还是之前的。
beforeUpdate()方法测试:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue模板语法</title>
</head>

<body>
    <div id='app'>
        <input type="text" v-model="username">
        <p id='username'>{{username}}</p>
    </div>
</body>

</html>


<script src="https://cdn.jsdelivr.net/npm/vue"></script>


<script>
    new Vue({
        el: '#app',
        data:{
            username:'Corley'
        },
        methods:{
            hello:function(){
                return 'hello worid'
            }
        },
        beforeUpdate(){
            console.log('*************'),
            console.log(document.getElementById('username').innerText),
            console.log('*************')
        }
    })
</script>

显示:
vue lifecycle beforeupdate
显然,每次获取到的都是更新之前的值。

updated

此时数据在data中更新了,也在网页中更新了。
updated()方法测试:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue模板语法</title>
</head>

<body>
    <div id='app'>
        <input type="text" v-model="username">
        <p id='username'>{{username}}</p>
    </div>
</body>

</html>


<script src="https://cdn.jsdelivr.net/npm/vue"></script>


<script>
    new Vue({
        el: '#app',
        data:{
            username:'Corley'
        },
        methods:{
            hello:function(){
                return 'hello worid'
            }
        },
        updated(){
            console.log('*************'),
            console.log(document.getElementById('username').innerText),
            console.log('*************')
        }
    })
</script>

显示:
vue lifecycle updated
此时显示的是更新之后的数据。

4.销毁期间

销毁期间的函数有beforeDestroy、destroyed。

beforeDestroy

Vue实例或者是组件在被销毁之前执行的函数,在这一个函数中Vue或者组件中所有的属性都是可以使用的。
beforeDestroy()方法测试:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue模板语法</title>
</head>

<body>
    <div id='app'>
        <p id='username'>{{username}}</p>
        <error-view v-bind:message="message" v-if="message"></error-view>
        <button @click="message=''">销毁</button>
    </div>
</body>

</html>


<script src="https://cdn.jsdelivr.net/npm/vue"></script>


<script>
    Vue.component('error-view',{
        props:['message'],
        template:'<p style="color:red">{{message}}</p>',
        beforeDestroy(){
            console.log('组件已销毁')
        }
    })

    new Vue({
        el: '#app',
        data:{
            username:'Corley',
            message:'错误信息'
        },
        methods:{
            hello:function(){
                return 'hello worid'
            }
        },
        updated(){
            console.log('*************'),
            console.log(document.getElementById('username').innerText),
            console.log('*************')
        }
    })
</script>

显示:
vue lifecycle beforedestroy
由于直接销毁Vue对象即相当于关闭当前网页,查看不到beforeDestroy()方法调用时的现象,所以转化为查看销毁创建的组件时的现象。

destroyed

Vue实例或者是组件被销毁后执行的,此时Vue实例上所有东西都会解绑,所有事件都会被移除,所有子元素都会被销毁。
测试如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue模板语法</title>
</head>

<body>
    <div id='app'>
        <p id='username'>{{username}}</p>
        <error-view v-bind:message="message" v-if="message"></error-view>
        <button @click="message=''">销毁</button>
    </div>
</body>

</html>


<script src="https://cdn.jsdelivr.net/npm/vue"></script>


<script>
    Vue.component('error-view',{
        props:['message'],
        template:'<p style="color:red">{{message}}</p>',
        destroyed() {
            this.$destroy() 
            console.log("destoryed");
        }
    })

    new Vue({
        el: '#app',
        data:{
            username:'Corley',
            message:'错误信息'
        },
        methods:{
            hello:function(){
                return 'hello worid'
            }
        },
    })
</script>

显示:
vue lifecycle destroyed
调用系统的destroy()方法来使组件销毁,从而可以观察到销毁的现象。

发布了100 篇原创文章 · 获赞 898 · 访问量 25万+

猜你喜欢

转载自blog.csdn.net/CUFEECR/article/details/105315373