一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情。
第一步vite 初始化项目
vite官网
使用npm
npm init vite@latest
使用yarn
yarn create vite
使用pnpm
pnpx create-vite
输入项目名称:vue3.0
选择项目框架:vue
选择语言:ts
创建项目完成
切换路径,安装依赖
cd vue3.0
npm install
npm run dev
第二步安装
安装2.x版本
npm i --save ant-design-vue@next
ant组件库Ant Design Vue
vite按需加载需要引入插件
npm i vite-plugin-style-import -S
集成路由
-
安装支持vue3的路由(
vue-router@4
)npm i vue-router@4
-
创建
src/router/index.ts
文件
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
import Layout from '@/layout/index.vue'
import recommend from '@/pages/recommend.vue'
import musicHall from '@/pages/MusicHall/musicHall.vue'
import myLike from '@/pages/myLike/myLike.vue'
import historyPlay from '@/pages/historyPlay/historyPlay.vue'
import playList from '@/pages/playList/playList.vue'
import album from '@/pages/album/album.vue'
import artist from '@/pages/artist/artist.vue'
import videoPlayer from '@/pages/videoPlayer/VideoPlayer.vue'
import search from '@/pages/search/search.vue'
import video from '@/pages/video/video.vue'
const routes: Array<RouteRecordRaw> = [
{
path: '/',
redirect: '/musicHall',
component: Layout,
children: [
{
path: 'recommend',
component: recommend,
meta: { title: 'PING', keepAlive: true }
},
{
path: 'musicHall',
component: musicHall,
meta: { title: 'PING', keepAlive: true }
},
{
path: 'myLike',
component: myLike,
meta: { title: 'PING', keepAlive: true }
},
{
path: 'historyPlay',
component: historyPlay,
meta: { title: 'PING', keepAlive: true }
},
{
path: 'playList/:id',
name: 'playList',
component: playList,
meta: { title: 'PING', keepAlive: false }
},
{
path: 'album/:id',
name: 'album',
component: album,
meta: { title: 'PING', keepAlive: false }
},
{
path: 'artist/:id',
name: 'artist',
component: artist,
meta: { title: 'PING', keepAlive: false }
},
{
path: 'videoPlayer/:type/:id',
name: 'videoPlayer',
component: videoPlayer,
meta: { title: 'PING', keepAlive: false }
},
{
path: 'search/:keywords',
name: 'search',
component: search,
meta: { title: 'PING', keepAlive: false }
},
{
path: 'video',
name: 'video',
component: video,
meta: { title: 'PING', keepAlive: false }
}
]
}
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
export default router
main.ts挂载
import { createApp } from 'vue'
import '@/style/antd-ui.less'
import '@/style/personal.css'
import Router from '@/router'
import Vuex from '@/store'
import svgIcon from '@/components/svgIcon.vue'
import Image from '@/components/global/Image.vue'
import initDirective from '@/utils/directive'
// @ts-ignore
import VuePlyr from 'vue-plyr'
import 'vue-plyr/dist/vue-plyr.css'
import App from '@/App.vue'
Router.beforeEach((to, from, next) => {
if (to.meta.title) {
// @ts-ignore
document.title = to.meta.title // 根据路由动态显示页面title
}
next()
})
const app = createApp(App)
// 加载自定义指令
initDirective(app)
app.use(Router)
app.use(Vuex)
app.use(VuePlyr, { plyr: {}})
app.component('SvgIcon', svgIcon)
app.component('Image', Image)
app.mount('#app')
集成Vuex
-
安装支持Vue3的状态管理工具
vuex@next
npm i vuex@next
-
创建
src/store/index.ts
文件
import { createStore } from 'vuex'
const defaultState = {
count: 0
}
// Create a new store instance.
export default createStore({
state() {
return defaultState
},
mutations: {
increment(state: typeof defaultState) {
state.count += 1
}
},
actions: {
increment(context) {
context.commit('increment')
}
},
getters: {
double(state: typeof defaultState) {
return 2 * state.count
}
}
})
在mian.ts 挂载
import { createApp } from 'vue'
import '@/style/antd-ui.less'
import '@/style/personal.css'
import Router from '@/router'
import Vuex from '@/store'
import svgIcon from '@/components/svgIcon.vue'
import Image from '@/components/global/Image.vue'
// @ts-ignore
import VuePlyr from 'vue-plyr'
import 'vue-plyr/dist/vue-plyr.css'
import App from '@/App.vue'
Router.beforeEach((to, from, next) => {
if (to.meta.title) {
// @ts-ignore
document.title = to.meta.title // 根据路由动态显示页面title
}
next()
})
const app = createApp(App)
// 加载自定义指令
initDirective(app)
app.use(Router)
app.use(Vuex)
app.use(VuePlyr, { plyr: {}})
app.component('SvgIcon', svgIcon)
app.component('Image', Image)
app.mount('#app')
集成HTTP工具 Axios
-
安装
Axios
(跟vue版本无关,安装最新即可)npm i axios
-
配置
Axios
根据常规规范,axios封装的方法放在 src/utils/http.ts
import axios from 'axios'
import { Message } from 'ant-design-vue'
// 创建axios实例
// 创建请求时可以用的配置选项
const instance = axios.create({
withCredentials: true,
timeout: 1000,
baseURL: ''
})
// axios的全局配置
instance.defaults.headers.post = {
'Content-Type': 'application/x-www-form-urlencoded'
}
instance.defaults.headers.common = {
'Auth-Type': 'company-web',
'X-Requested-With': 'XMLHttpRequest',
token: 'sdfjlsdfjlsdjflsjflsfjlskd'
}
// 添加请求拦截器(post只能接受字符串类型数据)
instance.interceptors.request.use(
(config) => {
return config
},
(error) => {
return Promise.reject(error)
}
)
const errorHandle = (status, other) => {
switch (status) {
case 400:
Message.error('信息校验失败')
break
case 401:
Message.error('认证失败')
break
case 403:
Message.error('token校验失败')
break
case 404:
Message.error('请求的资源不存在')
break
default:
Message.error(other)
break
}
}
// 添加响应拦截器
instance.interceptors.response.use(
// 响应包含以下信息data,status,statusText,headers,config
(res) => (res.status === 200 ? Promise.resolve(res) : Promise.reject(res)),
(err) => {
Message.error(err)
const { response } = err
if (response) {
errorHandle(response.status, response.data)
return Promise.reject(response)
}
Message.error('请求失败')
return true
}
)
export default instance
- 使用
Axios
在需要使用的地方引入http.ts
文件
import request from '@/utils/request'
export function getMvDetail(params:object) {
return request({
url: '/moive/detail',
method: 'get',
params
})
}
页面使用
import { getMvDetail } from '@/api/user'
export default defineComponent({
setup() {
const getMvData = () => {
const param = { mvid: route.params?.id }
getMvDetail(param).then((res:any) => {
if (res.code === 200) {
videoInfo.value = res.data
}
})
}
}
})
集成CSS预编译器
本项目以less为例,相关的loader Vite 已经集成好了,无需额外配置
-
安装
npm i less -D
安装其他的亦可
2.使用
<style lang="less"></style>
vite.config.ts配置文件
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
import { svgBuilder } from './src/plugins/svgBuilder'
import styleImport from 'vite-plugin-style-import'
// https://vitejs.dev/config/
export default defineConfig({
base: './',
server: {
port: 8080,
// open: true,
// proxy: {
// '/api/': {
// target: 'https://172.1.1.0:8080',
// changeOrigin: true,
// rewrite: (path) => path.replace(/^\/api\//, ''),
// }
// }
},
plugins: [
vue(),
svgBuilder('./src/assets/icons/svg/'),
styleImport({
libs: [
{
libraryName: 'ant-design-vue',
esModule: true,
resolveStyle: (name) => {
return `ant-design-vue/es/${name}/style/index`
}
}
]
})
],
resolve: {
alias: {
'@': resolve(__dirname, './src')
}
},
css: {
preprocessorOptions: {
less: {
javascriptEnabled: true
}
}
}
})