音乐网站实战(更新中)

3 篇文章 0 订阅
2 篇文章 0 订阅

音乐网站实战

1、vue工程搭建

电脑已配置过vue-cli,cnpm,vue2.x

在需要创建vue工程的目录执行命令行vue init webpack

然后依次填写项目名称及一系列配置,不要用npm下载node_modules,一会用自己的cnpm下载快一点。

cnpm install,cnpm run dev启动项目。

2、引入模块

2.1、Element-UI
cnpm install element-ui --save

在main.js中添加下面的代码

import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI);

这样每个vue页面都能使用了。

2.2、stylus
cnpm install stylus stylus-loader --save-dev

使用:

<style scoped lang="stylus">

</style>

报错的话,把"stylus-loader": "^3.0.2"降级。

2.3、清除默认样式

在main.js中导入

//清除默认样式
import './assets/css/base.css'
/**
 * Eric Meyer's Reset CSS v2.0 (http://meyerweb.com/eric/tools/css/reset/)
 * http://cssreset.com
 */
html,body{
  width: 100%;
  height: 100%;
}
html,
body,
div,
span,
applet,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
a,
abbr,
acronym,
address,
big,
cite,
code,
del,
dfn,
em,
img,
ins,
kbd,
q,
s,
samp,
small,
strike,
strong,
sub,
sup,
tt,
var,
b,
u,
i,
center,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
embed,
figure,
figcaption,
footer,
header,
menu,
nav,
output,
ruby,
section,
summary,
time,
mark,
audio,
video,
input {
  margin: 0;
  padding: 0;
  border: 0;
  /* font-size: 100%; */
  font-weight: normal;
  vertical-align: baseline;
}

/* HTML5 display-role reset for older browsers */
article,
aside,
details,
figcaption,
figure,
footer,
header,
menu,
nav,
section {
  display: block;
}

body {
  line-height: 1;
  font-family: "Microsoft YaHei";
  font-size: 16px;
}

blockquote,
q {
  quotes: none;
}

blockquote:before,
blockquote:after,
q:before,
q:after {
  content: none;
}

table {
  border-collapse: collapse;
  border-spacing: 0;
}

/* custom */
a {
  color: #7e8c8d;
  text-decoration: none;
  -webkit-backface-visibility: hidden;
}

li {
  list-style: none;
}

::-webkit-scrollbar {
  width: 5px;
  height: 5px;
}

::-webkit-scrollbar-track-piece {
  background-color: rgba(0, 0, 0, 0.2);
  -webkit-border-radius: 6px;
}

::-webkit-scrollbar-thumb:vertical {
  height: 5px;
  background-color: rgba(125, 125, 125, 0.7);
  -webkit-border-radius: 6px;
}

::-webkit-scrollbar-thumb:horizontal {
  width: 5px;
  background-color: rgba(125, 125, 125, 0.7);
  -webkit-border-radius: 6px;
}

html,
body {
  width: 100%;
}

body {
  -webkit-text-size-adjust: none;
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}

3、登录

环境:jdk1.8、springboot2.4.4和vue2.x和MySQL8

3.1、后端

设计数据库,先设计好admin表,id,username,password即可。

导入所需依赖

<!--fastjson-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.75</version>
</dependency>
<!--jdbc-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--web-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--mybatis-->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.4</version>
</dependency>
<!--devtools-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <scope>runtime</scope>
    <optional>true</optional>
</dependency>
<!--mysql驱动-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>
<!--lombok-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
<!--test-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

首先需要热加载,导入 spring-boot-devtools ,然后在IDEA中配置相关属性。

参考CSDN:https://blog.csdn.net/qq_16148137/article/details/99694566

编写applciation.yml

server:
  port: 8088
spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/music?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false
    driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
  type-aliases-package: com.ljh.pojo
  mapper-locations: classpath:mapper/*.xml

端口号和vue冲突,这里先改为8088

spring原生jdbc配置,也可以用druid

新建resources->mapper

配置type-aliases-packagemapper-locations,这一步千万别忘!!!

接下来就是pojo、mapper、service、controller、config的依次编写

pojo实体类

/**
 * 管理员表
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Admin {
  private Integer id;
  private String username;
  private String password;
}

mapper接口

@Repository
@Mapper
public interface AdminMapper {
  /**
   * 通过name和password查询返回多少个数值
   * @return
   */
  int getAdminByName(String username,String password);
}

resources->mapper的mapper实现类

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace绑定一个Mapper-->
<mapper namespace="com.ljh.mapper.AdminMapper">

  <select id="getAdminByName" resultType="int">
    select count(*) from admin where username = #{username} and password = #{password}
  </select>

</mapper>

AdminService

public interface AdminService {

  /**
   * 根据name查询数据库看是否存在
   * @param username
   * @return
   */
  boolean getAdminByName(String username,String password);
}

AdminServiceImpl

@Service
public class AdminServiceImpl implements AdminService {

  @Autowired
  AdminMapper adminMapper;

  @Override
  public boolean getAdminByName(String username,String password) {
    //返回结果大于0,则代表name真实存在于数据库
    return adminMapper.getAdminByName(username,password)>0;
  }
}

先配置常量类utils->Constants

/**
 * 常量
 */
public class Constants {
  //返回结果code
  public static final String CODE = "code";
  //返回信息
  public static final String MSG = "msg";
}

LoginController

@RestController
public class LoginController {

  @Autowired
  private AdminService adminService;

  @PostMapping("/admin/login")
  public Object login(HttpServletRequest request, HttpSession session) {
    JSONObject jsonObject = new JSONObject();
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    boolean flag = adminService.getAdminByName(username, password);
    if (flag) {
      jsonObject.put(Constants.CODE, 1);
      jsonObject.put(Constants.MSG,"登录成功");
      session.setAttribute("name",username);
      return jsonObject;
    }
    jsonObject.put(Constants.CODE, 0);
    jsonObject.put(Constants.MSG,"用户名或密码不正确!");
    return jsonObject;
  }
}

前端通过传递过去的code和msg判断是否登录成功。

因为是前后端分离,所以需要解决跨域问题

@Configuration
public class CrossOriginConfig implements WebMvcConfigurer{


  @Override
  public void addCorsMappings(CorsRegistry registry) {
    /**
     * 允许跨域,参数
     * addMapping:配置可以被跨域的路径,可以任意配置,可以具体到直接请求路径。
     * allowedOrigins:允许所有的请求域名访问我们的跨域资源,可以固定单条或者多条内容,如:"http://www.baidu.com",只有百度可以访问我们的跨域资源。
     * allowCredentials: 响应头表示是否可以将对请求的响应暴露给页面。返回true则可以,其他值均不可以
     * allowedMethods:允许输入参数的请求方法访问该跨域资源服务器,如:POST、GET、PUT、OPTIONS、DELETE等。
     * allowedHeaders:允许所有的请求header访问,可以自定义设置任意请求头信息,如:"X-YAUTH-TOKEN"
     * maxAge:配置客户端缓存预检请求的响应的时间(以秒为单位)。默认设置为1800秒(30分钟)。
     *
     */
    // 2.4.*版本解决跨域问题
    // 当allowCredentials是true时,allowedOrigins不能为" * ",切记切记!
    registry.addMapping("/**")
            .allowedOrigins("http://localhost:8081")
            .allowCredentials(true)
            .allowedMethods("GET", "POST", "DELETE", "PUT")
            .allowedHeaders("*")
            .maxAge(3600);

  }
}

springboot版本不同,解决跨域问题代码也不一样。2.4.x版本之后当allowCredentials是true时,allowedOrigins不能为" * ",直接写vue的地址。

3.2、前端

前端用的是vue脚手架和element-ui

后台登录页面

<template>
  <div class="login-wrap">
    <div class="ms-login">
      <div class="ms-title">后台管理系统</div>
      <el-form status-icon :model="param" :rules="rules" ref="login" label-width="0px" class="ms-content">
        <el-form-item prop="username">
          <el-input name="username"
                    v-model="param.username"
                    placeholder="username"
                    @keyup.enter.native="keyupClick()">
            <!-- <template slot="prepend"></template> -->
            <!-- 下面的代码#prepend就是slot="prepend"的简写 -->
            <!-- 通过 slot 来指定在 input 中前置或者后置内容。-->
            <!-- prepend是前置,append是后置 -->
            <template #prepend>
              <el-button icon="el-icon-user"></el-button>
            </template>
          </el-input>
        </el-form-item>
        <el-form-item prop="password">
          <el-input
            type="password"
            name="password"
            placeholder="password"
            v-model="param.password"
            ref="password"
            @keyup.enter.native="submitForm()"
          >
            <template #prepend>
              <el-button icon="el-icon-lock"></el-button>
            </template>
          </el-input>
        </el-form-item>
        <div class="login-btn">
          <el-button type="primary" @click="submitForm()">登录</el-button>
        </div>
      </el-form>
    </div>
  </div>
</template>

<script>
  import {getLoginStatus} from "../api/index";

  export default {
    data() {
      return {
        param: {
          username: "",
          password: ""
        },
        rules: {
          username: [
            {required: true, message: "请输入用户名", trigger: "blur"}
          ],
          password: [
            {required: true, message: "请输入密码", trigger: "blur"}
          ]
        }
      };
    },
    methods: {
      keyupClick() {
        this.$refs.password.focus();
      },
      submitForm() {
        this.$refs.login.validate(validate=>{
          if(validate) {
            let params = new URLSearchParams();
            params.append("username", this.param.username);
            params.append("password", this.param.password);
            getLoginStatus(params).then(res => {
              if (res.code === 1) {
                this.$router.push("/home");
                this.$message({
                  message:res.msg,
                  type:'success'
                })
              }else{
                this.$message({
                  message:res.msg,
                  type:'error'
                })
              }
            })
          }
        });
      }
    }
  };
</script>

<style scoped>
  .login-wrap {
    position: relative;
    width: 100%;
    height: 100%;
    background-image: url(../assets/image/login-bg.jpg);
    background-size: 100%;
  }

  .ms-title {
    width: 100%;
    line-height: 50px;
    text-align: center;
    font-size: 20px;
    color: #aaa;
    border-bottom: 1px solid #ddd;
  }

  .ms-login {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 350px;
    margin: -190px 0 0 -175px;
    border-radius: 5px;
    background: rgba(255, 255, 255, 0.7);
    overflow: hidden;
  }

  .ms-content {
    padding: 30px 30px;
  }

  .login-btn {
    text-align: center;
  }

  .login-btn button {
    width: 100%;
    height: 36px;
    margin-bottom: 10px;
  }
</style>

要保证width和height占满整个屏幕,必须设置html和body的width和height都为100%

总体使用element-ui的布局和方法,比较方便。

说明: status-icon属性为输入框添加了表示校验结果的反馈图标

:model="param"绑定data数据

:rules="rules"制定规则,在data中自定义规则即可

Form-Item中的prop属性设置需要校验的字段名

@keyup.enter.native="keyupClick()"就是在输完username后,按下回车键执行方法,这个方法就是聚焦到密码框上(因为密码框上设置了ref=“password”)

密码上的 @keyup.enter.native 就是回车提交表单

this.$refs.login.validate(validate=>{}) 返回的validate就是看用户名和密码是否为空,任意一个为空就返回false,全有值才为true。

this.$message({message:res.msg, type:‘error’}) 就是element-ui的弹窗提示,按类型弹窗。

封装axios

http.js

import axios from 'axios';
axios.defaults.timeout = 5000;//超时时间5s
axios.defaults.withCredentials = true;//允许跨域
//Content-Type 响应头
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
//基础url
axios.defaults.baseURL = "http://localhost:8088";

//响应拦截器
axios.interceptors.response.use(response=>{
  if(response.status === 200) {
    return Promise.resolve(response);
  }else{
    return Promise.reject(response);
  }
},error=>{
  if(error.response.status){
    switch(error.response.status){
      case 401:       //未登录
        router.replace('/');
        break;
      case 404:   //没找到
        break;
    }
    return Promise.reject(error.response);
  }
});


/**
 * 封装get方法
 */
export function get(url,params={}){
  return new Promise((resolve,reject) => {
    axios.get(url,{params:params})
      .then(response =>{
        resolve(response.data);
      })
      .catch(err =>{
        reject(err);
      })
  });
}

/**
 * 封装post方法
 */
export function post(url,data={}){
  return new Promise((resolve,reject) => {
    axios.post(url,data)
      .then(response =>{
        resolve(response.data);
      })
      .catch(err =>{
        reject(err);
      })
  });
}

编写index.js与后台交互

import {get,post} from './http';

// 判断管理员是否登录成功
export const getLoginStatus = (params)=>post(`admin/login`,params);

编写路由

import Vue from 'vue'
import Router from 'vue-router'

//一级路由
import Login from "./../pages/Login"
import Home from "../components/Home"


// 二级路由
import TheHeader from "./../components/TheHeader"
import TheAside from "./../components/TheAside"

Vue.use(Router);

//下面一定要写component
export default new Router({
  routes: [
    {
      path:'/',
      component:Login
    },
    {
      path:'/home',
      component:Home,
    }
  ]
})

注意:在vue单页面中要用components,而在配置路由则需要component

4、管理员页面

4.1、侧边菜单

TheAside.vue

<template>
    <div class="sidebar">
      <!--el-menu的mode	模式默认为vertical,即为垂直分布-->
      <!--default-active:当前激活菜单的index-->
      <!--collapse:是否水平折叠收起菜单(仅在 mode 为 vertical 时可用)-->
      <!--router:是否使用vue-router的模式,启用该模式会在激活导航时以index作为path进行路由跳转-->
      <el-menu class="sidebar-el-menu"
               :default-active="activeIndex"
               :collapse="collapse"
               background-color="#334256"
               text-color="#ffffff"
               active-text-color="#20a0ff"
               router
      >
        <template v-for="item in items">
          <template>
            <el-menu-item :index="item.index" :key="item.index">
              <i :class="item.icon"></i>
              <span>{{item.title}}</span>
            </el-menu-item>
          </template>
        </template>
      </el-menu>
    </div>
</template>

<script>
  import bus from "./../assets/js/bus"
  export default {
    name: "TheAside",
    data() {
      return{
        collapse: false,
        items:[
              {
                icon: 'el-icon-document',
                index: 'info',
                title: '系统首页'
              },
              {
                icon: 'el-icon-user',
                index: 'consumer',
                title: '用户管理'
              },
              {
                icon: 'el-icon-document',
                index: 'singer',
                title: '歌手管理'
              },
              {
                icon: 'el-icon-document',
                index: 'songlist',
                title: '歌单管理'
              }
            ]
      }
    },
    computed:{
      //获取当前激活菜单的index
      activeIndex() {
        //this.$route.path格式为:/home/info
        return this.$route.path.replace("/home/","");
      }
    },
    created() {
      bus.$on("collapse",value=>{
        this.collapse = value;
      })
    },
    methods:{

    }
  }
</script>

<style scoped>
/*页面内容禁止选中,仅输入框和文本域可选*/
  * {
    -webkit-touch-callout: none; /*系统默认菜单被禁用*/
    -webkit-user-select: none; /*webkit浏览器*/
    /*-khtml-user-select: none;*/ /*早期浏览器*/
    -moz-user-select: none; /*火狐*/
    -ms-user-select: none; /*IE10*/
    user-select: none;
  }
  input {
    -webkit-user-select: auto; /*webkit浏览器*/
  }
  textarea {
    -webkit-user-select: auto; /*webkit浏览器*/
  }
 /*上面的代码为了页面内容禁止选中*/

.sidebar{
  display: block;
  position: absolute;
  left: 0;
  top: 70px;
  bottom: 0;
  background: #334256;
}
/*解决el-menu菜单收缩部分边框突出问题,需要加下面的代码*/
.sidebar-el-menu:not(.el-menu--collapse){
  width: 150px;
}
.sidebar >ul {
  height: 100%;
}
</style>

主要是运用el-menu和el-menu-item并配置相关属性。

这里引入的bus是用于两个组件之间进行数据传递

解决el-menu菜单收缩部分边框突出问题,上面的代码是解决方案。

如果在this.$router.push(“xxx”)刷新同一个值时,会报错。

解决方案就是在配置路由的index.js中添加下列代码:

// 解决ElementUI导航栏中的vue-router在3.0版本以上重复点菜单报错问题
const originalPush = Router.prototype.push;

Router.prototype.push = function push(location) {
  return originalPush.call(this, location).catch(err => err)
};
4.2、头部页面

TheHeader.vue

<template>
  <div class="header">
    <div class="collapse-btn" @click="collapseChange">
      <i class="el-icon-menu"></i>
    </div>
    <div class="logo">music后台管理</div>
    <div class="header-right">
      <div class="btn-fullscreen" @click="handleFullScreen">
        <!--使用content属性来决定hover时的提示信息。由placement属性决定展示效果-->
        <!--placement为bottom时,提示信息在该图标的正下方显示-->
        <el-tooltip :content="fullscreen?`取消全屏`:`全屏`" placement="bottom">
          <i class="el-icon-rank"></i>
        </el-tooltip>
      </div>
      <div class="user-avator">
        <img src="../assets/image/user.jpg" alt="管理员头像"/>
      </div>
      <!--@command="handleCommand"点击菜单项触发的事件回调,会有一个参数command-->
      <!--在下面定义command="xxx",可以在方法中得到-->
      <el-dropdown class="user-name" trigger="click" @command="handleCommand">
          <span class="el-dropdown-link">
              {{userName}}
              <i class="el-icon-caret-bottom"></i>
          </span>
        <el-dropdown-menu slot="dropdown">
          <el-dropdown-item command="logout">退出登录</el-dropdown-item>
        </el-dropdown-menu>
      </el-dropdown>
    </div>
  </div>
</template>

<script>
  import bus from "./../assets/js/bus"

  export default {
    name: "TheHeader",
    data() {
      return {
        collapse: false,
        fullscreen: false
      }
    },
    methods: {
      //折叠侧边菜单
      collapseChange() {
        this.collapse = !this.collapse;
        bus.$emit("collapse", this.collapse);
      },
      //全屏事件,适配各种浏览器
      handleFullScreen(){
        if(this.fullscreen){
          if(document.exitFullscreen){
            document.exitFullscreen();
          }else if(document.webkitCancelFullScreen){      //safari 、Chrome
            document.webkitCancelFullScreen();
          }else if (document.mozCancelFullScreen){        //firefox
            document.mozCancelFullScreen();
          }else if(document.msExitFullScreen){            //ie
            document.msExitFullScreen();
          }
        }else{
          let element = document.documentElement;
          if(element.requestFullscreen){
            element.requestFullscreen();
          }else if(element.webkitRequestFullScreen){      //safari 、Chrome
            element.webkitRequestFullScreen();
          }else if(element.mozRequestFullScreen){         //firefox
            element.mozRequestFullScreen();
          }else if (element.msRequestFullScreen){         //ie
            element.msRequestFullScreen();
          }
        }
        this.fullscreen = !this.fullscreen;
      },
      //退出登录
      handleCommand(command) {
        if (command === 'logout') {
            //暂时不清空session
          localStorage.removeItem("userName");
          this.$router.push("/");
        }
      }
    },
    computed: {
      //从本地缓存中拿到username
      userName() {
        return localStorage.getItem("userName");
      }
    }
  }
</script>

<style scoped>
  .header {
    position: relative;
    background-color: #253041;
    box-sizing: border-box;
    width: 100%;
    height: 70px;
    font-size: 22px;
    color: #ffffff;
  }

  .collapse-btn {
    float: left;
    padding: 0 21px;
    cursor: pointer;
    line-height: 70px;
  }

  .header .logo {
    float: left;
    line-height: 70px;
  }

  .header-right {
    float: right;
    padding-right: 50px;
    display: flex;
    height: 70px;
    align-items: center;
  }

  .btn-fullscreen {
    transform: rotate(45deg);
    margin-right: 5px;
    font-size: 24px;
    cursor: pointer;
  }

  .user-avator {
    margin-left: 20px;
  }

  .user-avator img {
    display: block;
    width: 40px;
    height: 40px;
    border-radius: 50%;
  }

  .user-name {
    margin-left: 10px;
  }

  .el-dropdown-link {
    color: #ffffff;
    cursor: pointer;
  }
</style>

el-tooltip是提示信息的,el-dropdown是下拉菜单,里面有el-dropdown-menu和el-dropdown-item,具体的里面也有相应的注释。

bus.js

/**
 * 在需要传值的两个组件引入bus
 * 一个组件设置点击事件,触发methods,在方法中执行bus.$emit("xxx",要传递的值);
 * 在另一个组件的created周期中执行
 * bus.$on("xxx",value=>{
    this.值 = value; 接受value值
   })
 */

import Vue from 'vue'

// 使用 Event Bus
const bus = new Vue();

export default bus
4.3、整合页面

Home.vue

<template>
  <div>
    <the-header></the-header>
    <the-aside></the-aside>
    <!--动态添加content-collapse,作用使其在关闭侧边菜单时宽度变化,让右边内容靠拢-->
    <div class="view-wrapper" :class="{'content-collapse':collapse}">
      <router-view></router-view>
    </div>
  </div>
</template>

<script>
  import TheHeader from "./TheHeader"
  import TheAside from "./TheAside"
  //解决侧边菜单收缩,右边内容不自动靠拢
  import bus from "./../assets/js/bus"

  export default {
    name: "Home",
    data() {
      return{
        collapse:false
      }
    },
    components: {
      TheHeader,
      TheAside
    },
    created() {
      bus.$on("collapse",value=>{
        this.collapse = value;
      })
    }
  }
</script>

<style scoped>
  .view-wrapper {
    position: absolute;
    left: 150px;
    right: 0;
    bottom: 0;
    top: 70px;
    overflow-y: scroll;
    -webkit-transition: left .3s ease-in-out;
    transition: left .3s ease-in-out;
    background: #f0f0f0;
  }

  .content-collapse {
    left: 65px;
  }
</style>

解决侧边菜单收缩,由于他还占有位置,所以右边内容不自动靠拢

解决方案就是动态添加一个样式,用来动态改变左边距就ok

前提是还需要引入bus.js,并动态改变collapse的值

4.4、路由配置

index.js

import Vue from 'vue'
import Router from 'vue-router'
// 解决ElementUI导航栏中的vue-router在3.0版本以上重复点菜单报错问题
const originalPush = Router.prototype.push;
Router.prototype.push = function push(location) {
  return originalPush.call(this, location).catch(err => err)
};

//一级路由
import Login from "./../pages/Login"
import Home from "../components/Home"


// 二级路由
import InfoPage from "./../pages/InfoPage"
import ConsumerPage from "./../pages/ConsumerPage"
import SingerPage from "./../pages/SingerPage"
import SongListPage from "./../pages/SongListPage"

Vue.use(Router);

//下面一定要写component
/* 一级路由加"/",二级路由不加"/" */
export default new Router({
  routes: [
    {
      path: '/',
      component: Login
    },
    {
      path: '/home',
      component: Home,
      children: [
        {
          path: '',
          redirect: 'info'
        },
        {
          path: 'info',
          component: InfoPage
        },
        {
          path: 'consumer',
          component: ConsumerPage
        },
        {
          path: 'singer',
          component: SingerPage
        },
        {
          path: 'songlist',
          component: SongListPage
        }
      ]
    }
  ]
})
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值