ext-align: justify; text-indent: 2em; margin-top: 0px; margin-bottom: 0px; -ms-text-justify: inter-ideograph;"><img :src="attachImageUrl(avator)" alt="">
</div>
<ul class="menu">
<li v-for="(item, index) in menuList" :key="index" @click="goMenuList(item.path)">{{item.name}}</li>
</ul>
</div>
</div>
</template>
<script>
import { mixin } from '../mixins'
import { mapGetters } from 'vuex'
import { navMsg, loginMsg, menuList } from '../assets/data/header'
export default {
name: 'the-header',
mixins: [mixin],
data () {
return {
musicName: 'Yin-music',
navMsg: [], // 左侧导航栏
loginMsg: [], // 右侧导航栏
menuList: [], // 用户下拉菜单项
keywords: ''
}
},
computed: {
...mapGetters([
'userId',
'activeName',
'avator',
'username',
'loginIn'
])
},
created () {
this.navMsg = navMsg
this.loginMsg = loginMsg
this.menuList = menuList
console.log("testheader!")
console.log(navMsg)
console.log(loginMsg)
console.log(menuList)
},
mounted () {
document.querySelector('#user').addEventListener('click', function (e) {
document.querySelector('.menu').classList.add('show')
e.stopPropagation()// 关键在于阻止冒泡
}, false)
// 点击“菜单”内部时,阻止事件冒泡。(这样点击内部时,菜单不会关闭)
document.querySelector('.menu').addEventListener('click', function (e) {
e.stopPropagation()
}, false)
document.addEventListener('click', function () {
document.querySelector('.menu').classList.remove('show')
}, false)
},
methods: {
goHome () {
this.$router.push({path: '/'})
},
goPage (path, value) {
document.querySelector('.menu').classList.remove('show')
this.changeIndex(value)
this.$router.push({path: path})
},
changeIndex (value) {
this.$store.commit('setActiveName', value)
},
goMenuList (path) {
this.notify('改功能暂未实现', 'warning')
},
goSearch () {
this.notify('改功能暂未实现', 'warning')
}
}
}
</script>
<style lang="scss" scoped>
@import '../assets/css/the-header.scss';
</style>
步骤7:在components中新建一个名为“AlbumContent.vue”的组件,其完整代码如下。
<template>
<div class="content">
<h1 class="title">
<slot name="title"></slot>
</h1>
<hr>
<ul>
<li class="list-title">
<div class="song-item">
<span class="item-index"></span>
<span class="item-title">歌曲名</span>
<span class="item-name">艺人</span>
<span class="item-intro">专辑</span>
</div>
</li>
<li class="list-content" v-for="(item, index) in songList" :key="index">
<div class="song-item" :class="{'is-play': id === item.id}" @click="toplay(item.id, item.url, item.pic, index, item.name, item.lyric)">
<span class="item-index">
<span v-if="id !== item.id">{{index + 1}}</span>
<svg v-if="id === item.id" class="icon" aria-hidden="true">
<use xlink:href="#icon-yinliang"></use>
</svg>
</span>
<span class="item-title">{{replaceFName(item.name)}}</span>
<span class="item-name">{{replaceLName(item.name)}}</span>
<span class="item-intro">{{item.introduction}}</span>
</div>
</li>
</ul>
</div>
</template>
<script>
import {mixin} from '../mixins'
import { mapGetters } from 'vuex'
export default {
name: 'album-content',
mixins: [mixin],
props: [
"songList"
],
computed: {
...mapGetters([
'id' // 音乐ID
])
},
watch: {
songList: function(newVal,oldVal){
}
}
}
</script>
<style lang="scss" scoped>
@import '../assets/css/album-content.scss';
</style>
步骤8:在components中新建一个名为“ContentList.vue”的组件,其完整代码如下。
<template>
<div class="content-list">
<ul class="section-content">
<li class="content-item" v-for="(item, index) in contentList" :key="index">
<div class="kuo" @click="goAblum(item, item.name)">
<img class="item-img" :src="attachImageUrl(item.pic)" alt="">
<div class="mask" @click="goAblum(item, item.name)">
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-bofang"></use>
</svg>
</div>
</div>
<p class="item-name">{{item.name || item.title}}</p>
</li>
</ul>
</div>
</template>
<script>
import { mixin } from '../mixins'
export default {
name: 'content-list',
mixins: [mixin],
props: [
'contentList'
],
methods: {
goAblum (item, type) {
this.$store.commit('setTempList', item)
if (type) {
this.$router.push({path: `/singer-album/${item.id}`})
} else {
this.$router.push({path: `/song-list-album/${item.id}`})
}
}
}
}
</script>
<style lang="scss" scoped>
@import '../assets/css/content-list.scss';
</style>
步骤9:在pages文件夹下新建一个名为“Home.vue”的页面级组件,其完整代码如下。
<template>
<div class="home">
<!--轮播图-->
<swiper/>
<!--热门歌单/歌手-->
<div class="section" v-for="(item, index) in songsList" :key="index">
<div class="section-title">{{item.name}}</div>
<content-list :contentList="item.list"></content-list>
</div>
</div>
</template>
<script>
import Swiper from '../components/Swiper'
import ContentList from '../components/ContentList'
import axios from 'axios';
export default {
name: 'home',
components: {
Swiper,
ContentList
},
Data () {
return {
songsList: [
{name: '歌单', list: []},
{name: '歌手', list: []}
]
}
},
created () {
this.getSongList('songList')
this.getSinger('singer')
},
methods: {
getSinger(path) {
axios.post('api/music/getallsingers').then(res => {
console.log(res);
console.log(res.data.slice(0, 10));
this.songsList[1].list = res.data.slice(0, 10)
}).catch(err => {
console.log(err)
})
},
getSongList(path) {
axios.post('api/music/getsonglist').then(res => {
console.log(res);
console.log(res.data.slice(0, 10));
this.songsList[0].list = res.data.slice(0, 10)
}).catch(err => {
console.log(err)
})
}
}
}
</script>
<style lang="scss" scoped>
@import '../assets/css/home.scss';
</style>
步骤10:在pages文件夹下新建一个名为“Singer.vue”的页面级组件,其完整代码如下。
<template>
<div class="singer">
<ul class="singer-header">
<li
v-for="(item, index) in singerStyle"
:key="index"
:class="{active: item.name === activeName}"
@click="handleChangeView(item)">
{{item.name}}
</li>
</ul>
<content-list :contentList="data"></content-list>
<div class="pagination">
<el-pagination
@current-change="handleCurrentChange"
background
layout="total, prev, pager, next"
:current-page="currentPage"
:page-size="pageSize"
:total="albumDatas.length">
</el-pagination>
</div>
</div>
</template>
<script>
import ContentList from '../components/ContentList'
import { singerStyle } from '../assets/data/singer'
import axios from 'axios';
export default {
name: 'singer',
components: {
ContentList
},
data () {
return {
singerStyle: [], // 歌手导航栏类别
activeName: '全部歌手',
pageSize: 15, // 页数
currentPage: 1, // 当前页
albumDatas: []
}
},
computed: {
// 计算当前表格中的数据
data () {
return this.albumDatas.slice((this.currentPage - 1) * this.pageSize, this.currentPage * this.pageSize)
}
},
created () {
this.singerStyle = singerStyle
this.getAllSinger()
},
methods: {
// 获取当前页
handleCurrentChange (val) {
this.currentPage = val
},
handleChangeView (item) {
this.activeName = item.name
this.albumDatas = []
if (item.name === '全部歌手') {
this.getAllSinger()
} else {
this.getSingerSex(item.type)
}
},
// 获取所有歌手
getAllSinger () {
axios.post('api/music/getallsingers').then(res => {
console.log(res.data);
this.currentPage = 1
this.albumDatas = res.data
})
.catch(err => {
console.log(err)
})
},
// 通过性别对歌手分类
getSingerSex (sex) {
let singersex=sex;
let param={singersex};
console.log(sex);
axios.post('api/music/getSingerOfSex',param).then(res => {
console.log(res.data)
this.currentPage = 1
this.albumDatas = res.data
})
.catch(err => {
console.log(err)
})
}
}
}
</script>
<style lang="scss" scoped>
@import '../assets/css/singer.scss';
</style>
步骤11:在pages文件夹下新建一个名为“SingerAlbum.vue”的页面级组件,其完整代码如下。
<template>
<div class="singer-album">
<div class="album-slide">
<div class="singer-img">
<img :src="attachImageUrl(singer.pic)" alt="">
</div>
<ul class="info">
<li v-if="singer.sex !== 2">性别:{{attachSex(singer.sex)}}</li>
<li>生日:{{attachBirth(singer.birth)}}</li>
<li>故乡:{{singer.location}}</li>
</ul>
</div>
<div class="album-content">
<div class="intro">
<h2>{{singer.name}}</h2>
<span>{{singer.introduction}}</span>
</div>
<div class="content">
<album-content :songList="listOfSongs">
<template slot="title">歌单</template>
</album-content>
</div>
</div>
</div>
</template>
<script>
import { mixin } from '../mixins'
import { mapGetters } from 'vuex'
import AlbumContent from '../components/AlbumContent'
import axios from 'axios';
export default {
name: 'singer-album',
components: {
AlbumContent
},
mixins: [mixin],
data () {
return {
singerId: '',
SongList:[],
singer: {}
}
},
computed: {
...mapGetters([
'tempList',
'listOfSongs'
])
},
mounted () {
this.singerId = this.$route.params.id // 给歌单ID赋值
this.singer = this.tempList
this.getSongList()
},
methods: {
getSongList () {
let id=this.singerId;
let param={id};
console.log(id);
axios.post('api/music/getSongOfSingerId',param).then(res => {
console.log(res.data)
this.$store.commit('setListOfSongs', res.data)
this.SongList=res.data;
})
.catch(err => {
console.log(err)
})
},
attachSex (value) {
if (value === 0) {
return '女'
} else if (value === 1) {
return '男'
}
}
}
}
</script>
<style lang="scss" scoped>
@import '../assets/css/singer-album.scss';
</style>
步骤12:将router文件夹中的Index.js文件的内容改为如下代码:
import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/pages/Home'
import SongList from '@/pages/SongList'
import Singer from '@/pages/Singer'
import SongListAlbum from '@/pages/SongListAlbum'
import SingerAlbum from '@/pages/SingerAlbum'
import Lyric from '@/pages/Lyric'
Vue.use(Router)
export default new Router({
routes: [
{
path: '*',
redirect: '/404'
},
{
path: '/404',
component: resolve => require(['../pages/404.vue'], resolve)
},
{
path: '/',
name: 'home',
component: Home
},
{
path: '/song-list',
name: 'song-list',
component: SongList
},
{
path: '/song-list-album/:id',
name: 'song-list-album',
component: SongListAlbum
},
{
path: '/singer',
name: 'singer',
component: Singer
},
{
path: '/singer-album/:id',
name: 'singer-album',
component: SingerAlbum
},
{
path: '/lyric/:id',
name: 'lyric',
component: Lyric
}
],
scrollBehavior (to, from, savedPosition) {
return { x: 0, y: 0 }
}
})
步骤13:将根组件App.vue的代码修改为如下代码。
<template>
<div id="app">
<song-audio/>
<the-header/>
<the-aside></the-aside>
<router-view class="music-content"/>
<play-bar/>
<scroll-top/>
<the-footer/>
</div>
</template>
<script>
import ScrollTop from './components/ScrollTop' //回到顶部按钮
import SongAudio from './components/SongAudio' //音频播放组件
import TheHeader from './components/TheHeader' //头部
import TheFooter from './components/TheFooter' //顶部
import PlayBar from './components/PlayBar' //播放工具条
import TheAside from './components/TheAside' //播放列表(起始状态为隐藏)
export default {
name: 'App',
components: {
ScrollTop,
SongAudio,
TheHeader,
TheFooter,
TheAside,
PlayBar
}
}
</script>
<style lang="scss" scoped>
@import './assets/css/app.scss';
</style>
步骤14:将根组件main.js的代码修改为如下代码。
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store/index'
import './assets/css/index.scss'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import '@/assets/js/iconfont.js'
import '@/assets/js/iconfont1.js'
import '@/assets/js/iconfont2.js'
import '@/assets/js/iconfont3.js'
Vue.use(ElementUI)
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})
步骤15:保存以上文件之后,在cmd命令窗口中,按Ctrl+C停止服务,然后music-client目录下再次运行npm run dev,返回谷歌浏览器中,在地址为“http://localhost:8080/#/”的前端页面,发现谷歌浏览器的控制台中报404错误,这是因为前端页面的8080端口和后端服务器的8888端口是两个不同的端口,跨域了。这时候,找到前端“music-client”项目中的config文件夹中的文件index.js,可以看到,原本在开发配置dev里面的地址映射表proxyTable的内容为空,现在修改为如下代码。
proxyTable: {
'/api': {
target: 'http://127.0.0.1:8888', //请求的目标服务器接口
changeOrigin: true, //true允许跨域
pathRewrite: { //重写请求
//替换target中的请求地址,也就是说在请求
//http://127.0.0.1:8888/XXXXX这个地址的时候直接写成/api即可。
'^/api': '/api'
}
}
},
保存以上文件后,在cmd命令窗口中,按Ctrl+C停止服务,在music-client目录下的命令窗口中,再次运行npm run dev,然后再查看前端页面,运行效果如图5.5所示(注意按F12查看谷歌浏览器控制台的打印信息),表明运行成功!
, 《Web前端案例设计》实验指导书
基于VUE +CSS3+SASS+ElementUI+Node+MySql
的前后端分离复杂数据库应用
1. 巩固和掌握CSS3弹性盒子布局的运用技巧。
2. 熟悉和掌握SASS编程式层叠样式表技术的运用技巧。
3. 熟悉和掌握基于VUE +CSS3 Flex+SASS+ElementUI +Node+MySql的前后端分离数据库应用的编程方法。
二、实验内容
步骤1:确保已经安装好了node、webpack、vue-cli2.x, VSCode中已经安装了Vetur扩展。
步骤2:在MySQL中创建数据库和数据库表。
首先确保电脑上已经安装好了MySQL数据库及其管理工具Navicat for MySQL,然后,使用Navicat for MySQL创建一个名称为“tp_music”数据库,然后在该数据库中执行实验五附件DB文件夹中给出的“tp_music.sql”文件创建所需数据库表并插入数据。
步骤3:搭建Express Web服务器。
在站点文件夹下(如g:\vue\musicWebsiteClient\test1\)新建一个文件夹server,用于存放Express Web服务器的相关文件。在server目录的命令窗口中执行以下指令,初始化package.json,该文件是NodeJS预定的用来存放项目的信息和配置等信息的文件。
npm init -y
然后在VSCode中打开server文件夹,并按图5.1所示的结构创建文件夹和文件。
图5.1 server文件夹的目录结构
然后,将实验五附件中server文件夹里的img文件夹里的所有文件夹和所有文件整体拷贝到刚刚创建的img文件夹里,将实验五附件中server文件夹的song文件夹里的所有文件整体拷贝到刚刚创建的song文件夹里。
在server文件夹下的命令窗口执行以下代码,同时安装express、mysql和body-parser。
npm install express mysql body-parser
安装成功后,在node_modules中可以看到以上刚刚安装的三个依赖包的文件夹。
然后,依次编写以上刚刚新建的4个文件,分别为:index.js、DBHelper_Music.js、sqlMap_Music.js、musicApi.js。这4个文件的作用和代码说明如下。
(1)index.js文件
index.js是Express服务器的入口文件,代码如下。
// node后端服务器
const http = require('http');
const badyParser = require('body-parser');
const express = require('express');
const musicApi = require('./api/musicApi');
let app = express();
let server = http.createServer(app);
// 解析body数据
app.use(express.json())
// 托管静态文件
app.use('/img/singerPic', express.static(__dirname + '/img/singerPic'))
//下面是为了接受http请求服务器本地文件做的设置!重要!
app.get('/song/*', function (req, res) {
res.sendFile( __dirname + "/" + req.url );
console.log("Request for " + req.url + " received.");
})
app.get('/public/img/*', function (req, res) {
res.sendFile( __dirname + "/" + req.url );
console.log("Request for " + req.url + " received.");
})
app.get('/img/singerPic/*', function (req, res) {
res.sendFile( __dirname + "/" + req.url );
console.log("Request for " + req.url + " received.");
})
app.get('/img/songPic/*', function (req, res) {
res.sendFile( __dirname + "/" + req.url );
console.log("Request for " + req.url + " received.");
})
app.get('/img/songListPic/*', function (req, res) {
res.sendFile( __dirname + "/" + req.url );
console.log("Request for " + req.url + " received.");
})
app.get('/img/*', function (req, res) {
res.sendFile( __dirname + "/" + req.url );
console.log("Request for " + req.url + " received.");
})
app.use(badyParser.json());
app.use(badyParser.urlencoded({
extended: false
}));
// 后端api路由
app.use('/api/music',musicApi);
// 启动监听
server.listen(8888, () => {
console.log(' success!! port:8888')
})
(2)DBHelper_Music.js文件
DBHelper_Music.js用来连接MySQL数据库,代码如下(注意:password的取值根据MySQL安装的实际情况决定)。
// 数据库连接助手
const mysql = require('mysql');
class DBHelper_Music{
// 获取数据库连接
getConn(){
let conn = mysql.createConnection({
// 数据库连接配置
host:'localhost',
port:'3306',
user:'root',
password:'',
database:'tp_music' // 数据库名
});
conn.connect();
return conn;
}
}
module.exports = DBHelper_Music;
(3)sqlMap_Music.js文件
sqlMap_Music.js文件用于统一设置SQL语句映射,以供http请求处理文件调用使用,这样便于修改维护SQL语句,代码如下。
// sql语句
var sqlMap = {
singer:{
getsingers:'select * from singer',
getSingerOfSex:'select * from singer where sex=?'
},
song:{
getSongOfSingerId:'select * from song where singer_id=?'
},
songlist:
{
getsonglist:'select * from song_list',
getsonglistOfStyle:'select * from song_list where style=?'
},
//listSong:歌单的歌曲信息,歌单是“专辑”的意思
listSong:{
getSongListOfId:'select * from list_song where song_list_id=?',
getSongOfId:'select * from song where id=?'
},
//歌单评分
rank:{
//查询歌单Id评价平均分
getRankOfId:'select avg(score) as avgscore from rank where songListId=?'
}
}
module.exports = sqlMap;
(4)musicApi.js文件
如前所述,musicApi.js是http请求路由为’ /api/music’时的js处理文件,代码如下。
const express = require('express');
const router = express.Router();
const sql_Music = require('../sqlMap_Music');
const DBHelper_Music = require('../utils/DBHelper_Music');
//api/music/getSongOfSingerId
router.post('/getSongOfSingerId', (req, res) => {
let sqlStr = sql_Music.song.getSongOfSingerId;
let conn = new DBHelper_Music().getConn();
let params = req.body;
conn.query(sqlStr,[params.id],(err, result) => {
if (err) {
res.json(err);
} else {
res.json(result)
}
});
conn.end();
});
// 查询所有歌手
router.post('/getallsingers', (req, res) => {
let sqlStr = sql_Music.singer.getsingers;
let conn = new DBHelper_Music().getConn();
conn.query(sqlStr, (err, result) => {
if (err) {
res.json(err);
} else {
res.json(result)
}
});
conn.end();
});
// 按性别/类别查询歌手
router.post('/getSingerOfSex', (req, res) => {
let sqlStr = sql_Music.singer.getSingerOfSex;
let conn = new DBHelper_Music().getConn();
let params = req.body;
conn.query(sqlStr,[params.singersex],(err, result) => {
if (err) {
res.json(err);
} else {
res.json(result)
}
});
conn.end();
});
// 查询所有歌单
router.post('/getsonglist', (req, res) => {
let sqlStr = sql_Music.songlist.getsonglist;
let conn = new DBHelper_Music().getConn();
conn.query(sqlStr, (err, result) => {
if (err) {
res.json(err);
} else {
res.json(result)
}
});
conn.end();
});
//getsonglistOfStyle
router.post('/getsonglistOfStyle', (req, res) => {
let sqlStr = sql_Music.songlist.getsonglistOfStyle;
let conn = new DBHelper_Music().getConn();
//songstyle
let params = req.body;
conn.query(sqlStr,[params.songstyle],(err, result) => {
if (err) {
res.json(err);
} else {
res.json(result)
}
});
conn.end();
});
//getSongOfId
router.post('/getSongOfId', (req, res) => {
let sqlStr = sql_Music.collect.getSongOfId;
let conn = new DBHelper_Music().getConn();
let params = req.body;
conn.query(sqlStr,[params.id],(err, result) => {
if (err) {
res.json(err);
} else {
res.json(result)
}
});
conn.end();
});
//api/music/getSongListOfId
router.post('/getSongListOfId', (req, res) => {
let sqlStr = sql_Music.listSong.getSongListOfId;
let conn = new DBHelper_Music().getConn();
let params = req.body; //id
console.log(params.id)
conn.query(sqlStr,[params.id],(err, result) => {
if (err) {
res.json(err);
} else {
res.json(result)
}
});
conn.end();
});
//api/music/getSongAllOfId
router.post('/getSongAllOfId', (req, res) => {
let sqlStr = sql_Music.listSong.getSongOfId;
console.log(sqlStr)
let conn = new DBHelper_Music().getConn();
let params = req.body; //id
console.log(params.id)
conn.query(sqlStr,[params.id],(err, result) => {
if (err) {
res.json(err);
} else {
res.json(result)
}
});
conn.end();
});
//api/music/getRankOfId
router.post('/getRankOfId', (req, res) => {
console.log("enter getRankOfId!")
let sqlStr = sql_Music.rank.getRankOfId;
console.log(sqlStr)
let conn = new DBHelper_Music().getConn();
let params = req.body; //id
console.log(params.id)
conn.query(sqlStr,[params.id],(err, result) => {
if (err) {
res.json(err);
} else {
res.json(result)
}
});
conn.end();
});
module.exports = router;
以上4个文件全部编写完成之后,在server文件夹下的命令窗口执行“node index”,如看到success listen at port:8888,表明服务端启动成功。
步骤4:搭建前端项目
在站点文件夹(如g:\vue\musicWebsiteClient\test1),进入cmd命令窗口,然后在命令行中依次执行以下命令创建一个基于 webpack 模板的新项目“music-client”。
vue init webpack music-client
在命令行中依次执行以下两个命令,安装依赖包。
cd music-manage
npm install
在命令行中执行以下命令,编译并运行新建的项目“music-manage”。
npm run dev
在谷歌浏览器的地址栏中输入“““http://localhost:8080”,运行效果如图5.2所示,则表明基于webpack的vue项目已经成功创建。
图5.2 新建项目初始运行效果
在cmd命令窗口中,按Ctrl+C停止服务,开始安装element-ui和axios依赖包。
首先运行以下命令,安装element-ui依赖包和axios依赖包。。
npm install element-ui axios –S
在命令窗口中,执行以下代码再安装vuex依赖包。
npm install vuex@3.1.1 –save
在命令窗口中,连续执行以下代码再安装sass相关依赖包。
npm install sass-loader@7.3.1 --save-dev
npm install node-sass@4.14.1 --save-dev
在命令窗口中,执行以下代码再安装安装moment依赖包
npm install --save moment
查看自动生成的package.json文件,若包含如图5.3所示的内容,表明以上依赖包已经安装成功。
图5.3 package.json文件中dependencies节内容截图
然后,在cmd命令窗口中,在命令行中再输入以下命令,再次编译运行“music-client“项目。
npm run dev
之后,在谷歌浏览器中,访问“http://localhost:8080/#/“这个页面,运行效果如图5.2所示。
步骤5:
在src下面创建如图5.4所示的目录结构。注意:其中assets、components和router文件夹本来就有。
图5.4 music-client文件夹中的src文件夹的目录结构
(1) 将实验五附件中client文件夹的assets文件夹中的所有文件夹和文件都整体拷贝到刚刚新建的assets文件夹中;
(2) 将实验五附件中client文件夹的components文件夹中的所有文件都拷贝到components文件夹中;
(3) 将实验五附件中client文件夹的pages文件夹中的所有文件都拷贝到刚刚新建的pages文件夹中;
(4) 将实验五附件中client文件夹的minixs文件夹中的所有文件都拷贝到刚刚新建的minixs文件夹中;
(5) 将实验五附件中client文件夹的store文件夹中的所有文件拷贝到刚刚新建的store文件夹中。
步骤6:在components中新建一个名为“TheHeader.vue”的组件,其完整代码如下。
<template>
<div class="the-header">
<!--图标-->
<div class="header-logo" @click="goHome">
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-erji"></use>
</svg>
<span>{{musicName}}</span>
</div>
<ul class="navbar" ref="change">
<li :class="{active: item.name === activeName}" v-for="item in navMsg" :key="item.path" @click="goPage(item.path, item.name)">
{{item.name}}
</li>
<li>
<div class="header-search">
<input type="text" placeholder="搜索音乐" @keyup.enter="goSearch()" v-model="keywords">
<div class="search-btn" @click="goSearch()" >
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-sousuo"></use>
</svg>
</div>
</div>
</li>
<li v-if="!loginIn" :class="{active: item.name === activeName}" v-for="item in loginMsg" :key="item.type" @click="goPage(item.path, item.name)">{{item.name}}</li>
</ul>
<!--设置-->
<div class="header-right" v-show="loginIn">
<div id="user">
全套毕业设计论文现成成品资料请咨询