【Vue3网易云音乐项目实战教程】三、项目启动前做一些初始化工作

1,248 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情

前言

前两节只是对我们即将要做的项目进行初步的介绍与分析,从这一节开始,我们就要正式进入到项目代码的开发过程中了。当然了,在正式进入到代码开发中,我们还是要做一些初始化的工作,这能够让我们在后期的开发过程中,更加轻松、方便。

项目代码初始化

配置 Vite.config.js

1、alias别名设置

平常我们在项目中引入目标模块的时候,会这样写../../../views/index/index相对路径,抑或者是/src/views/index/index这样的绝对路径。但是在实际的项目开发中,这样的写法不仅难看,还臃肿,一不小心就有可能会写错路径,后期项目若是进行重构,需要更改路径或者名称等情况,就会令人抓狂。如果我们设置了项目路径别名,如@views/index/index,就可以用来提高代码的可读性和可维护性。

// Vite.config.js
import { resolve } from 'path' 

export default defineConfig({
    // ...
    resolve: {
        alias: {
            '@': resolve(__dirname, 'src'),
            '@components': resolve(__dirname, 'src/components'),
            '@apis': resolve(__dirname, 'src/apis'),
            '@utils': resolve(__dirname, 'src/utils'),
            '@plugins': resolve(__dirname, 'src/plugins'),
            '@assets': resolve(__dirname, 'src/assets'),
            '@views': resolve(__dirname, 'src/views'),
        }
    }
})

2、extensions省略扩展名

默认['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json'],导入时想要省略的扩展名列表。注意, 建议忽略自定义导入类型的扩展名(例如:.vue),因为它会影响 IDE 和类型支持。

export default defineConfig({
    // ...
    resolve: {
        extensions: ['.less', '.js', '.ts', '.jsx', '.tsx', '.json']
    }
})

3、开发服务器选项配置

export default defineConfig({
    // ...
    server: {
        host: 0.0.0.0,  // 设置为 `0.0.0.0` 或者 `true` 将监听所有地址,包括局域网和公网地址
        port: 1234,     // 自定义开发服务器端口,适合多个项目同时启动,导致端口号被占用
        proxy: {}
    }
})

Element-Plus的引入

因为element-plus的UI组件库,我们并不会是全部使用,所以我喜欢是按需引入,根据官方提供的文档,我摘抄如下:

首先你需要安装unplugin-vue-components 和 unplugin-auto-import这两款插件

$ npm install -D unplugin-vue-components unplugin-auto-import


// vite.config.js
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'


export default defineConfig({
  plugins: [
    // ...
    AutoImport({
      resolvers: [ElementPlusResolver()],
    }),
    Components({
      resolvers: [ElementPlusResolver()],
    }),
  ],
})

CSS样式初始化

这是老生常谈的问题,作为一个前端开发应该都知道,各大浏览器都内置了 HTML 元素默认样式表,为了考虑到浏览器的兼容问题,节省开发时间,我们就需要重置一下CSS样式,以获得更好的跨浏览器兼容。


:root {
    --t-primary-color: #f7be10;
    --t-text-color: #2d2d2d; 
    --t-muted-color: #909090;       
    --t-light-color: #ccc;       
    --t-highlight-color: var(--t-primary-color);
    --t-container-background: rgba(250, 250, 250, .8);
    --t-modal-shadow: inset 1px 1px 0 0 hsla(0,0%,100%,.5),0 3px 8px 0 #555a64;
}

* { 
    padding: 0; 
    margin: 0; 
}
html, body { 
    height: 100%; 
    font-size: 14px;
    font-family: PingFang SC,Arial,Microsoft YaHei,sans-serif; 
    color: var(--t-text-color); 
    background-color: var(--t-container-background);
}
a { 
    text-decoration: none;  
    color: var(--color-text-main);
}
a:hover { 
    text-decoration:underline;
}
img { 
    border:none;
}
ol,ul,li { 
    list-style:none;
}
*,*:focus,*:hover, input{ 
    outline:none; 
}
// 滚动条样式
::-webkit-scrollbar { 
    width: 0px;
}
::-webkit-scrollbar-track {
    border-radius: 8px;
    background: transparent;
}
::-webkit-scrollbar-thumb { 
    border-radius: 8px; 
    background: var(--t-light-color);
}
::-webkit-scrollbar-thumb:hover { 
    background: var(--t-muted-color);
}

// 页面布局的宽高
#app, .el-container { width: 100vw; height: 100%; }

项目结构划分

页面布局

上一节课我们已经将页面布局简单地画了一下,这一节我们就这边实现。

// App.vue
<template>
    <!-- 页面主体边框 -->
    <el-container>

        <!-- 页面左侧导航 -->
        <Sidebar />

        <!-- 页面内容主体 -->
        <el-main>
            <!-- 主体部分,顶部搜索及登录部分 -->
            <Header />

            <!-- 主体部分,页面渲染区域 -->
            <router-view></router-view>
        </el-main>

        <!-- 音乐播放条 -->
        <!-- <play-bar></play-bar> -->
    </el-container>
</template>
<script setup>
import Sidebar from '@components/Sidebar.vue';
import Header from '@components/Header.vue';
</script>

<style>
</style>

左侧sidebar组件

左侧导航部分,效果图如下所示:

20220422154205.jpg

实现的效果,切换导航,根据路由渲染数据,当前导航高亮。

顶部fixed

主体区域顶部,准备实现搜索、用户登录注册退出等功能,后续如果还有其他功能,可以继续添加。

20220422155235.jpg

// Header.vue
<template>
    <el-header>
        <!-- 搜索框 -->
        <div class="search">
            搜索
        </div>
        <!-- 用户操作:登录注册退出 -->
        <div class="user-info">
            登录/注册
        </div>
    </el-header>
</template>

<script setup>
</script>

<style scoped>
</style>

音乐播放条 play-bar

页面底部的音乐播放条,功能比较多而复杂,后期会专门有所讲解,我们目前只是需要知道要实现的效果即可。

20220422155336.jpg 依次展示当前播放歌曲的封面海报、歌曲名、演唱者、当前播放时长、音乐总时长、上一首、播放/暂停、下一首、音量条、音乐播放模式、歌曲、播放列表、mini播放器......

项目路由配置

我们需要将我们的组件映射到路由上,点击后会渲染不同的页面数据。

import { createRouter, createWebHistory} from 'vue-router';

// 定义一些路由, 每个路由都需要映射到一个组件
const routes = [
    { path: '/', redirect: '/index'},
    { path: '/index', name: 'index', component: () => import('@views/index/Index.vue')},
];

// 创建路由实例并传递 `routes` 配置
const router = createRouter({
    history: createWebHistory(),
    routes
});

export default router;

路由的具体用法,在后期课程会有所涉猎,还没看过的,可先自行到官网查阅。

axios的封装

Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。封装起来,就不用每次都要引入调用了,减少不必要的代码量。

// instance.js
import axios from 'axios';

// 自定义配置
// 新建一个 axios 实例
const instance = axios.create({
    // `timeout` 指定请求超时的毫秒数(0 表示无超时时间)
    // 如果请求话费了超过 `timeout` 的时间,请求将被中断
    timeout: 1000 * 60,
    // `withCredentials` 表示跨域请求时是否需要使用凭证
    withCredentials: true,
    // `validateStatus` 定义对于给定的HTTP 响应状态码是 resolve 或 reject  promise 。
    // 如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`),
    // promise 将被 resolve; 否则,promise 将被 rejecte
    validateStatus: status => {
        return status >= 200 && status < 300; // default
    },
    baseURL: 'DOMIAN'
});

// 拦截器
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    return config;
}, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
});

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
    // 对响应数据做点什么
    return response;
}, function (error) {
    // 对响应错误做点什么
    return Promise.reject(error);
});

// 请求时使用的方法
const ajaxMethod = ['get', 'post']
const api = {}
ajaxMethod.forEach(method => {
    api[method] = function (uri, data, config) {
        return new Promise(function (resolve, reject) {
            instance[method](uri, data, config)
            .then(response => {
                resolve(response)
            })
            .catch(error => {
                reject(error)
            })
        })
    }
});

export default api;

通过封装后,设置全局变量,挂载到#app。具体设置,可以自行下载代码查阅。

课后总结

看到这里,我们终于已经开始着手了代码的开发,目前项目的初始重置、页面结构的划分以及页面路由等都已经配置完成,若是后期在开发过程中有所变化,我们会随时进行调整。在这节课我们也学到了稍微那么有点儿用的东西了吧。

下节课,我们计划要实现项目首页左侧导航条、登录/注册、轮播图、热门歌单功能。

好了,下节课见。

一键三连,努力变得更强!!!