目录
路由配置
路由配置基本相同不过在路由守卫中需要引入以下为例
import {
createWebHashHistory, createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
import Home from '../views/Home.vue'
import Layout from "../views/Layout/Layout.vue"
// 路由正常配置
{
path: '',
component: Layout,
children: [
{
path: '',
name: 'Home',
component: Home,
meta: {
title: "首页",
parentpath: '/'
}
},
{
path: '/',
redirect: '/home'
}, {
path: '/Strategy',
name: 'Strategy',
component: () => import('../views/Strategy/Strategy.vue'),
meta: {
title: "旅游攻略",
parentpath: '/Strategy'
}
}, {
path: '/hotel',
name: 'hotel',
component: () => import('../views/Hotel/Hotel.vue'),
meta: {
title: "酒店",
parentpath: '/hotel'
}
},],
},
//决定路由模式
const isPro: boolean = process.env.NODE_ENV === 'production'
const router = createRouter({
//history是路由模式
history: isPro ? createWebHashHistory(process.env.BASE_URL) : createWebHistory(process.env.BASE_URL),
routes
})
router.beforeEach((to, from, next) => {
document.title = to.meta.title
next()
})
封装请求
import {
message } from 'ant-design-vue' //按需引入(提示)
import axios, {
AxiosInstance, AxiosRequestConfig, AxiosError, AxiosResponse } from 'axios'
import nprogress from 'nprogress' //请求进度条(动画效果)
import 'nprogress/nprogress.css'
const service: AxiosInstance = axios.create({
baseURL: '/api',
timeout: 10000
})
service.interceptors.request.use((config: AxiosRequestConfig): AxiosRequestConfig => {
nprogress.start()
return config
}, (err: AxiosError) => {
nprogress.done()
console.log(err)
return Promise.reject(err)
})
service.interceptors.response.use((res: AxiosResponse): AxiosResponse => {
nprogress.done()
return res.data
}, (err: AxiosError) => {
nprogress.done()
if (err.response && err.response.status) {
let status = err.response.status
console.log(err.response, "7877789");
if (status === 400) {
//如果请求错误为400的话会有提示
message.error(err.response.data.message)
}
}
})
export default service
封装api
import service from './index' //引入封装的axios文件
const token = localStorage.getItem('token') //按需使用
export default {
//文章列表
articleList({
city }: {
city: number | string }) {
//没个参数都需要定义类型
if (city) {
return service.get(`posts?city=${
city}`) }
else {
return service.get(`posts`) }
},
//验证码
Accont({
tel }: {
tel: string | number }) {
return service.post(`captchas`, {
tel })
},
}
定义axios的接收数据类型
在src根目录下定义一个axios.d.ts文件,其中内容如下,里面放请求后拿到的所有的数据的数据类型
import * as axios from 'axios'
declare module 'axios' {
interface AxiosResponse<T> {
data?: T,
total?: number,
code?: string,
token?: string,
user?: any,
message?: string,
data?: object,
total?: number,
}
}
Ant图标的使用
main.ts中代码如下
import {
createApp } from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import Antd from 'ant-design-vue';
import 'ant-design-vue/dist/antd.css';
import * as Icons from '@ant-design/icons-vue'; //全局引入
const app = createApp(App);
app.use(store);
app.use(router).mount('#app');
app.use(Antd)
const icons: any = Icons;
for (let i in icons) {
//循环注册
app.component(i, icons[i]);
}
使用时候需注意
import api from "../../http/api";
import {
Form } from "ant-design-vue/types/form/form";
import {
defineComponent,reactive,toRefs,SetupContext,onMounted} from "vue";
import {
message } from "ant-design-vue";
import {
useRoute, useRouter } from "vue-router";
interface Data {
//定义data中的数据类型
form: formitem;
SpecialAir: [];
addomg: additem[];
data: [];
data1: [];
}
onMounted(() => {
//同2.0中的mounted
});
let back = () => {
message.warning("目前暂不支持往返,请使用单程选票!");
};
每个事件都需要return出去
return {
...toRefs(data),
back,
};
跳转路由
import {
useRoute, useRouter } from "vue-router"; //先引入
let router = useRouter();
let buy = (item: any) => {
console.log(item);
router.push({
path: "/ticket",
query: {
item: JSON.stringify(item), //如果不是字符串类型的话需要转换一下
},
});
跳转路由(接受传值)
data.departCity = JSON.parse(route.query.item as string).departCity;
});
拿到路由中meta定义的内容(常用来设置侧边栏)
<a-menu id="dddddd" v-model:selectedKeys="selectedKeys" theme="light">
<a-menu-item
v-for="item in $router.options.routes[0].children"
:key="item.path"
@click="goto(item.path)"
>
<component :is="item.meta.icon"></component>
<span>{
{
item.meta.title }}</span>
</a-menu-item>
</a-menu>
import {
useRoute, useRouter } from "vue-router";
setup(props, ctx: SetupContext) {
let router = useRouter();
return {
...toRefs(data),
goto,
};
}
计算属性
let userinfow = computed(() => {
return store.state.userinfo; //vuex中的数据
});
动态绑定class
<div
class="left"
:class="{shine:$route.meta.parentpath===item.path}" //shine为类名
v-for="(item,index) in top "
:key="index"
@click="goto(item)"
>{
{
item.name}}</div>
动态绑定style
<div:style="`background: url(${item.url}) center center no-repeat`"></div>
使用vuex
import {
useStore } from "vuex"; //引入
let store = useStore(); //创建实例
let registeredall = () => {
api
.registered()
.then((res: Res) => {
if (res.token) {
store.commit("setuserinfo", res.user); //调用vuex中的方法去改变数据
}
})
.catch((err: any) => {
console.log(err);
});
};
vuex中
import {
createStore } from 'vuex'
export default createStore({
state: {
userinfo: null || JSON.parse(localStorage.getItem('user')!)
},
mutations: {
setuserinfo(state, data) {
state.userinfo = data
}
},
actions: {
},
modules: {
}
})
注册子组件
<template>
<Top></Top>
<Bottom></Bottom>
</template>
import Top from "../../components/layout/Top.vue";
import Bottom from "../../components/layout/Bottom.vue";
<script lang='ts'>
export default defineComponent({
components: {
Top,
Bottom,
},
用ref表单验证
<a-form
name="custom-validation"
style="margin-top: 20px"
ref="shin"
:model="ruleForm"
:rules="rules"
>
<a-form-item
required
label="姓名"
name="checkPass"
style="display: flex; width: 80%"
>
<a-input
v-model:value="ruleForm.checkPass"
style="margin-right: 0px; width: 125%; margin-top: 15px"
autocomplete="off"
/>
</a-form-item>
</a-form>
import {
Form } from "ant-design-vue/types/form/form";
setup(props, ctx: SetupContext) {
let shin = ref<Form | null>(null); //shin为ref的名字 创建实例
let info = () => {
shin.value!.validate().then((res: any) => {
//当表单验证成功时才会执行后面then中代码
router.push("/");
});
};
}