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 = 18let 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 = 29let 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中操作响应式数据要加上.valuename.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包一下// 可以使用reflet 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 = str1lastName.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] = valueif(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:stringname: stringage: number
}// 一个自定义类型 export用来交出去
export type PersonList = Array<PersonInterFace>// vue
<script setup lang="ts"> // 前面要加上typeimport {type PersonInterFace,type PersonList} from '@/types'// 限制类中的成员let person:PersonInterFace = {id:'ayusaaa',name:'张三',age:20}// 一个数组里面是PersonInterFacelet 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:stringname: stringage: 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来接收路由了,要使用namename:'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


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1542096.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Windows安装Oracle11gR2(图文教程)

本章教程&#xff0c;记录在Windows10上安装Oracle11gR2过程。 一、下载安装包 通过网盘分享的文件&#xff1a;oracle11g 链接: https://pan.baidu.com/s/15ilciQ5NlKWtClklmdAH_w?pwds4dd 提取码: s4dd 二、下载并解压文件 将网盘中的安装包文件下载到本地&#xff0c;在此之…

心觉:感恩何其重要,感恩之心如何培养

Hi&#xff0c;我是心觉&#xff0c;与你一起玩转潜意识、脑波音乐和吸引力法则&#xff0c;轻松掌控自己的人生&#xff01; 挑战每日一省写作177/1000天 上篇文章我们讲了保持感恩之心&#xff0c;可以吸引更多的机会和财富 但是现实中很多人是缺乏感恩之心 这是由于他们…

c++day3 手动封装一个顺序表(SeqList),分文件编译实现

要求: 有私有成员&#xff1a;顺序表数组的起始地址 ptr、 顺序表的总长度&#xff1a;size、顺序表的实际长度&#xff1a;len 成员函数&#xff1a;初始化 init(int n) 判空&#xff1a;empty 判满&#xff1a;full 尾插&#xff1a;push_back 插入&#xff1a;insert&…

进程间的通信4 共享内存

共享内存 1.共享内存简介 共享内存是将分配的物理空间直接映射到进程的用户虚拟地址空间中&#xff0c;减少数据在内核空间缓存共享内存是一种效率较高的进程间通讯的方式在 Linux 系统中通过 ipcs -m 查看所有的共享内存 共享内存模型图 2.共享内存的创建 1.函数头文件 #…

【如何在 Windows 10 主机上通过 VMware 安装 Windows 11 虚拟机,并共享主机网络】

环境说明 主机操作系统&#xff1a;Windows 10虚拟机操作系统&#xff1a;Windows 11虚拟机软件&#xff1a;VMware 步骤一&#xff1a;确保主机&#xff08;Windows 10&#xff09;网络连接正常 启动网络加速软件&#xff1a;在主机上启动软件&#xff0c;确保主机可以正常访…

JavaEE: 深入探索TCP网络编程的奇妙世界(三)

文章目录 TCP核心机制TCP核心机制三: 连接管理建立连接(三次握手)断开连接(四次挥手)三次握手/四次挥手 流程简图 TCP核心机制 书接上文~ TCP核心机制三: 连接管理 建立连接(三次握手),断开连接(四次挥手). 这里的次数指的是网络通信的次数,挥手/握手是形象的比喻(handshake…

基于SpringBoot+Vue的智慧物业管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目源码、Python精…

SpringBoot3核心特性-核心原理

目录 传送门前言一、事件和监听器1、生命周期监听2、事件触发时机 二、自动配置原理1、入门理解1.1、自动配置流程1.2、SPI机制1.3、功能开关 2、进阶理解2.1、 SpringBootApplication2.2、 完整启动加载流程 三、自定义starter1、业务代码2、基本抽取3、使用EnableXxx机制4、完…

SaaS软件的配置化平台是如何实现个性化定制的?

SaaS&#xff08;Software as a Service&#xff0c;软件即服务&#xff09;是一种通过互联网提供软件的模式&#xff0c;用户无需安装和维护任何复杂的基础设施&#xff0c;只需通过网络连接即可使用软件。SaaS 供应商负责软件的维护、升级和可用性&#xff0c;用户则通过订阅…

智能体时代,AI正从“神坛”走向“人间”

从通用大模型到行业大模型&#xff1a;AI智能体引领新风口 在人工智能领域&#xff0c;一场深刻的变革正悄然发生。从昔日高高在上的通用大模型&#xff0c;到如今愈发接地气的行业大模型&#xff0c;AI的风向标已经鲜明地指向了AI智能体&#xff08;AI Agent&#xff09;&…

APO v0.4.0 发布:新增影响面分析;新增调用数据库指标;优化告警事件关联展示

APO 新版本 v0.4.0 正式发布&#xff01;本次更新主要包含以下内容&#xff1a; 新增影响面分析&#xff0c;识别服务端点对服务入口的影响 服务入口是指业务被访问时调用的第一个服务端点&#xff0c;在调用拓扑图中处于最上游。服务入口直接反映了系统对外提供服务的状态&a…

基于SpringBoot+Vue+MySQL的手机销售管理系统

系统展示 用户前台界面 管理员后台界面 商家后台界面 系统背景 随着智能手机的普及和市场竞争的日益激烈&#xff0c;手机销售行业面临着前所未有的挑战与机遇。传统的手工记录和简单的电子表格管理方式已难以满足现代手机销售业务的需求&#xff0c;销售数据的混乱和管理效率低…

(done) 声音信号处理基础知识(2) (重点知识:pitch)(Sound Waveforms)

来源&#xff1a;https://www.youtube.com/watch?vbnHHVo3j124 复习物理知识&#xff1a; 声音由物体的振动产生 物体振动会导致空气分支振荡 某一处的空气气压变化会创造一个波 声音是机械波 空气的振荡在空间中传递 能量从空间中的一个点到另一个点 机械波需要媒介&#x…

DBNet 博客转载

论文地址&#xff1a;https://arxiv.org/abs/1911.08947 最后的文字概率还需要扩张d https://blog.csdn.net/weixin_46505265/article/details/134836652 https://paddlepedia.readthedocs.io/en/latest/tutorials/computer_vision/OCR/OCR_Detection/DBNet.html

ThreadLocal与AsyncLocal

简介 ThreadLocal 用于在多线程环境中创建线程局部变量&#xff0c;可以让每个线程独立地访问自己的变量副本&#xff0c;互不影响。 而 AsyncLocal 是 ThreadLocal 的异步版本&#xff0c;专门用于异步编程场景&#xff0c;在异步操作中它可以正确处理上下文切换。 ThreadLo…

【Python】探索 Elpy:Emacs 中的 Python 开发环境

可以短时间不开心&#xff0c;但别长时间不清醒。 对于使用 Emacs 编辑器的 Python 开发者来说&#xff0c;Elpy 是一个强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;它通过整合多个 Emacs Lisp 和 Python 包&#xff0c;提供了一套完整的 Python 编程支持。本文…

MySQL基础篇的补充

前言&#xff1a; 查询语句的书写顺序 select > from > where > group by > having > order by > limit 查询语句的执行顺序 from > where > group by > having > select > order by > limit 这个很重要&#xff0c;提前再复习一下。…

vue入门小练习

文章目录 1.案例需求2.编程思路3.案例源码4.小结 1.案例需求 一个简易的计算器&#xff0c;其效果如下&#xff1a; 图片切换&#xff0c;其效果如下&#xff1a; 简易记事本&#xff0c;其效果如下&#xff1a; 2.编程思路 1.这个Vue.js应用实现了一个简单的计算器&#x…

检索索引对象中的重复值、删除重复值pandas.Index.duplicated

【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 检索索引对象中的重复值、删除重复值 pandas.Index.duplicated [太阳]选择题 根据代码&#xff0c;下列哪个选项正确表示了去重后的结果&#xff1f; import pandas as pd idx pd.Index([1,…

图书管理系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;图书分类管理&#xff0c;图书信息管理&#xff0c;我的待还处管理&#xff0c;图书归还管理&#xff0c;催还提醒管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统…