插槽就是向指定位置插入一段html代码

案例1

MyTable组件

<template>
    <table border="1" width="500px">
        <thead>
            <tr>
                <th>编号</th>
                <th>姓名</th>
                <th>年龄</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>1000</td>
                <td>张三</td>
                <td>20</td>
                <td>
                    <!-- 插槽出口 -->
                    <slot></slot>
                </td>
            </tr>
        </tbody>
    </table>
</template>

父组件

<template>
 
    <MyTable>
        <button>删除</button>
        <button>编辑</button>
    </MyTable>
    
</template>
 
<script setup>
    import MyTable from './MyTable.vue';
</script>
 
<style scoped>
    button {
        background-color: red;
    }
</style>

具名插槽

子组件

<template>
    <table border="1" width="500px">
        <thead>
            <tr>
                <th>编号</th>
                <th>姓名</th>
                <th>年龄</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>1000</td>
                <td>张三</td>
                <td>20</td>
                <td>
                    <!-- 插槽出口 -->
                    <slot name="opation"></slot>
                </td>
            </tr>
            <tr>
                <td colspan="4">
                    <slot name="footer"></slot>
                </td>
            </tr>
        </tbody>
    </table>
</template>

父组件

<template>
 
    <MyTable>
        <!-- 简写<template #opation> -->
        <template v-slot:opation> 
            <button>删除</button>
            <button>编辑</button>
        </template>
        <template #footer>
            共<span style="color: red;">100</span>条数据
        </template>
    </MyTable>
    
</template>
 
<script setup>
    import MyTable from './MyTable.vue';
</script>
 
<style scoped>
    button {
        background-color: red;
    }
</style>

生命周期

选项式

<template>
    <h1 ref="title" @click="test">{{msg}}</h1>
    <SubLive v-if="isShow" @click="cheangeShow"/>
</template>
<script>
 
import SubLive from '@/components/t5/SubLive.vue'
 
    export default {
        data(){
            return {
                msg: '张三',
                isShow: true
            }
        },
        components: {
            SubLive
        },
        beforeCreate(){
            // 在这里,你不能访问 this.msg,因为数据属性还未被初始化  
            // 你可以执行一些初始化操作,这些操作不依赖于组件的数据或 DOM  
            // 例如,设置初始状态、加载非响应式数据、配置事件监听器
 
            //无法获取dom信息
            console.log("beforeCreate:"+this.$refs.title)
            // 无法获取data参数
            console.log("beforeCreate:"+this.msg); 
        },
        created() {
            //这里可以访问thi.msg
            //但是不可以访问DOM
            //适合发送一下不需要操作DOM的网络请求,这里可以调用methods里的函数
 
            //无法获取dom信息
            console.log("created:"+this.$refs.title)
            // 可以获取data参数
            //this.msg = '李四'
            console.log("created:"+this.msg); 
        },
        beforeMount(){
            // 在这里,模板已经编译成虚拟 DOM,但尚未挂载到页面  
            // 你可以做一些在挂载之前的准备工作  
            // 注意:此时不能操作真实的 DOM 元素
 
            //无法获取dom信息
            console.log("beforeMount:"+this.$refs.title)
            //可以获取data参数
            console.log("beforeMount:"+this.msg);
        },
        mounted(){
            //此时组件的模板已经渲染成了真实的 DOM,并挂载到了页面的指定元素上,可以进行DOM操作
            //父组件上的mounted会在子组件之后最后执行
 
            //可以获取dom信息
            console.log("mounted:"+this.$refs.title)
            //可以获取data参数
            console.log("mounted:"+this.msg);
            this.$refs.title.style.color = 'red';
        },
        beforeUpdate(){
            //它在组件的数据发生变化,并且虚拟 DOM 即将重新渲染和打补丁之前被调用。但是,此时组件的 DOM 还没有被更新,所以你仍然看到的是旧的 DOM。
 
            //此时获取的DOM仍然是旧DOM
            console.log("beforeUpdate:"+this.$refs.title.innerHTML);
 
        },
        updated(){
            // 在这里,你可以安全地访问和操作更新后的 DOM 元素  
            // 例如,重新计算某些元素的位置或尺寸  
            // 或者启动某些依赖于更新后 DOM 的动画
            console.log("updated:"+this.$refs.title.innerHTML);
        },
 
        methods: {
             test(){
                this.msg = '更新啦'
            },
            cheangeShow(){
                this.isShow = false
            }
        },
 
    }
</script>
 
<style scoped>
 
</style>
<template>
    <h1 ref="title">啊啊啊</h1>
</template>
 
<script>
    export default {
        data(){
            return {
                timer: null
            }
        },
        mounted(){
            this.timer = setInterval(()=>{
                console.log(1);
            },1000)
        }
        ,
        beforeUnmount(){
            console.log('sub-beforeUnmount')
            console.log('sub-beforeUnmount:'+this.$refs.title);
            //清理定时器
            clearInterval(this.timer)
            this.timer = null
 
        },
        unmounted(){
            console.log('sub-unmounted')
            //无法获取DOM因为组件被销毁
            console.log('sub-unmounted:'+this.$refs.title);
        },
       
        
    }
</script>
 

组合式(vue3 组合式中取消了beforeCreate、created) setup函数取代

<template>
    <h1 ref="title" @click="test">{{msg}}</h1>
    <SubLive v-if="isShow" @click="cheangeShow"/>
</template>
<script setup>
 
import SubLive from '@/components/t5/SubLive.vue'
import { ref,onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted } from 'vue';
 
    let msg = ref('张三');
    let isShow = ref(true);
 
    let title = ref(null)
 
    function cheangeShow(){
        isShow.value = false;
    }
 
    const test = () => {
        msg.value = '更新啦'
    }
 
    onBeforeMount(()=>{
        // 在这里,模板已经编译成虚拟 DOM,但尚未挂载到页面  
        // 你可以做一些在挂载之前的准备工作  
        // 注意:此时不能操作真实的 DOM 元素
 
        //无法获取dom信息
        console.log("beforeMount:"+title.value)
        //可以获取data参数
        console.log("beforeMount:"+msg.value);
    })
 
    onMounted(()=>{
        //此时组件的模板已经渲染成了真实的 DOM,并挂载到了页面的指定元素上,可以进行DOM操作
        //父组件上的mounted会在子组件之后最后执行
 
        //可以获取dom信息
        console.log("mounted:"+title.value)
        //可以获取data参数
        console.log("mounted:"+msg.value);
        title.value.style.color = 'red';
    })
 
    onBeforeUpdate(()=>{
        //它在组件的数据发生变化,并且虚拟 DOM 即将重新渲染和打补丁之前被调用。但是,此时组件的 DOM 还没有被更新,所以你仍然看到的是旧的 DOM。
 
        //此时获取的DOM仍然是旧DOM
        console.log("beforeUpdate:"+title.value.innerHTML);
    })
 
    onUpdated(()=>{
            // 在这里,你可以安全地访问和操作更新后的 DOM 元素  
            // 例如,重新计算某些元素的位置或尺寸  
            // 或者启动某些依赖于更新后 DOM 的动画
            console.log("updated:"+title.value.innerHTML);
    })
</script>
 
<style scoped>
 
</style>

路由

安装路由

npm install vue-router

在src目录下创建一个目录views,改目录下存放页面文件

在src目录下创建一个目录router,在router目录下创建一个index.js文件

index.js

import { createRouter,createWebHistory } from "vue-router";
 
const routers = [
    {
        path: '/',
        name: 'home',
        component: () => import('@/views/Home.vue')
    },
    {
        path: '/page1',
        name: 'page1',
        component: () => import('@/views/Page1.vue')
    },
    {
        path: '/page2',
        name: 'page2',
        component: () => import('@/views/Page2.vue')
    }
]
 
const router = createRouter({
    routes: routers,
    history: createWebHistory()
})
 
export default router

全局引入

main.js

import { createApp } from 'vue'
import App from './App.vue'
import router from './router';
import Header from '@/components/t4/Header.vue'
 
const app = createApp(App);
 
// 注入全局组件
app.component('Header',Header);
 
app.use(router);
 
app.mount('#app')

App.vue

<template>
    <RouterView></RouterView>
</template>
 
<script setup>
   
</script>
 
<style scoped>
    
</style>

Home.vue

<template>
    <h1>欢迎光临,首页</h1>
    <!-- <RouterLink to="/page1?id=10">测试页1</RouterLink>&nbsp; -->
    <RouterLink :to="{path: '/page1',query: {id: 10}}">测试页1</RouterLink>&nbsp;
    <button @click="testJump">测试页2</button>
</template>
 
<script setup>
    // export default {
    //     data(){
    //         return {
                
    //         }
    //     },
    //     methods: {
    //         testJump(){
    //             this.$router.replace('/page2'); //没有历史记录的跳转,无法返回上一页
    //             //this.$router.push('/page2');//有历史记录的跳转
    //         }
    //     }
    // }
 
    import { useRouter } from "vue-router";
    const router = useRouter(); // 使用路由k
 
    function testJump(){
        //router.push('/page2');
        // router.replace('/page2')
 
        router.push({
            path: '/page2',
            query: {id: 100}
        })
    }
 
</script>

Page1.vue

<template>
    <h1>测试页1</h1>
    <h1>{{id}}</h1>
</template>
 
<script setup>
    // export default {
    //     data() {
    //         return {
    //             id: this.$route.query.id
    //         }
    //     },
    // }
 
    import { ref } from 'vue';
    import { useRoute } from 'vue-router';
 
    let route = useRoute();
 
    let id = ref(route.query.id)
</script>

Page2.vue

<template>
    <h1>测试页2</h1>
    <h1>参数:{{$route.query.id}}</h1>
</template>