创建项目
js
// 使用vite创建项目, 并指定模板为vue
npm create vite@latest vue-app -- --template vue
// 执行上面命令后,控制台会输出下面三句话
cd vue-app // 进行项目文件夹
npm install // 安装项目依赖 网络不好的可以尝试使用 yarn 或 cnpm
npm run dev // 运行项目
执行完以上命令后 你将会看到一下页面
下面们来看看项目的代码, 在编辑器里打开后会呈现如下的文件目录
其中我们最关心的红色部分
node_modules
里存放的全是项目依赖 通过npm install安装的都会在里面,public
存放的是静态文件 如 index.html 图片等文件assets
里放静态资源 图片 图标 等components
存放的是我们项目里的vue 组件app.vue
项目跟组件 最先加载的组件main.js
项目入口文件 主要用于启动插件vite.config.js
vite的配置 项目打包配置时有用
下面我们来看项目入口文件,和根组件
main.js
app.vue
使用路由
首先我们安装路由
js
npm install vue-router@4 //网络不好可以使用 yarn add vue-router@4 或 cnpm
使用路由
- 在scr下创建views文件夹, 在views下创建两个vue文件, 就是路由跳转匹配的页面
- 首先在src文件夹下创建router文件夹, 然后再router 文件夹下创建 index.js
- 在index.js编写路由规则 在文件里我们写了两个路由 / 和 /about 并使用createWebHashHistory方式加载路由 这里我我们使用了
import.meta.glob('../views/**/*.vue')
的方式去加载组件
js
import { createRouter, createWebHashHistory } from 'vue-router'
const routerFile = import.meta.glob('../views/**/*.vue')
const routes = [
{
path: "/",
component: () => routerFile['../views/home.vue']()
},
{
path: "/about",
component: () => routerFile['../views/about.vue']()
}
]
// 导出router 在main里给vue使用
export const router = createRouter({
history: createWebHashHistory(),
routes
})
expoer funtion setupRouter(app){
app.use(router)
router.isReady()
}
- 在main.js 里使用路由
js
import { createApp } from 'vue'
import { setupRouter } from './router/index.js' // 引入 router 导出
import './style.css'
import App from './App.vue'
const app = createApp(App)
setupRouter(app)
app.mount("#app")
- 在app跟组件里来接受路由
js
<template>
<p>
<router-link to="/">Home</router-link>
/
<router-link to="/about">About</router-link>
</p>
<router-view></router-view>
</template>
<script setup>
</script>
以上就实现了最简单的路由匹配, 让我们来查一下效果吧
使用antd
安装antd
js
npm install ant-design-vue@4.x --save
// 或者
yarn add ant-design-vue@4.x
如何使用,在main.js里引入 并use(antd), 这里是全局注册,要按需注册,需引入所需组件使用即可
js
import { createApp } from 'vue';
import Antd from 'ant-design-vue';
import App from './App';
import 'ant-design-vue/dist/reset.css';
const app = createApp(App);
app.use(Antd)
app.mount('#app');
更多antd 用法请参考antdv官网 各种组件用法例示都有
antd layout布局
1 首先写出layout 组件, 在components下 新建layout文件夹, 创建 index.js 以及两个组件 登录layout 和 main layout 代码如下
index.js
js
import MainLayout from './mainLayout.vue'
import LoginLayout from './loginLayout.vue'
export function setupLayout(app){
app.component('MainLayout', MainLayout)
app.component('LoginLayout', LoginLayout)
}
mainLayout.vue
js
<template>
<a-layout style="height: 100vh;">
<a-layout-header :style="headerStyle">顶部区域</a-layout-header>
<a-layout>
<a-layout-sider :style="siderStyle">菜单区域</a-layout-sider>
<a-layout-content :style="contentStyle">
<router-view></router-view>
</a-layout-content>
</a-layout>
<a-layout-footer :style="footerStyle">底部区域</a-layout-footer>
</a-layout>
</template>
loginLayout.vue
js
<template>
<a-layout class="main-container">
<router-view></router-view>
</a-layout>
</template>
完成以上步骤后 在main.js 里引入并使用 layout 代码如下
js
import { createApp } from 'vue' // 引入vue启动函数
import { router } from './router/index.js'
import Antd from 'ant-design-vue';
import { setupLayout } from './components/layout/index.js'
import './style.css'
import 'ant-design-vue/dist/reset.css';
// 引入App组件
import App from './App.vue'
const app = createApp(App)
// 使用引入的layout
setupLayout(app)
app.use(router)
app.use(Antd)
app.mount("#app")
下面还需要配置两处地方,才可以产生效果 app.vue 和 router下面的index.js
app.vue 修改后
js
<template>
<component :is="componentId">
<router-view></router-view>
</component>
</template>
<script lang="ts" setup>
import { computed } from 'vue'
import { useRoute } from 'vue-router';
const route = useRoute()
const componentId = computed(() => {
return route.meta.layout || 'div'; // 默认情况下使用一个 div 包裹
});
</script>
router/ index.js
js
import { createRouter, createWebHashHistory } from 'vue-router'
const routeFiles = import.meta.glob('../views/**/*.vue')
const routes = [
{
path: "/",
name: 'index',
meta:{
layout: 'MainLayout'
},
component:() => routeFiles['../views/home.vue']()
},
{
path: "/login",
name: 'login',
meta:{
layout: 'LoginLayout'
},
component:() => routeFiles['../views/login/index.vue']()
},
{
path: '/about',
name: 'about',
meta:{
layout: 'MainLayout'
},
component:() => routeFiles['../views/about.vue']()
}
]
export const router = createRouter({
history :createWebHashHistory(),
routes
})
效果: 通过加载不同的路由就实现了 加载不同的layout
使用pinia
安装pinia
js
npm install pinia
或者
yarn add pinia
在src文件夹下创建 store, 在store下创建index.js 和 modules文件夹,在modules下创建 index.js 和user文件夹然后在 user下在创建user.js
store下的index.js
创建pinia 导入modules下的store
js
import { createPinia } from "pinia";
const store = createPinia()
export function setupStore(app) {
app.use(store)
}
export * from './modules'
modules下的index.js
导出store 如果后续有多少store 就导出多少
js
export * from './user/user'
user.js
这里创建了一个存储token的store
js
import { defineStore } from "pinia"
const LOCAL_NAME = 'token'
function getToken(){
return localStorage.getItem(LOCAL_NAME)
}
function setToken(token){
localStorage.setItem(LOCAL_NAME, token)
}
export const userStore = defineStore("user", {
state: () => getToken(),
getters: {
getToken: (state) => state.token
},
actions: {
setToken(token){
this.token = token
setToken(token)
}
}
})
在main.js里注册store
js
import { setupStore } from './store/index.js'
const app = createApp(App)
setupStore(app);
app.mount("#app")
使用
js
<template>
<div>
我是home页面
<a-button type="primary" @click="setToken">存储token</a-button>
<a-button type="primary" @click="getToken">获取token</a-button>
{{ T }}
</div>
</template>
<script setup>
import { ref } from 'vue'
import { useUserStore } from '../store/index.js'
const T = ref("")
const userStore = useUserStore()
const setToken = () => {
userStore.setToken("122121")
}
const getToken = () =>{
T.value = userStore.getToken
}
</script>
登录页面
html
js
<template>
<div class="login">
<div class="login-header">
<span>vue后台管理系统</span>
</div>
<div class="login-conent">
<div class="login-conent-form">
<a-form
:model="formState"
name="basic"
:label-col="{ span: 4 }"
:wrapper-col="{ span: 20 }"
autocomplete="off"
@finish="onFinish"
>
<a-form-item
label="用户名"
name="username"
:rules="[{ required: true, message: 'Please input your username!' }]"
>
<a-input v-model:value="formState.username" />
</a-form-item>
<a-form-item
label="密码"
name="password"
:rules="[{ required: true, message: 'Please input your password!' }]"
>
<a-input-password v-model:value="formState.password" />
</a-form-item>
<a-form-item>
<a-button type="primary" html-type="submit">登录</a-button>
</a-form-item>
</a-form>
</div>
</div>
<div class="login-footer">
</div>
</div>
</template>
vue
js
import { reactive, nextTick} from 'vue';
import { router } from '../../router/index'
import { useUserStore } from '../../store/index'
interface FormState {
username: string;
password: string;
remember: boolean;
}
const formState = reactive<FormState>({
username: 'admin',
password: 'admin',
remember: true,
});
const userStore = useUserStore()
const onFinish = async (values: any) => {
// 调用登录接口
// 登录成功后 处理用户token 用户信息 后并路由跳转
await userStore.setToken("token")
nextTick(() =>{
router.push("/")
})
};
beforeEach 判断用户是否登录 如果登录 存在用户token 直接进入页面 如果未登录 进入登录页面 在router文件夹下新建 guard.js 代码如下
js
import { message } from 'ant-design-vue'
import { useUserStore } from '../store/index'
import { store } from '../store/index'
const passPath = ["/login"]
const userStore = useUserStore(store)
export function setupPageGuard(router){
router.beforeEach( async (to, form, next) =>{
if(passPath.includes(to.path)){
next()
}else{
if(!userStore.getToken){
message.success("请先登录")
next('/login')
}else{
next()
}
}
})
}
使用guard.js
js
import { setupPageGuard } from './guard'
setupPageGuard(router)
这样就完成登录了