Vue组件

一、生命周期:

 

1.单个组件:

 

(1)挂载阶段:

  beforeCreate

  created(Vue实例初始化完成,并没有开始渲染)

  beforeMount

  mounted(页面渲染完成)

 

(2)更新阶段:

  beforeUpdate

  updated

 

(3)销毁阶段:

  beforeDestroy(解除绑定、销毁子组件、销毁事件监听器)

  destroyed

 

2.父子组件:

 

 

(1)基本原则:

  初始化Vue实例:从外到内

  渲染:从内到外(只有把子组件渲染完了,父组件才能渲染完)

  更新前:从外到内

  更新完:从内到外(只有把子组件更新完了,父组件才能更新完)

  销毁前:从外到内

  销毁完:从内到外(只有把子组件销毁完了,父组件才能销毁完)

 

(2)各种阶段的流程:

  初始化和渲染阶段:

    父beforeCreate => 父created => 父beforeMount => 子beforeCreate => 子created => 子beforeMount => 子mounted => 父mounted,子组件的流程插入了父组件的beforeMount和mounted之间

  更新阶段:

    父beforeUpdate => 子beforeUpdate => 子updated => 父updated,子组件的流程插入了父组件的beforeUpdate和updated之间

  销毁阶段:

    父beforeDestroy => 子beforeDestroy => 子destroyed => 父destroyed,子组件的流程插入了父组件的beforeDestroy和destroyed之间

 

二、父子组件通讯:

 

1.props(类型和默认值)

<template>
    <div>
        <Input @add="addHandler"/>
        <List :list="list" @delete="deleteHandler"/>
    </div>
</template>

<script>
import Input from './Input'
import List from './List'

export default {
    components: {
        Input,
        List
    },
    data() {
        return {
            list: [
                {
                    id: 'id-1',
                    title: '标题1'
                },
                {
                    id: 'id-2',
                    title: '标题2'
                }
            ]
        }
    },
    methods: {
        addHandler(title) {
            this.list.push({
                id: `id-${Date.now()}`,
                title
            })
        },
        deleteHandler(id) {
            this.list = this.list.filter(item => item.id !== id)
        }
    },
    created() {
        // eslint-disable-next-line
        console.log('index created')
    },
    mounted() {
        // eslint-disable-next-line
        console.log('index mounted')
    },
    beforeUpdate() {
        // eslint-disable-next-line
        console.log('index before update')
    },
    updated() {
        // eslint-disable-next-line
        console.log('index updated')
    },
}
</script>

 

2.v-on和$emit:

<template>
    <div>
        <input type="text" v-model="title"/>
        <button @click="addTitle">add</button>
    </div>
</template>

<script>
import event from './event'

export default {
    data() {
        return {
            title: ''
        }
    },
    methods: {
        addTitle() {
            // 调用父组件的事件
            this.$emit('add', this.title)

            // 调用自定义事件
            event.$emit('onAddTitle', this.title)

            this.title = ''
        }
    }
}
</script>
<template>
    <div>
        <ul>
            <li v-for="item in list" :key="item.id">
                {{item.title}}

                <button @click="deleteItem(item.id)">删除</button>
            </li>
        </ul>
    </div>
</template>

<script>
import event from './event'

export default {
    // props: ['list']
    props: {
        // prop 类型和默认值
        list: {
            type: Array,
            default() {
                return []
            }
        }
    },
    data() {
        return {

        }
    },
    methods: {
        deleteItem(id) {
            this.$emit('delete', id)
        },
        addTitleHandler(title) {
            // eslint-disable-next-line
            console.log('on add title', title)
        }
    },
    created() {
        // eslint-disable-next-line
        console.log('list created')
    },
    mounted() {
        // eslint-disable-next-line
        console.log('list mounted')

        // 绑定自定义事件
        event.$on('onAddTitle', this.addTitleHandler)
    },
    beforeUpdate() {
        // eslint-disable-next-line
        console.log('list before update')
    },
    updated() {
        // eslint-disable-next-line
        console.log('list updated')
    },
    beforeDestroy() {
        // 及时销毁,否则可能造成内存泄露
        event.$off('onAddTitle', this.addTitleHandler)
    }
}
</script>

 

三、非父子组件通讯:自定义事件

<template>
    <div>
        <input type="text" v-model="title"/>
        <button @click="addTitle">add</button>
    </div>
</template>

<script>
import event from './event'

export default {
    data() {
        return {
            title: ''
        }
    },
    methods: {
        addTitle() {
            // 调用父组件的事件
            this.$emit('add', this.title)

            // 调用自定义事件
            event.$emit('onAddTitle', this.title)

            this.title = ''
        }
    }
}
</script>
<template>
    <div>
        <ul>
            <li v-for="item in list" :key="item.id">
                {{item.title}}

                <button @click="deleteItem(item.id)">删除</button>
            </li>
        </ul>
    </div>
</template>

<script>
import event from './event'

export default {
    // props: ['list']
    props: {
        // prop 类型和默认值
        list: {
            type: Array,
            default() {
                return []
            }
        }
    },
    data() {
        return {

        }
    },
    methods: {
        deleteItem(id) {
            this.$emit('delete', id)
        },
        addTitleHandler(title) {
            // eslint-disable-next-line
            console.log('on add title', title)
        }
    },
    created() {
        // eslint-disable-next-line
        console.log('list created')
    },
    mounted() {
        // eslint-disable-next-line
        console.log('list mounted')

        // 绑定自定义事件
        event.$on('onAddTitle', this.addTitleHandler)
    },
    beforeUpdate() {
        // eslint-disable-next-line
        console.log('list before update')
    },
    updated() {
        // eslint-disable-next-line
        console.log('list updated')
    },
    beforeDestroy() {
        // 及时销毁,否则可能造成内存泄露
        event.$off('onAddTitle', this.addTitleHandler)
    }
}
</script>
import Vue from 'vue'

export default new Vue()
// 这是eventjs,Vue本身已经实现了自定义事件,不需要使用bus之类的

 

四、v-slot:

1.定义:插槽,相当于是复杂的属性

2.类型:默认插槽、具名插槽、作用域插槽(传递的是一个返回组件的函数)

3.解释:

https://blog.csdn.net/liushijun_/article/details/92186739?spm=1001.2014.3001.5502

 

 

posted @ 2021-05-07 11:02  starlog  阅读(71)  评论(0编辑  收藏  举报