Vue3.0-04Vue+TS编程
再公司开发用到Vue3.0这个版本。
Vue3.0+JavaScript来进行开发:
Vue3.0+TypeScript来进行开发:语言检测、语法要求严格一些。 一、项目搭建
还是使用vite来搭建我们的项目。
yarn create vite
选中创建的项目Vue
选择创建项目vue-ts这个选项 二、搭建项目路由
创建项目的时候,有没有让你选择路由。
默认创建项目,没有路由配置、也没有状态机配置 搭建路由环境非TS约束
下载路由
npm i vue-router@next
@next代表目前下载最新版本路由
创建路由文件
src目录下面创建router/index.ts文件,这就是路由配置文件
import {createRouter,createWebHistory,createWebHashHistory} from "vue-router"
import Login from "../views/Login.vue"
import Register from "../views/Register.vue"
import Home from "../views/Home.vue"
const routes = [
{
path:"/login",
component:Login
},
{
path:"/register",
component:Register
},
{
path:"/home",
component:Home
}
]
const router = createRouter({
//映射关系
routes,
//路由模式
history:createWebHistory()
})
export default router
main.ts文件中加载路由配置
import { createApp } from 'vue'
import App from './App.vue'
import router from "./router"
const app = createApp(App);
// 挂载router
app.use(router)
// 将app实例挂载到页面上面
app.mount('#app');
将index.ts文件放在main.ts加载。
再App.vue组件中渲染路由出口
<template>
<!-- <HelloWorldVue :msg="msg"></HelloWorldVue>
<h2>App</h2> -->
<!-- 路由渲染出口 -->
<router-view></router-view>
</template>
搭建路由TS版本
我们需要针对routes进行路由配置
import {createRouter,createWebHistory,createWebHashHistory,RouteRecordRaw} from "vue-router"
RouteRecordRaw:路由的约束接口。不需要你们自己写
你们也可以自己写interface,必须要提供完善的信息
// interface IRouter {
// path: string,
// component?: Component,
// name?: string, // 命名路由
// components?: { [name: string]: Component }, // 命名视图组件
// redirect?: string | Location | Function,
// props?: boolean | Object | Function,
// alias?: string | Array<string>,
// children?: Array<IRouter>, // 嵌套路由
// meta?: any
// }
代码中
const routes:Array<RouteRecordRaw> = [
{
path:"/login",
component:Login,
name:"Login",
},
{
path:"/register",
component:Register
},
{
path:"/home",
component:Home,
}
]
Array:代表的是数组类型,数组使用RouteRecordRaw类约束数据 路由跳转
Vue3里我们路由跳转无法使用this.$routerl来执行
需要使用Vue提供的hook来进行跳转
import {useRoute,useRouter} from "vue-router"
const router = useRouter()
const route = useRoute()
useRouter:相当于以前的this.$router
useRoute:相当于以前的this.$route
router.push("/路径")
三、组件内部数据
回顾再Vue3中定义数据有两种方式
import {ref,reactive} from "vue"
const count = ref(0)
const state = reactive({
username:"xiaowang",
classes:[]
})
官方推出两种方式都可以定义数据,习惯于ref用于定义基础数据类型,reactive定义复杂的数据类型 ref定义数据
我们可以使用它泛型来规定我们德数据格式
const count = ref<number>(0)
const user = ref<IUser>({id:"123",name:"xiaowang"})
const students = ref<Array<IUser>>([{id:1,name:"xiaofeifei"}])
一旦设置了泛型,那就意味着我们这个变量的类型已经确定
项目中以后有很多的约束条件,我们需要将这些内容单独提取到文件中
再src目录下面types/user-type.ts
export interface IUser {
id: string | number,
name: string
}
项目中引入约束
import {IUser} from "../types/user-types"
const count = ref<number>(0)
const user = ref<IUser>({id:"123",name:"xiaowang"})
const students = ref<Array<IUser>>([{id:1,name:"xiaofeifei"}])
reactive定义数据
我们可以使用一个reactive定义很多个数据
import {IUser,IStudent} from "../types/user-types"
const state = reactive<{username:string,student:Array<IStudent>}>({
username:"xiaowang",
student:[
{id:1,address:"武侯区"}
]
})
你需要再reactive函数后面加上泛型约束,。提供的一个对象,因为我们reactive里面有很多数据需要约束 四、配置vscode模块
找到vscode文件。
选择【首选项】—【用户片段】
新建全局代码片段,输入一个vue3名字,自动给你创建文件。vue3.xxxx.json
将以下内容赋值到json文件中
{
"Print to console": {
"prefix": "vue3",
"body": [
"<template>",
" <div></div>",
"</template>",
"",
"<script lang='ts' setup>",
"import { reactive,ref} from 'vue'",
"</script>",
"",
"<style lang='less' scoped>",
"</style>"
],
"description": "Log output to console"
}
}
再页面上vue3就可以提示你快捷创建模板
五、组件通信
回顾Vue3里面组件通信如何实现的
const props = defineProps({
msg:Number
})
const emit = defineEmits()
emit("自定义事件名字",传递的参数)
在TS版本中我们需要操作的通信 父组件传递给子组件
父组件
<HeaderVue :count="count" msg="小王"></HeaderVue>
const count = ref<number>(10)
子组件
<template>
<div>
<h2>Header组件</h2>
<p>{{count}}</p>
<p>{{msg}}</p>
</div>
</template>
<script lang='ts' setup>
import { reactive,ref} from 'vue'
defineProps<{count:number,msg:string}>()
</script>
我们需要defineProps函数定义泛型 子组件传递参数给父组件
const emit = defineEmits<
{
(e:"getChildrenValue",val:number):void,
(e:"changeCount",val:string):void,
}
>()
const changeCount = ()=>{
// emit("getChildrenValue",20)
emit("changeCount","xiaowang")
}
emit这个函数在执行的过程中能够传递哪些参数,在泛型里面已经决定了。 六、antd组件库使用
Vue3的项目中要使用antd,我们需要下载依赖,引入到项目中使用
下载依赖
yarn add ant-design-vue
main.ts文件中引入antd,并将antd挂载到Vue实例身上
import Antd from "ant-design-vue"
import "ant-design-vue/dist/antd.css"
app.use(Antd)
打开antd官网,针对Vue版本
地址:https://www.antdv.com/components/button-cn
在使用过程中很多组件都提供了ts版本的代码。你们使用的时候,自己区分一下
七、项目中使用less来开发
我们需要下载对应的依赖
yarn add less less-loader@7.x --dev
npm install less less-loader@7.x --save-dev
开发依赖。
你可以在组件中给style标签新增lang=”less“
<style lang='less' scoped>
.box{
width: 100px;
height: 100px;
background-color: tomato;
span{
color: white;
}
}
</style>
八、网络请求
Vue3里面发送网络请求还是基于axios工具来完成
下载依赖
不用指定版本,直接下载默认版本
yarn add axios
src目录下面创建request文件夹 api.ts文件
import axios from "axios";
const newAxios = axios.create({
baseURL:"http://127.0.0.1:8002/",
timeout:3000
})
// 请求拦截器
newAxios.interceptors.request.use((req)=>{
// 给req设置请求头.token
// 在req这个对象无法获取到headers,默认返回一个对象
req.headers = req.headers || {}
req.headers.token = localStorage.getItem("token") || ""
return req
})
// 响应拦截器
newAxios.interceptors.response.use((response)=>{
return response
},(error)=>{
const response = error.response;
if(response){
switch(response.status){
case 401:
alert("身份过期请重新登录")
window.location.href="/login"
break;
default:
alert("服务器有问题")
}
}
})
export default newAxios
请求拦截器里面设置headers可能会抛出异常,可以解决一下这个异常。
九、Vuex使用
默认项目里面是没有Vuex,我们需要自己搭建这个环境
下载依赖
yarn add vuex@next
在项目src目录项目store文件夹,index.ts 文件
import {createStore} from "vuex"
const store = createStore({
state:{
username:"xiaowang",
users:[
{id:1,name:"xiaofei"}
]
},
getters:{
},
mutations:{
},
actions:{
},
modules:{
}
})
export default store;
在main.ts文件中加载store仓库
import { createApp } from 'vue'
import App from './App.vue'
import router from "./router"
import Antd from "ant-design-vue"
import "ant-design-vue/dist/antd.css"
import store from "./store"
const app = createApp(App);
// 挂载router
app.use(router)
app.use(Antd)
app.use(store)
// 将app实例挂载到页面上面
app.mount('#app');
页面上使用仓库数据
vuex给我们提供了一个新的hook函数 useStore
import {useStore} from "vuex"
const store = useStore()
<p>{{store.state.username}}</p>
修改仓库数据
调用mutations方法来修改。mutations定义修改方法
import {createStore} from "vuex"
const store = createStore({
state:{
username:"xiaowang",
users:[
{id:1,name:"xiaofei"}
]
},
mutations:{
changeUsername(state,payload){
state.username = payload
}
},
})
export default store;
页面上
store.commit("changeUsername","xiaofeifei")
异步修改,调用actions里面方法执行修改
import {createStore} from "vuex"
const store = createStore({
state:{
username:"xiaowang",
users:[
{id:1,name:"xiaofei"}
]
},
actions:{
asyncChangeUsername(context,payload){
setTimeout(() => {
//调用mutation方法修改数据
context.commit("changeUsername",payload)
// context.state.username = payload
}, 1000);
}
},
})
export default store;
页面上
store.dispatch("asyncChangeUsername","xiaofeifei2")
如果你的vuex仓库分了模块,调用指定模块里面的函数或获取数据
store.state.命名空间.username
store.commit("命名空间/函数名字")
store.dispatch("命名空间/函数名字")
Vuex数据采用TS约束
import {createStore} from "vuex"
interface IState {
username:string,
users:Array<IUser>
}
interface IUser {
id:number,name:string
}
const store = createStore<IState>({
state:{
username:"xiaowang",
users:[
{id:1,name:"xiaofei"}
]
},
getters:{
},
mutations:{
changeUsername(state,payload){
state.username = payload
}
},
actions:{
asyncChangeUsername(context,payload){
setTimeout(() => {
//调用mutation方法修改数据
context.commit("changeUsername",payload)
// context.state.username = payload
}, 1000);
}
},
modules:{
}
})
export default store;
十、生命周期
在Vue3里生命周期函数跟以前有比较大的区别。 选项式 API Hook inside setup beforeCreate Not needed created Not needed beforeMount onBeforeMount mounted onMounted beforeUpdate onBeforeUpdate updated onUpdated beforeUnmount onBeforeUnmount unmounted onUnmounted errorCaptured onErrorCaptured renderTracked onRenderTracked renderTriggered onRenderTriggered
Vue3里生命周期函数需要引入过后才能用
import { onMounted, reactive, ref } from 'vue';
onMounted(()=>{
console.log(123);
fetchData()
})
生命周期函数需要我们传递一个回调函数,执行页面对应的时间段,调用这个函数