Vue3初体验(2)

一、props的使用

父组件可以传递简单类型和响应式对象类型的数据给子组件,具体操作只需要在调用子组件时,给子组件标签加属性,子组件接收该属性的,并展示对应的值。

子组件具体是通过defineProps([属性1,属性2......])来接收数据的。// 是一个数组,接收多个值。

下面是父组件的示例:

复制代码
<template>
  <h2>props-父亲</h2>
  <button @click="addAddr">父加一条地址</button>
  <hr>
  <person a="儿子,我是爸爸" :address="addrs"/>
</template>
<script setup>
  import person from '@/views/person.vue'
  import {reactive} from 'vue'
  let addrs = reactive([
      { id: 1, addrName: '现居住', city: '北京朝阳区', detail: '朝阳街1号' },
      { id: 2, addrName: '公司', city: '北京海淀区', detail: '海淀1号' },
      { id: 3, addrName: '老家', city: '山西省大同市', detail: '中央大街1号' }
  ])

  function addAddr(){
      let id = Math.floor(Math.random() * 1000) // 可能重复,这里只是示例
      addrs.push({ id: id, addrName: '新地址' + id, city: '新地址朝阳区', detail: '新地址朝阳街1号' })
  }


</script>

下面是子组件的示例:

复制代码
<template>
    <h2>props-儿子</h2>
    <div>来自父亲传过来的数据:{{ a }}</div>
    <ul>
        <li v-for="item in address" :key="item.id">{{ item.addrName }}的详细地址是{{ item.city }}{{ item.detail }}</li>
    </ul>
</template>
<script setup>
    defineProps(['a','address'])
</script>

二、生命周期

1、Vue2的生命周期

vue2的生命周期是分为4个阶段8个函数

具体如下:

生命周期 函数
创建 beforeCreate(), created()
挂载 beforeMount(), mounted()
更新 beforeUpdate(), updated()
销毁 beforeDestroy(),destroyed()

2、Vue3的生命周期

在 vue3 中,不用再写 beforeCreatecreated ,用 setup 函数替代了;销毁改为卸载了。

vue3的生命周期是分为4个阶段7个函数

具体如下:

生命周期 函数
创建 setup
挂载 onBeforeMount(), onMounted()
更新 onBeforeUpdate(), onUpdated()
卸载 onBeforeUnmount(),onUnmounted()

代码示例-父组件:

复制代码
<template>
  <button @click="flag = !flag">点我更新person组件状态</button>
  <person v-if="!flag"/>
</template>
<script setup>
  import person from '@/views/person.vue'
  import {ref} from 'vue'
  let flag = ref(true)
</script>

代码示例-子组件:

复制代码
<template>
    <div>{{ sum }}</div>
    <button @click="sum+=1">点我sum+1</button>
</template>
<script setup>
    import {ref,onBeforeMount, onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted } from 'vue';
    let sum = ref(0)
    
    onBeforeMount(()=>{
        console.log('onBeforeMount执行了-挂载前')
    })

    onMounted(()=>{
        console.log('onMounted执行了-挂载后')
    })

    onBeforeUpdate(()=>{
        console.log('onBeforeUpdate执行了-更新前')
    })

    onUpdated(()=>{
        console.log('onUpdated执行了-更新后')
    })

    onBeforeUnmount(()=>{
        console.log('onBeforeUnmount执行了-卸载前')
    })

    onUnmounted(()=>{
        console.log('onUnmounted执行了-卸载后')
    })

</script>

三、Hooks用法和真正的Composition组合式API

一、Hooks介绍

Hooks,顾名思义,挂钩;钩子的意思。在Vue3里,通过hooks,将不同的功能的数据,方法,计算属性,生命周期函数等,所有和该功能有关联的内容,封装到一个函数中。只需要在使用该功能的地方直接引入即可。多个功能,多个Hooks。这样实际就组成了Vue3中真正的Composition组合式API。

二、示例

我们定义2个功能:(只为演示说明)用不同实现,看下效果。

功能1:计算2个数字的和。

功能2:修改个人信息

2.1 不用hooks实现

复制代码
<template>
    <div>{{ count }}</div>
    <button @click="addCount">点我count+10</button>
    <hr>
    <h2>个人信息展示:{{ person.name }}的年龄是{{ person.age }},爱好是{{ person.hobby }}</h2>
     <button @click="changeInfo">点我修改个人信息</button>
</template>
<script setup>
    import {ref,reactive} from 'vue'
    let count = ref(10)
    let person = reactive({name:'张三',age:18,hobby:'打球'})
    function addCount(){
        count.value +=10
    }
    function changeInfo(){
        person.hobby = '追剧'
    }
</script>

但是两个功能是这样子,那么多个功能呢?假设有100个功能,那每个功能的数据、方法、计算属性都放到一起,那有需求变化时,简直就是噩梦。这就需要用到开头说的hooks来进行封装了。


2.2 使用hooks实现

首先呢,需要新建hooks文件,文件的命名规范是use开头功能结尾,比如我们这个就可以写成useCount和usePerson,如下,新建hooks目录和文件。

目录和文件:

count功能useCount.ts代码如下:

复制代码
import {ref} from 'vue'
export default function(){
    let count = ref(10)
    function addCount(){
        count.value +=10
    }
    return{count,addCount}
}

修改个人信息的usePerson.ts代码如下:

复制代码
import {reactive} from 'vue'
export default function(){
    let person = reactive({name:'张三',age:18,hobby:'打球'})
    function changeInfo(){
        person.hobby = '追剧'
    }
    return{person,changeInfo}
}

主文件内容如下:

复制代码
<template>
    <div>{{ count }}</div>
    <button @click="addCount">点我count+10</button>
    <hr>
    <h2>个人信息展示:{{ person.name }}的年龄是{{ person.age }},爱好是{{ person.hobby }}</h2>
     <button @click="changeInfo">点我修改个人信息</button>
</template>
<script setup>
    import useCount from '@/Hooks/useCount'
    import usePerson from '@/Hooks/usePerson'

    let {count,addCount} = useCount()
    let {person,changeInfo} = usePerson()
</script>

四、路由

  1. 对路由的理解

它允许你通过定义不同的路径来导航到不同的组件,并且可以实现页面间的无缝切换而不重新加载整个页面。

  1. 路由配置演示

(1) 如果还没下载vue-router需要先下载

复制代码
npm install vue-router

(2)scr 目录下新建 router 文件夹,在其下创建index.ts 文件

index.ts 文件( 将一组一组的路由配置到routes里。这里引入了2个页面组件,用来切换和显示***)***

复制代码
import {createRouter,createWebHistory} from 'vue-router'
import Person from '@/views/person.vue'
import Count from '@/views/count.vue'
const router = createRouter({
    history:createWebHistory(),
    routes:[
        {
            path:'/person',
            component:Person
        },
        {
            path:'/count',
            component:Count
        },
    ]
})
export default router

createRouter: 这是从 vue-router 包中导入的一个函数,用于创建一个新的路由器实例。

createWebHistory:也是从vue-router 包中导入的一个函数,意味着应用将使用 history 模式,与之对应的还有hash模式。

export default router:导出路由实例,以方便在其他地方导入使用。

(3) 在main.ts 下使用 vue-router

main.ts 文件

复制代码
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
//第一步:引入创建pinia的函数
import { createPinia } from 'pinia'

const app = createApp(App)
//第二步:创建pinia的函数,最好在创建完app以后
const pinia = createPinia()
//第三步:将pinia应用到app上
app.use(router)
app.use(pinia)
app.mount('#app')

(4) 声明式导航代码示例 ------ 新建几个组件,并编写跳转代码

App.vue 文件

复制代码
<template>
  <div>
    <router-link to="/person" active-class="active">人员信息</router-link>
    <router-link to="/count" active-class="active">count相关的信息</router-link>
  </div>
  <div class="main">
    <RouterView></RouterView>
  </div>
</template>
<script setup></script>
<style>
a{
  border: 1px solid #000;
  margin-right: 10px;
}
.main{
  margin-top: 20px;
  width: 100%;
  height: 200px;
  border: 1px solid #000;
}
.active {
  background-color: skyblue;
}
</style>

通过<RouterLink to="/person" active-class="active">person</RouterLink> 来识别和控制路由切换,以及选中样式的添加。

to有3种写法,:to="{path:'/person'}"和to="/person" 和:to="{name: 'xinxi'}"

通过<RouterView></RouterView>来定位路由切换后页面组件的显示位置。


person.vue

复制代码
<template>
    <h2>个人信息展示:{{ person.name }}的年龄是{{ person.age }},爱好是{{ person.hobby }}</h2>
    <button @click="changeInfo">点我修改个人信息</button>
</template>
<script setup>
    import usePerson from '@/Hooks/usePerson'
    let {person,changeInfo} = usePerson()
</script>

count.vue

复制代码
<template>
    <div>{{ count }}</div>
    <button @click="addCount">点我count+10</button>
    
</template>
<script setup>
    import useCount from '@/Hooks/useCount'
    let {count,addCount} = useCount()
</script>

上面实现一个基本的路由切换

五、编程式路由导航

在实际开发中,我们经常是通过在<script>脚本里来进行路由跳转的,直接用<RouterLink>的时候较少。使用编程式导航的场景更多。

如下,将跳转person的路由替换成一个button,调用一个方法。在方法中进行跳转路由,这里需要引入useRouter,并使用router.push或者router.replace方法进行路由跳转。方法里的内容和<RouterLink>里属性to的内容完全是一样的。


举个例子:从count.vue跳转到person.vue

复制代码
//count.vue

<template>
    <button @click="toPerson()">Person</button>
</template>
<script setup lang="ts">
import { useRouter } from 'vue-router';

const router = useRouter();
function toPerson() {
    router.push(
      {
        path: '/person',
        query: {
          id: 1,
          name: '王大拿',
          age: 56
        }
      }
    )
}
</script>

//person.vue

<template>
    <div>从count组件接收到的信息是:{{query.name  }}的年龄是{{ query.age }}</div>
</template>
<script setup>
    import {useRoute} from 'vue-router'
    const {query} = useRoute()//接收参数
</script>

跳转的时候可以使用push跳转,也可以使用replace,push和replace的区别就是,push的留存浏览记录的,可以在浏览器前进和回退里进行操作上一步或者下一步,而replace是不保存浏览记录的。在浏览器前进和回退是无法点击的。

六、路由的两种模式 ------ History 与 Hash 模式

1.1 history 模式

优点:url 更加美观,不带有 #,更接近传统网站的url.

缺点:后期项目上线,需要服务端配合处理路径问题,否则刷新会有 404 报错。

1.2 hash 模式

优点:兼容性更好,因为不需要服务器端处理路径。

缺点:url 不美观,且在`SEO`优化方面相对较差。

1.3 刷新导致404的原因

使用 history 模式,如果服务端不配合处理路径问题,那么刷新会有404 报错。原因是当你直接访问某个路由路径或刷新页面时,浏览器会向服务器请求该路径,而服务器如果没有正确配置,则会返回 404 错误。

hash模式不会出现这种情况的原因是,'#'号后面的部分被称为 hash部分,例如一个链接 http://xxxxx.xxx/#aaa 浏览器在请求页面时,只会发送 http://xxxxx.xxx 这部分 URL 给服务器,而这部分 #aaa(即 hash 部分)不会被发送。因此无论用户访问的路径是什么(例如 /home /about ),服务器始终只接收到根路径 / 的请求。这意味着服务器总是返回 index.html 文件,然后由 Vue Router 在客户端解析并显示相应的组件。

关于路由更详细的内容可以参考:https://blog.csdn.net/qq_58195504/article/details/145496539

相关推荐
css趣多多1 小时前
vue3的ref响应式,取值的时候自动补全value的设置,以及两种修改方式
前端
学习3人组1 小时前
Win11 使用 Proxifier 强制本地流量通过 Fiddler Classic 代理指南
前端·测试工具·fiddler
超绝大帅哥2 小时前
vue2vue3响应式
前端
Hhang2 小时前
Pageindex -- 新一代的文档智能检索
前端·人工智能
恋猫de小郭2 小时前
Claude Code 已经 100% 自己写代码,为什么 Anthropic 还有上百个工程职位空缺?
前端·人工智能·ai编程
liann1192 小时前
4.3.2_WEB——WEB后端语言——PHP
开发语言·前端·网络·安全·web安全·网络安全·php
是欢欢啊2 小时前
前端纯原生canvas图片裁剪工具,不依赖任何插件
前端
zheshiyangyang2 小时前
前端面试基础知识整理【Day-4】
前端·面试·职场和发展
FunW1n2 小时前
tmf.js Hook Shark框架相关疑问归纳总结报告
java·前端·javascript