vue3快速入门(看心情更新)

vue3初始化工程目录


在这里插入图片描述



编写一个App


.vscode下的extensions.json 配置插件的地方
public 页签图标
src 你的.vue文件都是在这个目录下的
.gitgnore 忽略文件
env.d.ts 让Ts去识别一些文件
index.html 入口文件
vite.config.ts 整个工程的配置文件

.vue文件中可以写的内容 template(结构标签) script(脚本标签 js/ts) style(样式)

<!-- template(结构标签)  script(脚本标签 js/ts)  style(样式) -->

<template>
    <div class="app">
        <h1>你好啊</h1>
    </div>
</template>

<script lang="ts">
    export default{
        name:'app' // 组件的名子
    }
</script>

<style>
    .app{
        background-color: antiquewhite;
        box-shadow: 0 0 10px;
        border-radius: 10px;
        padding: 20px;
    }
</style>

main.ts文件

// 引入crerateApp用来创建应用
import {createApp} from 'vue'
// 引入App根组件
import App from './App.vue'

createApp(App).mount('#app')


OptionsApi 与 CompositionApi (setup)

什么是选项式(vue2),什么是组合式(vue3)

// 选项式 vue2

<h2>姓名:{{ name }}</h2>
<h2>年龄:{{ age }}</h2>
<button @click="changeName">修改名子</button>
<button @click="changeAge">修改年龄</button>
<button @click="showTel">电话</button>

export default{
        name:'Person',
        data(){
            return{
            	// 数据
                name:'张三',
                age:18, 
                tel:'124345555'
            }
        },
        methods:{
        	// 方法
            changeName(){
                this.name = 'zhang-san'
            },
            changeAge(){
                this.age += 1
            },
            showTel(){
                alert(this.tel)
            }
        },

// 组合式 vue3

<h2>姓名:{{ name }}</h2>
<h2>年龄:{{ age }}</h2>
<button @click="changeName">修改名子</button>
<button @click="changeAge">修改年龄</button>
<button @click="showTel">电话</button>


export default{
        name:'Person',
        setup(){
            // 数据
            let name = '张三' // 这样写name不是响应式的
            let age = 18
            let tel = 12388889999
            
			// 方法
            function changeName(){
                name = 'zhang-san'
            }
            function changeAge(){
                age += 1
            }
            function showTel(){
                alert(tel)
            }
            // 最后把数据交出去
            return {
                name,
                age,
                changeName,
                changeAge,
                showTel
            }
            // setup的返回值也可以是一个渲染的函数
			return ()=> 'hh'
        }
        
    }


setup 语法糖


<script setup lang="ts"> 
// 相当于setup 并且会自动retrun 
    let a = '李四'
    let b = 29
    let tel = 1238888888 
</script>


ref基本类型的响应式数据

注:erf还可以定义对象类型的响应式数据


<template>
    <div class="person">
        <!-- 这里可以不用.value -->
        <h2>姓名:{{ name }}</h2>
        <h2>年龄:{{ age }}</h2>
        <button @click="changeName">修改名子</button>
        <button @click="changeAge">修改年龄</button>
        <button @click="showTel">电话</button>
    </div>
</template>


<script setup lang="ts"> 
    import {ref} from 'vue' // 想让那个数据是响应式的就用ref包一下

    let name = ref('李四') // 变成响应式数据
    let age = ref(18)
    let tel = 1238888888 

    function changeName(){
    	// 在ts/js中操作响应式数据要加上.value
    	name.value = 'zhang-san'
    }
    function changeAge(){
       age.value += 1
    }
    function showTel(){
       alert(this.tel)
    }
</script>


reactive对象类型的响应式数据

注:reactive只能定义对象类型的数据


<template>
    <div class="person">
        <h2>一辆{{ car.brand }}车,价值{{ car.price }}</h2>
        <button @click="changePrice">修改汽车的价格</button>
    </div>
</template>


<script setup lang="ts"> 
    import {reactive} from 'vue' // 想让那个数据是响应式的就用ref包一下
	
	// 可以使用ref
    let car = reactive({brand:"奔驰",price:200}) // 把对象数据用reactive包裹起来

    function changePrice(){
        car.price += 10
    }

    //同样可以让数组变成响应式
    let games = reactive([ 
        {id: 1, name: 'LOL'},
        {id: 2, name: 'CSGO'},
        {id: 3, name: 'DOTA2'},
    ])

</script>

reactive的局限性在重新分配一个对象的时候会失去响应式

    let games = reactive([ 
        {id: 1, name: 'LOL'},
        {id: 2, name: 'CSGO'},
        {id: 3, name: 'DOTA2'},
    ])

    // 重新分配一个对象 这时games就不再是一个响应式的对象了
    function changeCar(){
        games = [{
            id: 3,
            name: 'LOL'
        }]
    }

    // 可以使用Object.assign(obj1,obj2,obj3)
    Object.assign(games,games = [{id: 3,name: 'LOL'}])


ref定义对象类型的响应式数据

如果想要ref定义对象类型的响应式数据,需要使用.value来拿到对象

注:ref不能定义多次响应式对象或基本类型


<script setup lang="ts"> 
    import {ref} from 'vue' // 想让那个数据是响应式的就用ref包一下

    let games = ref([ 
        {id: 1, name: 'LOL'},
        {id: 2, name: 'CSGO'},
        {id: 3, name: 'DOTA2'},
    ])

    function changeGame (){
        //  用ref定义响应式的数据需要在对象的后面.value 拿到这个对象
        games.value[0].name = 'LOL2';
    }

	// ref可以直接修改整个对象 这样改完后还是响应式对象
	function changeRef(){
		games = {[id:4,name:'赛博朋克2077']} // reactive 不能这样
	}
</script>

可以发现ref的value不再是基本类型,而是Proxy类型底层通过reactive来处理

在这里插入图片描述

选择

  • 若需要一个基本类型的响应式数据必须用 ref
  • 若需要一个响应式对象,层级不深 ref reactive 都可以
  • 若需要一个响应式对象,且层级较深,推荐使用 reactive


toRefs 与 toRef


toRefs就是把所定义的对象变成ref所组成的响应式的数据,toRef一个个的去取变成响应式数据

<script setup lang="ts"> 
import {ref,reactive, toRef, toRefs } from 'vue' 

    // 数据
    let Person = reactive({
        name:'张三',
        age:18,
        sex:'男',
    })

    // 使用toRefs让所有数据变成响应式的数据
    let {name,age,sex} = toRefs(Person)

	// 使用toRef就是把其中一个拧出来变成响应式的数据
    let {name,age,sex} = toRef(Person,'sex')

</script>


Computed计算属性


计算属性的特点依赖的数据只要发生变化 ,就会重新计算

注:计算属性是有缓存的,只要依赖的数据没有发生变化就不会重新计算,方法就没有缓存

<template>
    <div class="person">
        姓名:<input type="text" v-model="firstNanme">
        <br>  
        名字:<input type="text" v-model="lastName">
        <br>
        全名:<span>{{ fullName }}</span>
        <button @click="changeFullName">修改</button>
    </div>
</template>


<script setup lang="ts"> 
import {ref,computed} from 'vue' // 引入computed来计算属性
let firstNanme = ref('张')
let lastName = ref('三')

// 这么定义的fullName计算属性是一个只读的,不可修改
// let fullName = computed(()=>{
//     return firstNanme.value + lastName.value
// })


// 这么定义的fullName计算属性是可读可写的
let fullName = computed({
    get(){
        return firstNanme.value.slice(0,1).toUpperCase + firstNanme.value.slice(1) +  '-' + lastName.value 
    },

    // 这里的valchangeFullName给的值
    set(val){
        const [str1,str2] = val.split('-')
        firstNanme.value = str1
        lastName.value = str2
     }
})

// 这里把值给到fullName要通过get/set的方式来让它变成可读可改的数据
function changeFullName(){
    fullName.value = '李四'
}

</script>


watch监视


vue3中的watch只能监视以下四种数据

  1. ref 定义的数据
  2. reactive 定义的数据
  3. 函数返回一个值(getter 函数)
  4. 一个包含上述内容的数组

情况:1

<template>
    <div class="person">
        <h1>情况一:监视ref定义的基本类型数据</h1>
        <h2>当前求和为:{{ sum }}</h2>        
    </div>
    <button @click="changeSum">点我sum+1</button>
</template>


<script setup lang="ts"> 
import {ref,watch} from 'vue' 

// 数据
let sum = ref(0)

// 方法
function changeSum(){
    return sum.value += 1
}

// 监视 监视ref定义的基本类型数据
const stopWatch = watch(sum,(newVaule,oldValue)=>{
    console.log(newVaule,oldValue)
    if(newVaule >= 0){
        // watch有一个返回方法,调用后就会停止监视
        stopWatch()
    }
})
</script>

情况:2

监视 ref 定义的 对象类型 数据

注意:

  • 若修改的是 ref 定义的对象中的属性,newValueoldValue 都是新值,因为它们是同一个对象
  • 若修改的是整个 ref 定义的对象,newValue 是新值 oldValue 是旧值
<template>
    <div class="person">
        <h1>情况二:监视ref定义的对象类型数据</h1>
        <h2>姓名:{{ person.name }}</h2>   
        <h2>年龄:{{ person.age }}</h2>     
    </div>
    <button @click="changeName">点我姓名</button>
    <button @click="changeAge">点我修改年龄</button>
    <button @click="changePerson">点我修改整个对象</button>
</template>


<script setup lang="ts"> 
import {ref,watch} from 'vue' 

// 数据
let person = ref({
    name:'张三',
    age:18
})

// 方法
function changeName(){
    person.value.name += '~'
}
function changeAge(){
    person.value.age += 1
}
function changePerson(){
    person.value = {name:'李四',age:20}
}

// 情况二:监视的是对象的地址值,若想监视对象内部属性的变化,需要手动开启深度监视
// 参数一:被监视的数据
// 参数二:监视的回调
// 参数三:配置对象(deep,immediate...)
watch(person,(newVaule,oldValue)=>{
    console.log(newVaule,oldValue)
},{deep:true}) // deep:true 开启深度监视
</script>

情况:3

监视 reactive 定义的 对象类型 数据

监视 reactive 定义的对象类型数据,默认开启深度监视,并且 无法关闭

<template>
    <div class="person">
        <h1>情况三:监视reactive定义的对象类型数据</h1>
        <h2>姓名:{{ person.name }}</h2>   
        <h2>年龄:{{ person.age }}</h2>     
    </div>
    <button @click="changeName">点我姓名</button>
    <button @click="changeAge">点我修改年龄</button>
    <button @click="changePerson">点我修改整个对象</button>
</template>


<script setup lang="ts"> 
import {reactive,watch} from 'vue' 

// 数据
let person = reactive({
    name:'张三',
    age:18
})

// 方法
function changeName(){
    person.name += '~'
}
function changeAge(){
    person.age += 1
}

// 无法直接用对象赋值的方式
function changePerson(){
    Object.assign(person,{name:'李四',age:20})
}

// 情况三:监视reactive定义的对象类型数据,默认是开启深度监视,并且无法关闭
watch(person,(newVaule,oldValue)=>{
    console.log(newVaule,oldValue)
},{deep:false}) // 无法关闭 
</script>

情况:4

监视 reactive 定义的 对象类型 数据中的 某个属性

注意:

  1. 若该属性值 不是 对象类型,需要 写成函数形式
  2. 若该属性值 依然对象类型,建议 写成函数形式,并 开启深度监视
<template>
    <div class="person">
        <h1>情况四:监视reactive定义的对象类型数据中的某个属性</h1>
        <h2>姓名:{{ person.name }}</h2>   
        <h2>年龄:{{ person.age }}</h2>
        <h2>气辆:{{ person.car.c1 }},{{ person.car.c2 }}</h2>
    </div>
    <button @click="changeName">点我修改姓名</button>
    <button @click="changeAge">点我修改年龄</button>
    <button @click="changeCar1">点我修改第一台车</button>
    <button @click="changeCar2">点我修改第二台车</button>
    <button @click="changeCarAll">点我修改整台车</button>
</template>


<script setup lang="ts"> 
import {reactive,watch} from 'vue' 

// 数据
let person = reactive({
    name:'张三',
    age:18,
    car:{
        c1:'奔驰',
        c2:'宝马'
    }
})

// 方法
function changeName(){
    person.name += '~'
}
function changeAge(){
    person.age += 1
}
function changeCar1(){
    person.car.c1 = 'BYD'
}
function changeCar2(){
    person.car.c2 = "小米"
}
function changeCarAll(){
    person.car = {c1:'华为',c2:'蔚来'}
}

// 情况四:监视reactive定义的对象类型数据中的某个属性,且该属性是基本类型的,要写成函数式
watch(()=>person.name,()=>{
    console.log('name改变啦')
})


 // 这样写就相当于监视的是这个函数的地址值
 // 只要是监视对象中的某个属性,就直接写函数式
watch(()=>person.car,()=>{
    console.log('car改变啦')
},{deep:true})

</script>

情况:5

监视上述的多个数据

<template>
    <div class="person">
        <h1>情况五:监视上述的多个数据</h1>
        <h2>姓名:{{ person.name }}</h2>   
        <h2>年龄:{{ person.age }}</h2>
        <h2>气辆:{{ person.car.c1 }},{{ person.car.c2 }}</h2>
    </div>
    <button @click="changeName">点我修改姓名</button>
    <button @click="changeAge">点我修改年龄</button>
    <button @click="changeCar1">点我修改第一台车</button>
    <button @click="changeCar2">点我修改第二台车</button>
    <button @click="changeCarAll">点我修改整台车</button>
</template>


<script setup lang="ts"> 
import {reactive,watch} from 'vue' 

// 数据
let person = reactive({
    name:'张三',
    age:18,
    car:{
        c1:'奔驰',
        c2:'宝马'
    }
})

// 方法
function changeName(){
    person.name += '~'
}
function changeAge(){
    person.age += 1
}
function changeCar1(){
    person.car.c1 = 'BYD'
}
function changeCar2(){
    person.car.c2 = "小米"
}
function changeCarAll(){
    person.car = {c1:'华为',c2:'蔚来'}
}

//情况五:监视上述的多个数据,用数组包起来,并且里面都要写成函数式
watch([()=>person.name,()=>person.age,()=>person.car.c1,()=>person.car.c2],(newValue,oldValue)=>{
    console.log(newValue,oldValue)
},{
    deep:true
})

</script>



watchEffect


watch 对比 watchEffect

  • watch:要明确指出监视的数据
  • watchEffect:不用明确指出监视的数据(函数中用到哪些属性,那就监视哪些属性)
<template>
    <div class="person">
        <h2>当前水温:{{temp }}</h2>   
        <h2>当前水位:{{height }}</h2>   
        <button @click="changeSum">点我sum加一</button>
        <button @click="changeHeight">点我height加一</button>
    </div>
</template>


<script setup lang="ts"> 
import {ref,watch,watchEffect} from 'vue' // watchEffect用来明确监视某个变量的变化

// 数据
let temp = ref(0)
let height = ref(0)

// 方法
function changeSum(){
    temp.value += 10
}

function changeHeight(){
    height.value += 10
}

// 监视 watch实现
watch([temp,height],(value)=>{
    let [newTemp,newHeight] = value

    if(newTemp > 100 || newHeight > 100){
        alert('当前温度或水位过高')
    } 
})


// 监视 watchEffect实现
watchEffect(()=>{
    if(temp.value > 100 || height.value > 100){
        alert('当前温度或水位过高')
    } 
})
</script>


标签的ref属性


注意:

  1. 可以用在普通的html标签上,也可以用在组件标签上
  2. 普通的 html 拿到的是 dom元素组件 拿到的是 组件实例对象
<template>
    <div class="person">
        <h2 ref="title2">中国</h2>   
        <h2>北京</h2>   
        <button @click="showLog">点我输出h2这个元素</button>
    </div>
</template>


<script setup lang="ts"> 
    import { ref,defineExpose } from 'vue'
    // 创建一个title2 ,用于存储ref标记的内容
    let title2 = ref()
    

    let a = ref()
    let b = ref()
    let c = ref()

    function showLog(){
        console.log(title2.value)
    }

    // 表示给父组件使用
    defineExpose({a,b,c})
</script>


自定义类型 接口 泛型 (ts)

// ts
// 定义一个接口,用于限制person对象的具体属性
export interface PersonInterFace {
  id:string
  name: string
  age: number
}

// 一个自定义类型 export用来交出去
export type PersonList = Array<PersonInterFace>

// vue
<script setup lang="ts"> 
	// 前面要加上type
    import {type PersonInterFace,type PersonList} from '@/types'

    // 限制类中的成员
    let person:PersonInterFace = {id:'ayusaaa',name:'张三',age:20}

    // 一个数组里面是PersonInterFace
    let personlist:PersonList = [
        {id:'ayusaaa',name:'张三',age:20},
        {id:'ayusaaa',name:'张三',age:20},
        {id:'ayusaaa',name:'张三',age:20}
    ]
</script>


Props的使用


// ts
// 定义一个接口,用于限制person对象的具体属性
export interface PersonInterFace {
  id:string
  name: string
  age: number
  // 在使用时加?表示可选属性
  num?:number
}

// 一个自定义类型 export用来交出去
export type PersonList = Array<PersonInterFace>

// vue
<template>
    <!-- :list 把personList当做一个变量 加上:就相当于表达式会做运算,否则就是字符串-->
    <Person a="hh" :list="personList" />
</template>

<script lang="ts" setup>
    import Person from './components/Person.vue'; // 枝
    import { ref } from 'vue';
    import { type PersonList } from './types';

    // ref可以通过传入泛型的方式来限制其中的属性成员
    let personList = ref<PersonList>([
        {id:'ayusaaa',name:'张三',age:20},
        {id:'ayusaaa',name:'张三',age:20},
        {id:'ayusaaa',name:'张三',age:20}
    ])
    
</script>

// App.vue
<template>
    <div class="person">
        <!-- <h2>{{ a }}</h2> -->
        <ul>
            <!-- :key就相当于去读取每个item中的唯一的id -->
            <!-- v-for不仅可以写数组还可以写次数 -->
            <li v-for="item in list" :key="item.id">{{ item }}</li>
        </ul>
    </div>
</template>

// Person.vue
<script setup lang="ts"> 
    import { defineProps,withDefaults } from 'vue'; // withDefaults默认值
    import { type PersonList } from '@/types';

    // 从外部组件接收一个对象a,list
    // defineProps(['a','list'])

    // 接收list,同时将props保存起来
    // let x = defineProps(['list'])

    // 接收list,同时限制类型
    // defineProps<{list:PersonList}>()

    // 接口list,同时限制类型,限制必要性,指定默认值
    withDefaults(defineProps<{list?:PersonList}>(),
        {
            // 设置默认认值
            list:()=> [{id:"aaa",name:'bbb',age:98}]
        }
    )
    
</script>


Vue的生命周期


组件的生命周期:

  1. 创建
  2. 挂载
  3. 更新
  4. 销毁

Vue2的生命周期:
4个接阶段,8个状态
创建(创建前 beforeCreate,创建完毕 created
挂载(挂载前 beforeMount,挂载完毕 mounted
更新(更新前 beforeUpdate,更新完毕 updated
销毁(销毁前 beforeDestroy,销毁完毕 destroyed

Vue3的生命周期:
4个接阶段,8个状态
创建(创建前 setup,创建完毕 setup
挂载(挂载前 onBeforeMount,挂载完毕 onMounted
更新(更新前 onBeforeUpdate,更新完毕 onUpdated
卸载(卸载前 onBeforeUnmount,卸载完毕 onUnmounted

父组件和子组件的生命周期 子组件优先执行,最后是父组件

<template>
    <div class="person">
        <h2>当前的求和为:{{ sum }}</h2>
        <button @click="sumAdd">+</button>
    </div>
</template>


<script setup lang="ts">
    import {ref,onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted} from 'vue'
    // 创建
    let sum = ref(0)

    // 方法
    function sumAdd(){
        sum.value += 1    
    }

    // 创建
    console.log('这里就是创建,setup就是在为我们做创建的工作')

    // 挂载前
    onBeforeMount(()=>{
        console.log("挂载前")
    })

    // 挂载完毕
    onMounted(()=>{
        console.log("挂载完毕")
    })

    // 更新前
    onBeforeUpdate(()=>{
        console.log('更新前')
    })

    // 更新完毕
    onUpdated(()=>{
        console.log('更新完毕')
    })

    // 卸载前
    onBeforeUnmount(()=>{
        console.log('卸载前')
    })

    // 卸载完毕
    onUnmounted(()=>{
        console.log('卸载完毕')
    })
</script>


自定义Hooks


命名规范:use后面跟功能名称

hooks就是把相同功能的方法和数据封装到一个文件中(可以是ts,也可以是js)

在这里插入图片描述
useDog.ts


import {ref} from 'vue'
import axios from 'axios'


export default function (){
    // 只包含和useDog相关的变量和方法
    let dogList = ref([
        'aaa'
    ])

    // 方法
    async function getDog(){
        let result = await axios.get('https://dog.ceo/api/breeds/image/random')
        dogList.value.push(result.data.message)
    }

    // 向外部提供数据
    return {
        dogList,
        getDog
    }
}

useSum.ts


import {ref} from 'vue'


export default function useSum(){
    // 数据
    let sum = ref(0)

    // 方法
    function sumAdd(){
        sum.value += 1    
    }

    return {
        sum,
        sumAdd
    }

    // 向外提供数据和方法
    return {sum,sumAdd}
}

在Person中就可以直接使用了

<script setup lang="ts">
	// 导入这两个文件
    import useDog from '@/hooks/useDog';
    import useSum from '@/hooks/useSum';

	// 可以直接调用这个方法来获取他导出的数据
    const { sum, sumAdd } = useSum();
    const { dogList, getDog } = useDog();
</script>


路由


路由的基本效果

注意点:
一般组件: 亲手写的标签出来的(一般放在components文件夹当中)
路由组件: 靠路由的规则渲染出来的(一般放在pages/views文件夹当中)

main.ts

// main.ts
// 引入crerateApp用来创建应用
import {createApp} from 'vue' 
// 引入App根组件
import App from './App.vue'
// 引入路由器
import router from './router'
// 创建一个应用
const app = createApp(App)
// 使用路由器
app.use(router)
// 挂载整个应用到app容器中
app.mount('#app')

App.vue

// App.vue
<template>
    <div class="app">
        <h2 class="title">Vue 路由测试</h2>
        <!-- 导航区-->
         <div class="navigate">
            <RouterLink to="/home" active-class="active">首页</RouterLink>
            <RouterLink to="news" active-class="active">新闻</RouterLink>
            <RouterLink to="/about" active-class="active">关于</RouterLink>
         </div>
        <!-- 展示区-->
        <div class="main-content"> 
            <RouterView></RouterView>
        </div> 
    </div>
</template>

<script lang="ts" setup>
    import { RouterView } from 'vue-router';
</script>

router.ts

//router.ts
// 引入 createRouter
import {createRouter,createWebHashHistory} from 'vue-router'

// 引入一个个可能创建的路由组件
import Home from '@/components/Home.vue'
import News from '@/components/News.vue'
import About from '@/components/About.vue'

// 创建路由器
const router = createRouter(
    {
        // 路由器的工作模式
        history:createWebHashHistory(),
        routes:[
            {
                path:'/home/',
                component:Home
            },
            {
                path:'/news/',
                component:News
            },
            {
                path:'/about/',
                component:About
            }
        ]
    }
)

// 暴露出去
export default router


路由器的工作模式


history模式

优点:URL更加美观,不带有#
缺点:后期项目上线,需要服务端配合处理路径问题,否则刷新会有404错误

const router = createRouter({
// history模式
	history:createWebHistory()
})

hash模式

优点:兼容性更好,不需要服务器端处理路径
缺点:URL带有#号,不太美观,并且在SEO优化方面相对较差

const router = createRouter({
// Hash模式
	history:createWebHashHistory()
})


to的两种写法


// 第一种:to的字符串
<RouterLink to="/home" active-class="active">首页</RouterLink>
// 第二种:to的对象
<RouterLink :to="{path:'/home'}" active-class="active">首页</RouterLink>


命名路由


// 通过名称来路由
...
{
	name:'zhuye',
	path:'/home/',
	component:Home
}
...
<RouterLink :to="{name:'zhuye'}" active-class="active">主页</RouterLink>


嵌套路由


// 创建路由器
const router = createRouter(
    {
        // 路由器的工作模式
        history:createWebHistory(),
        routes:[
            {
                name:'zhuye',
                path:'/home/',
                component:Home
            },
            {
                name:'xinwen',
                path:'/news/',
                component:News,
                children:[
                    {
                        path:'detail',
                        component:Detail
                    }
                ]
            },
            {
                path:'/about/',
                component:About
            }
        ]
    }
)


路由传参


注1:使用 params 参数时,若使用 ot 的对象写法,必须使用 name 配置项,不能使用 path
注2:使用 params 参数时,需要提前在规则中占位

路由的传参有两种形式

  • query
  • params

query的方式传参

// query第一种写法:
// 普通的传参方式
<RouterLink to="/news/detail?id=3&title=哈哈&content=无">{{ item.title }}</RouterLink>
// 使用模板字符串进行传参
<RouterLink :to="`/news/detail?id=${item.id}&title=${item.title}`">{{ item.title }}</RouterLink>

// query第二种写法:
<RouterLink 
:to="{
	path:'news/detail',
	query:{
		id:item.id,
		title:item.title
		}
	}"
>
	{{ item.title }}
</RouterLink>

params的方式传参

// params第一种的写法
// 这里的哈哈/嘿嘿/了了将做为参数进行传递
<RouterLink to="/news/detail/哈哈/嘿嘿/了了">{{ item.title }}</RouterLink>
 routes:[
            {
                name:'zhuye',
                path:'/home/',
                component:Home
            },
            {
                name:'xinwen',
                path:'/news/',
                component:News,
                children:[
                    {
                    	name:'xiangqin'
                        // 使用params的方式传参需要在这里进行占位,占位符可以是任意字符串
                        	(如果有些参数是可传可不传的可以在后面加个问号) 参数的必要性
                        path:'detail/:x/:y/:z?',
                        component:Detail
                    }
                ]
            },
            {
                path:'/about/',
                component:About
            }
        ]
        
// params第二种写法:
<RouterLink 
:to="{
	// 这里就不能用path来接收路由了,要使用name
    name:'xiangqin',
	query:{
		id:item.id,
		title:item.title
		}
	}"
>
	{{ item.title }}
</RouterLink>



路由的Props配置


{
	name:'xinwen',
	path:'/news/',
	component:News,
	children:[
			{
			name:'xiangqin',
			// 使用params的方式传参需要在这里进行占位,占位符可以是任意字符串
			path:'detail/:x/:y/:z',
			component:Detail,
			// 第一种写法 表示直接把path上的占位符参数给传递过去(只能处理params参数)
			props:true
			// 第二种写法 函数写法,可以自己决定将什么作为props给路由组件
			props(route){
				return route.query
			}
			// 第三种写法 对象写法,可以自己决定将什么作为props给路由组件
			props:{
				a:100,
				b:200,
				c:300
			}
			}
	]
},

<template>
    <ul class="news-list">
        <li>{{ x }}</li>
        <li>{{ y }}</li>
    </ul>
</template>


<script setup lang="ts" name="Detail">
    //这里就可以使用defineProps来接收
    defineProps(['x','y','z'])
</script>


路由replace属性


路由默认每次跳转都是push的模式

			// 在RouterLink  上添加replace就把push改为replace模式了
	        <RouterLink  replace to="/home" active-class="active">首页</RouterLink>
            <RouterLink  replace :to="{name:'xinwen'}" active-class="active">新闻</RouterLink>
            <RouterLink  replace :to="{path:'/about'}" active-class="active">关于</RouterLink>


编程式路由导航


简单写法

	<script setup lang="ts" name="Home">
	    import {onMounted} from "vue";
	    import {useRouter} from "vue-router";
	    
	    const router = useRouter();
	
	    onMounted(()=>{
	        setTimeout(()=>{
	        	// 通过路由属性中的push进行跳转
	            router.push("/news");
	        },3000)
	    })
	</script>

对象写法

		<script setup lang="ts" name="Home">
	    import {onMounted} from "vue";
	    import {useRouter} from "vue-router";
	    
	    const router = useRouter();
	
	    function showNewDetail(new:any){
			router.push({
				name:'xing',
				query:{
					new.id,
					new.title,
					new.content
				}
			})
		}
	</script>


路由重定向


在路由规则最后一个加上

	{
		path:'/',
		// 重定向
		redirect:'/home/'
	}


Pinia


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值