快速搭建前端页面并与后端交互

快速搭建前端页面

1 Vue

前置:需要先包含node环境
如果没有,可去node官网下载一个并配置
node官网地址:https://nodejs.org/zh-cn/

# 检测是否安装成功
node -v 

1.1 vue脚手架

  1. 检测是否有node环境,如果没有则去node官网下载配置【进入cmd执行以下命令】
node -v
  1. 安装vue脚手架
npm install -g @vue/cli
# 检测是否安装成功
vue --version 
  1. 创建项目
# 全局安装初始化命令
npm i -g @vue/cli-init
# 创建项目
vue init webpack 文件夹名称

如果当前文件夹已经存在会提示Target directory exists. Continue? 是否在当前目录下创建,输入yes表示同意

# 项目名
Project name -- testpro
# 项目描述
Project description -- A Vue.js project
# 作者
Author -- ziyi
# build选项
Vue build ("通过上下箭头选择")
	- Runtime+Compiler 运行加编译【建议】
	- Runtime-only 仅运行
# 是否安装路由【输入y或者n即可】
Install vue-router(Y/n) 
# 是否使用ESLint(代码风格校验工具)
Use ESLint to lint your code?(Y/n) 
# 是否设置单元测试
Set up unit tests (Y/n) 
# 是否设置端到端测试
Setup e2e tests with Nightwatch (Y/n) 
# 使用什么管理包
Should we run `npm install` for you after the project has been created?
	- Yes, use NPM (使用npm包管理)
	- Yes, use Yarn (使用yarn包管理)
	- No, I will handle that myself (自己处理)
  1. 项目初始化并启动

切记一定要进入项目的文件夹,否则会报找不到package.json

cd work(进入项目所在文件夹)

# 启动项目
npm run dev

快速搭建前端页面并与后端交互_第1张图片
快速搭建前端页面并与后端交互_第2张图片
5. 连接链接,访问
快速搭建前端页面并与后端交互_第3张图片
项目结构:
快速搭建前端页面并与后端交互_第4张图片

1.2 vue+elementUi实现注册登录

首先已经通过1.1的vue脚手架搭建好了vue基本框架,通是编写对应js

# 安装element-ui
npm i element-ui -S

vue项目结构介绍:
快速搭建前端页面并与后端交互_第5张图片

①新建vue文件

新建两个Vue文件,Login.vue和Register.vue

Login.vue:

<template>
  <div class="loginbody">
    <div class="logindata">
      <div class="logintext">
        <h2>Welcomeh2>
      div>
      <div class="formdata">
        <el-form ref="form" :model="form" :rules="rules">
          <el-form-item prop="username">
            <el-input
              v-model="form.username"
              clearable
              placeholder="请输入账号"
            >el-input>
          el-form-item>
          <el-form-item prop="password">
            <el-input
              v-model="form.password"
              clearable
              placeholder="请输入密码"
              show-password
            >el-input>
          el-form-item>
        el-form>
      div>
      <div class="tool">
        <div>
          <el-checkbox v-model="checked" @change="remenber"
            >记住密码el-checkbox
          >
        div>
        <div>
          <span class="shou" @click="forgetpas">忘记密码?span>
        div>
      div>
      <div class="butt">
        <el-button type="primary" @click.native.prevent="login('form')"
          >登录el-button
        >
        <el-button class="shou" @click="register">注册el-button>
      div>
    div>
  div>
template>

<script>
import { login } from "@/api/login";

export default {
  name: "Login",
  data() {
    return {
      form: {
        password: "",
        username: "",
      },
      checked: false,
      rules: {
        username: [
          { required: true, message: "请输入用户名", trigger: "blur" },
          { max: 10, message: "不能大于10个字符", trigger: "blur" },
        ],
        password: [
          { required: true, message: "请输入密码", trigger: "blur" },
          { max: 10, message: "不能大于10个字符", trigger: "blur" },
        ],
      },
    };
  },
  mounted() {
    if (localStorage.getItem("news")) {
      this.form = JSON.parse(localStorage.getItem("news"));
      this.checked = true;
    }
  },
  methods: {
    login(form) {
      this.$refs[form].validate((valid) => {
        if (valid) {
          login(this.form)
            .then((res) => {
              if (res.code === 200) {
                setToken(res.data.token);
                localStorage.setItem("USERNAME", res.data.username);
                this.$message({
                  message: "登录成功啦",
                  type: "success",
                  showClose: true,
                });
                this.$router.replace("/");
              } else {
                this.$message({
                  message: "账户名或密码错误",
                  type: "error",
                  showClose: true,
                });
              }
            })
            .catch((err) => {
              this.$message({
                message: "账户名或密码错误",
                type: "error",
                showClose: true,
              });
            });
        } else {
          return false;
        }
      });
    },
    remenber(data) {
      this.checked = data;
      if (this.checked) {
        localStorage.setItem("news", JSON.stringify(this.form));
      } else {
        localStorage.removeItem("news");
      }
    },
    forgetpas() {
      this.$message({
        type: "info",
        message: "功能尚未开发额",
        showClose: true,
      });
    },
    register() {
      //跳转到注册页面
      this.$router.push({path:`register`})
    },
  },
};
script>

<style scoped>
.loginbody {
  width: 100%;
  height: 100%;
  min-width: 1000px;
  background-image: url("../assets/login.png");
  background-size: 100% 100%;
  background-position: center center;
  overflow: auto;
  background-repeat: no-repeat;
  position: fixed;
  line-height: 100%;
  padding-top: 150px;
}

.logintext {
  margin-bottom: 20px;
  line-height: 50px;
  text-align: center;
  font-size: 30px;
  font-weight: bolder;
  color: white;
  text-shadow: 2px 2px 4px #000000;
}

.logindata {
  width: 400px;
  height: 300px;
  transform: translate(-50%);
  margin-left: 50%;
}

.tool {
  display: flex;
  justify-content: space-between;
  color: #606266;
}

.butt {
  margin-top: 10px;
  text-align: center;
}

.shou {
  cursor: pointer;
  color: #606266;
}
style>

Register.vue:

<template>
  <div class="login clearfix">
    <div class="login-wrap">
      <el-row type="flex" justify="center">
        <el-form ref="loginForm" :model="user" status-icon label-width="80px">
          <h3>注册h3>
          <hr>
          <el-form-item prop="username" label="用户名">
            <el-input v-model="user.username" placeholder="请输入用户名">el-input>
          el-form-item>
          <el-form-item prop="email" label="邮箱">
            <el-input v-model="user.email" placeholder="请输入邮箱">el-input>
          el-form-item>
          <el-form-item prop="password" label="设置密码">
            <el-input v-model="user.password" show-password placeholder="请输入密码">el-input>
          el-form-item>
          <el-form-item>
            <el-button type="primary" icon @click="doRegister()">注册账号el-button>
          el-form-item>
        el-form>
      el-row>
    div>
  div>
template>
 
<script>
import axios from "axios";
export default {
  name: "login",
  data() {
    return {
      user: {
        username: "",
        email: "",
        password: ""
      },
    };
  },
  created() {
    // console.log($);
    // console.log("1111");
  },
  methods: {
    doRegister() {
      if (!this.user.username) {
        this.$message.error("请输入用户名!");
        return;
      } else if (!this.user.email) {
        this.$message.error("请输入邮箱!");
        return;
      } else if (this.user.email != null) {
        var reg = /^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/;
        if (!reg.test(this.user.email)) {
          this.$message.error("请输入有效的邮箱!");
        } else if (!this.user.password) {
          this.$message.error("请输入密码!");
          return;
        } else {
          // this.$router.push({ path: "/" }); //无需向后台提交数据,方便前台调试
          axios
            .post("/register/", {
              name: this.user.username,
              email: this.user.email,
              password: this.user.password
            })
            .then(res => {
              // console.log("输出response.data", res.data);
              // console.log("输出response.data.status", res.data.status);
              if (res.data.status === 200) {
                this.$router.push({ path: "/" });
              } else {
                alert("您输入的用户名已存在!");
              }
            });
        }
      }
    }
  }
};
script>
 

<style scoped>
.login {
  width: 100%;
  height: 740px;
  background-size: cover;
  overflow: hidden;
}
.login-wrap {
  background-size: cover;
  width: 400px;
  height: 300px;
  margin: 215px auto;
  overflow: hidden;
  padding-top: 10px;
  line-height: 20px;
}
 
h3 {
  color: #0babeab8;
  font-size: 24px;
}
hr {
  background-color: #444;
  margin: 20px auto;
}
 
.el-button {
  width: 80%;
  margin-left: -50px;
}
style>

②新建js文件

login.js:

登录请求是通过引入外部js实现,注册请求则是通过写入vue页面中的script实现,没有做复用【当然也可以封装到外部,写在login.js或register.js中】

import Axios from "axios";
import {get, post} from "./http";

// post 请求
export const login = (params) => post(`login`, params)

快速搭建前端页面并与后端交互_第6张图片

③添加路由配置

添加路由配置router文件夹下的index.js
一定要加上mode: "history",同时要import组件

index.js:

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Register from '@/components/Register'
import Login from '@/components/Login'

Vue.use(Router)

export default new Router({
  routes: [
    // {
    //   path: '/',
    //   name: 'HelloWorld',
    //   component: HelloWorld
    // },
    {
      path:'/',
      name: 'Login',
      component: Login
    },
    {
      path: '/register',
      name: 'Register',
      component: Register
    }
  ],
  mode: "history"
})

path:是指跳转路径,name是名称,component是组件名(对应.vue文件)

例如:/register表示如果路径是localhost:8080/register,就跳转到Register.vue文件夹下

④实例化vue对象,引入axios

实例化vue对象,引入需要使用的工具,如:axios、element-ui等

main.js:

import Vue from 'vue'
import App from './App'
import router from './router'
import axios from 'axios'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
 
Vue.use(ElementUI)
//全局配置
Vue.prototype.$axios = axios
Vue.config.productionTip = false
 
/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: ''
})

⑤效果

登录页面:
快速搭建前端页面并与后端交互_第7张图片

注册页面:
快速搭建前端页面并与后端交互_第8张图片

图片自取,页面图片,放在assets下,并命名为login.png:
快速搭建前端页面并与后端交互_第9张图片

拓展:操作js(与后端交互)

①封装http请求

src/api/http.js
快速搭建前端页面并与后端交互_第10张图片

http.js:

// 封装通用请求
import axios from 'axios'
import router from '../router'
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:8090'

// 响应拦截器
axios.interceptors.response.use(
  response => {
    // 如果response里面的status是200,说明访问到接口了,否则失败
    if (response.status === 200) {
      // Promise:异步框架
      return Promise.resolve(response)
    } else {
      return Promise.reject(response)
    }
  },
  error => {
    if (error.response.status) {
      // 根据访问失败返回的状态码,分别做不同的处理
      switch (error.response.status) {
        case 401: // 未登录
          router.replace({
            path: '/',
            query: {
              redirect: router.currentRoute.fullPath // 存之前访问地址
            }
          })
          break
        case 404: // not found
          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)
      })
  })
}

②定义请求的js

例如文件为:index.js【文件放在src/api/index.js】

//查询所有歌手【普通的get请求,不带参数】
export const getAllSinger = () => get(`singer/selectAll`)

//根据歌手性别查询【带参数的get请求】
export const getSingerOfSex = (sex) => get(`singer/selectSingerOfSex?sex=${sex}`)

//返回当前的评论列表【根据传参发送不同请求】
export const getAllComment = (type, id) => {
  if(type == 0){ //type: 0 歌曲
    return get(`comment/commentOfSongId?songId=${id}`);
  }else{ //歌单
    return get(`comment/commentOfSongListId?songListId=${id}`);
  }
}

//新增收藏【post请求】
export const setCollect = (params) => post(`collect/add`, params);

//下载音乐【异步请求】
export const download = (url) => Axios({
  method: 'get',
  url: url,
  responseType: 'blob'
})

③在页面中引入并使用

在xxx.vue的

你可能感兴趣的:(template,前端,webpack,vue.js,前后端分离,前后端交互)