资料详情

基于VUE +CSS3+SASS+ElementUI+Node+MySql的前后端分离复杂数据库应用

头像

理工论文

编号:11292
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 �CS

在命令窗口中,执行以下代码再安装vuex依赖包。

npm install vuex@3.1.1 �Csave

在命令窗口中,连续执行以下代码再安装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">

  全套毕业设计论文现成成品资料请咨询