B Station Cloud E Office Vue + SpringBoot Proyecto de separación frontal y posterior: compilación del proyecto Vue.js (1)

Directorio de notas de estudio del front-end del proyecto

B station cloud E office Vue + SpringBoot proyecto de separación frontal y posterior: compilación del proyecto vue.js

B station cloud E office Vue + SpringBoot proyecto de separación de front-end y back-end: el front-end obtiene dinámicamente el directorio del menú

Directorio de notas de estudio de backend del proyecto

B station cloud E office Vue + SpringBoot proyecto de separación frontal y posterior: arquitectura de tres niveles MVC para construir un proyecto en segundo plano

Descripción del Proyecto

Antecedentes del proyecto: Afectadas por la epidemia, muchas empresas han pasado de la oficina en línea a la oficina fuera de línea. Con el aumento del número de personas que trabajan en línea, las ventajas de la oficina en línea se vuelven gradualmente prominentes: al automatizar el flujo de trabajo, ahorrar costos de oficina corporativa, lograr una oficina ecológica y mejorar la eficiencia de la oficina.

Introducción del proyecto: Este proyecto implementa un sistema de oficina en línea para gestionar los asuntos diarios de la oficina: aprobación de procesos diarios, noticias, avisos, anuncios, información de archivos, finanzas, personal, gastos, activos, administración, proyectos, oficina móvil, etc. A través del software, el sistema de oficina se puede administrar según su conveniencia y se puede mejorar el nivel general de administración y operación.

Método de implementación: este proyecto se basa en Vue + Spring Boot para crear un proyecto de separación de front-end y back-end. La interfaz se construye utilizando el marco de código abierto Vue, que es muy activo en la comunidad. En pocas palabras, la idea central de la separación de front-end y back-end es que la página de front-end llama a la API restuful de back-end para la interacción de datos a través de ajax, mientras que una aplicación de una sola página (aplicación web de una sola página, SPA) Tiene solo una página y cuando el usuario interactúa con la aplicación. Una aplicación web que actualiza dinámicamente la página de vez en cuando.

Los datos JSON se comunican entre el front-end y el back-end a través de la API RESTful. A diferencia de JSP y similares, el backend no involucra el contenido de la página en sí. Al desarrollar, el front-end usa el servidor front-end (Nginx) y el back-end usa el servidor back-end (Tomcat). Cuando desarrollo el contenido del front-end, puedo reenviar la solicitud del front-end a el back-end a través del servidor front-end (llamado proxy inverso), para que pueda observar los resultados en tiempo real, y no necesita saber cómo se implementa el backend, solo necesita conocer las funciones proporcionadas por La interfaz.

1. Arquitectura Técnica

 2. Arquitectura técnica de front-end

Este proyecto adopta el modo de desarrollo de separación de front-end y back-end, y utiliza Spring Boot para construir el back-end. Los módulos front-end se dividen en: inicio de sesión, gestión de puestos, gestión de títulos, gestión de departamentos, calendario del operador, gestión de empleados, gestión de cuentas salariales, centro personal, chat en línea.

Las tecnologías utilizadas en el front end son:

    Construcción del proyecto: Vue-cli

    Gestión estatal: Vuex

    Gestión de enrutamiento: VueRouter

    Interfaz UI: Elemento UI

    Marco de comunicación: Axios

    Sintaxis de interfaz de usuario: ES6

    Embalaje: paquete web

    Chat en vivo: WebSocket

    Fuente: fuente impresionante

    Carga y descarga de archivos: js-file-download

    Proyecto de código abierto de chat en línea: vue-chat

3. Arquitectura técnica de back-end

Marco de desarrollo principal de back-end: SpringBoot+Spring MVC+MyBatisPlus. Utilice Spring Security para autenticación de seguridad y gestión de autoridad, Redis para almacenamiento en caché, RabbitMq para enviar correos electrónicos, utilice EasyPOI para importar y exportar datos de empleados y utilice WebSocket para chatear en línea

    Marco de seguridad: seguridad de primavera

    Ficha: JWT

    Código de verificación gráfico: Kaptcha

    Caché: redis

    Importación y exportación de documentos: EasyPOI

    Message Queuing: RabbitMQ realiza procesamiento asincrónico y envía correos electrónicos

    Componente de correo: correo

    Chat en vivo: WebSocket

    Servidor de archivos: FastDFS

    Base de datosMySQL+Redis

1. Cree un proyecto vue.js

1. introducción a la vista

        Aunque JS nativo puede realizar la mayoría de las funciones, es demasiado engorroso o tiene defectos, por lo que la mayoría de los desarrolladores elegirán primero la solución de desarrollo del marco. En términos de marco, se deben dominar conocimientos básicos como el ciclo de vida, la función de enlace, el DOM virtual y el algoritmo Diff. Entre ellos, se deben dominar la comunicación entre componentes en diferentes niveles, la gestión del estado de los componentes, los saltos de enrutamiento, la optimización del rendimiento de los componentes, etc. flexible grado de uso. En el desarrollo de proyectos front-end, podemos utilizar Vue en distintos grados según la situación real. Los proyectos creados con Vue CLI (o escritos como vue-cli, es decir, andamio de Vue) pueden reflejar mejor las características de Vue. Podemos experimentar esto lentamente en el siguiente contenido.

El desarrollo modular consiste en dividir un archivo grande en muchos archivos pequeños independientes e importarlos en diferentes componentes según sea necesario, lo que reduce el acoplamiento del código y mejora la reutilización del código. Vue desarrolla una aplicación de una sola página con una sola entrada html y el resto se denomina componentes. El verdadero punto de entrada es main.js. Vue: marco js progresivo, que implementa gradualmente nuevas funciones. Como desarrollo modular, enrutamiento, gestión de estado, etc.

1.1 ejes

Marco de comunicación front-end. Debido a que el límite de vue es muy claro, es para procesar DOM, por lo que no tiene capacidades de comunicación. En este momento, necesita usar un marco de comunicación adicional para interactuar con el servidor; por supuesto, también puede usar directamente Función de comunicación AJAX proporcionada por jQuery.

1.2 enrutador Vue

Vue Router es el administrador de enrutamiento oficial para Vue.js. Está profundamente integrado con el núcleo de Vue.js, lo que facilita la creación de aplicaciones de una sola página. Las características incluidas son:

Tablas de enrutamiento/ver anidadas

Configuración de enrutamiento modular basada en componentes

Parámetros de ruta, consultas, comodines

Ver efecto de transición basado en el sistema de transición Vue.js

Control de navegación detallado

Enlaces con clases CSS activadas automáticamente

Modo historial HTML5 o modo hash, degradado automáticamente en IE9

comportamiento de la barra de desplazamiento personalizada

1.3 paquete web

        La principal diferencia entre el desarrollo front-end y otros trabajos de desarrollo es que el front-end se basa en un trabajo de organización y codificación en varios idiomas y niveles múltiples y, en segundo lugar, la entrega de productos front-end se basa en el navegador, y estos recursos se ejecutan en el navegador mediante carga incremental. Cómo organizar estos códigos y recursos fragmentados en el entorno de desarrollo y garantizar su carga y actualización rápidas y elegantes en el navegador requiere un sistema modular.

        webpack es un paquete de módulos estático (paquete de módulos) para aplicaciones JavaScript modernas. Cuando webpack procesa una aplicación, crea recursivamente un gráfico de dependencia que incluye todos los módulos que la aplicación necesita y luego empaqueta todos estos módulos en uno o más paquetes. La idea del paquete web: todo es un módulo, es decir, el paquete web no solo está modularizado por JavaScript, sino que también es necesario modularizar recursos como CSS, imágenes y fuentes. Webpack: empaquetador de módulos, la función principal es empaquetar, comprimir, fusionar y cargar en orden. Como empaquetar ES6 en ES5

        En el archivo de configuración del paquete web, main.js está configurado como archivo de entrada y nuestro proyecto accede a index.html de forma predeterminada, este archivo se superpone perfectamente con el contenedor en el componente App.vue, es decir, el componente está montado en el índice. página, y luego solo necesitamos construir otros componentes. En el componente de la aplicación, también podemos introducir, registrar y aplicar otros componentes. Podemos representar otros componentes en el componente de la aplicación a través del enrutamiento, por lo que solo debemos prestar atención a cada uno Componente Función perfecta. Es decir, la página predeterminada de vue es index.html, y el componente grande App.vue se monta en el índice, y luego todos los demás subcomponentes (hello.vue, etc.) pertenecen al componente principal App.vue.

1.4 módulos ES6

        Vue generalmente se escribe en es6 y se exporta con la exportación predeterminada, que puede contener datos, ciclo de vida (montado, etc.), métodos (métodos), etc. Para obtener una sintaxis específica, consulte el documento vue.js. El estándar ES6 agrega una definición de sistema de módulos a nivel de lenguaje javascript. La idea de diseño de los módulos ES6 es ser lo más estático posible, de modo que las dependencias de los módulos, así como las variables de entrada y salida, puedan determinarse en el momento de la compilación. Tanto los módulos CommonJS como AMD solo pueden determinar estas cosas en tiempo de ejecución.

1.5 marco de interfaz de usuario

Element-UI, lanzado por Ele.me

1.6 vista

Un patrón de gestión de estado desarrollado específicamente para aplicaciones.

npm install vuex --save

Cree un nuevo directorio de tienda en el directorio src, cree un nuevo archivo index.js e impórtelo a main.js

Error de inicio de instalación de vuex "exportar 'reloj' no se encontró en 'vue'

Si tu versión de vue es 2.X, puedes solucionarlo actualizando vuex a 3.XX

instalación npm --guardar [email protected]

Si tu versión de vue es 3.X, puedes solucionarlo actualizando vuex a 4.XX

instalación npm --save [email protected] instalación npm --save [email protected]

2. Construya el proyecto vue.js

2.1 Preparación del entorno

Instale Node.js (>=6.x, preferido 8.x) Este proyecto es la versión v14.18.0

2.2 Instalar Vue CLI

Debido a que necesita usar npm para instalar Vue CLI, y npm está integrado en Node.js, el primer paso debemos instalar Node.js, visite el sitio web oficial de Node.js, puede descargarlo desde la página de inicio.

Una vez completada la descarga, ejecute el paquete de instalación y siga el siguiente paso.

Luego ingrese nodo -v en cmd para verificar si el nodo se instaló correctamente.

Ingrese npm -v para ver el número de versión de npm

Ingrese npm -g install npm para actualizar npm a la última versión.

Después de eso, instale el andamio con npm install -g vue-cli. (Este proyecto utiliza la versión 2.9.6)

Tenga en cuenta que la versión 2.x de Vue CLI se instala de esta manera y la última versión debe instalarse a través de npm install -g @vue/cli. La nueva versión puede usar la interfaz gráfica para inicializar el proyecto y agregar el contenido del monitoreo del estado del proyecto, pero las dependencias del proyecto creadas con la nueva versión no coinciden con este tutorial y es problemático descartarlas.

Acelerador de espejo Taobao cnpm instalado Node.js

En la mayoría de los casos, use npm y cnpm si no puede instalarlo.

npm instala cnpm -g

Instalación de npm --registry=https://registry.npm.taobao.org

3. Construya el proyecto front-end

El método general construye el proyecto directamente usando la línea de comando.

Luego ejecute el comando vue init webpack yeb, donde webpack usa webpack como plantilla para hacer referencia al proyecto generado, y también se puede reemplazar con parámetros como pwa y simple, que no se describirán aquí.

Habrá algunas indicaciones durante la ejecución del programa. Puede presionar Enter hasta el final de acuerdo con la configuración predeterminada, o puede modificarlo según sea necesario. Por ejemplo, si la siguiente imagen me pregunta si el nombre del proyecto es wj-vue , simplemente presione Enter para confirmar.

Aquí también se le preguntará si desea instalar vue-router, debe elegir sí, es decir, presionar Enter o presionar Y. Vue-router es la clave para que podamos crear una aplicación de una sola página.

Y si desea usar es-lint, seleccione N.

Luego espere a que se construya el proyecto y estará bien.

La carpeta del proyecto se genera en el directorio del espacio de trabajo y debe ejecutar npm install en esta carpeta, npm run build y luego ejecutar npm run dev.

Visite http://localhost:8080 , vea la demostración de la página web y ¡listo!

Nota: En el proyecto vue, a veces es necesario ejecutar npm run server para iniciar el proyecto y, a veces, es necesario utilizar npm run dev. ¿Cuál es la diferencia?

la diferencia

De forma predeterminada, dev es el comando admitido por [email protected] de forma predeterminada ;

De forma predeterminada, server es el comando compatible con [email protected] y superiores.

4. Análisis de la estructura del proyecto Vue

├── construir --------------------------------- Archivos de configuración relacionados con la construcción del proyecto (paquete web), parámetros de configuración, etc. encendido, generalmente no se mueve

│ ├── build.js -------------------------- archivo de configuración de empaquetado del paquete web

│ ├── check-versions.js ------------------------------ Verifique npm, versión de nodejs

│ ├── dev-client.js ---------------------------------- Configuración del entorno

│ ├── dev-server.js ---------------------------------- Cree un servidor express y configure middleware, que inicia un servidor recargable en caliente para proyectos de desarrollo

│ ├── utils.js --------------------------------------- Configurar la ruta del recurso , Configurar el cargador CSS

│ ├── vue-loader.conf.js ----------------------- Configurar el cargador CSS, etc.

│ ├── webpack.base.conf.js --------------------------- configuración básica del paquete web

│ ├── webpack.dev.conf.js ---------------------------- configuración del paquete web para desarrollo

│ ├── webpack.prod.conf.js --------------------------- configuración del paquete web para empaquetado

├── config ----------------------------------- Directorio de configuración, incluido el número de puerto, etc. Podemos usar el valor predeterminado para principiantes.

│ ├── dev.env.js -------------------------- Variables de entorno de desarrollo

│ ├── index.js ---------------------------- archivo de configuración del proyecto

│ ├── prod.env.js ------------------------- variables de entorno de producción

│ ├── test.env.js ------------------------- variables de entorno de prueba

├── node_modules ---------------------------- módulos dependientes del proyecto cargados por npm

├── src ------------------------------------- El directorio que queremos desarrollar, básicamente Todo lo que haces está en este directorio.

│ ├── activos ------------------------------ Archivos estáticos, coloque algunas imágenes, como logotipos, etc.

│ ├── componentes -------------------- Directorio de componentes, almacenar archivos de componentes, no se puede utilizar.

│ ├── principal.js ----------------------------- principal js

│ ├── App.vue ----------------------------- componente de entrada del proyecto, también podemos escribir el componente directamente aquí, y El directorio de componentes no se utiliza.

│ ├── enrutador ------------------------------ enrutamiento

├── estático ---------------------------- Directorio de recursos estáticos, como imágenes, fuentes, etc.

├── .babelrc--------------------------------- archivo de configuración de babel

├── .editorconfig---------------------------- configuración del editor

├── .gitignore------------------------------- Configura archivos que git puede ignorar

├── index.html ------------------------------ Archivo de entrada de la página de inicio, puede agregar metainformación o código estadístico de.

├── package.json ---------------------------- archivo de configuración de nodo, que registra algunos comandos y dependencias y una breve información de descripción del proyecto

├── .README.md------------------------------- Documentación del proyecto en formato Markdown. Escribe como quieras, si no sabes escribir, consulta los proyectos con muchas estrellas en github para ver cómo escriben.

Explicación detallada de los documentos principales.

4.1 src - [archivo principal del proyecto]

En el proyecto vue-cli, se debe dominar la carpeta src, porque básicamente todo lo que se debe hacer está en este directorio.

4.2 index.html - [Página de inicio]

index.html es igual que otros html, pero generalmente solo define un nodo raíz vacío. La instancia definida en main.js se montará debajo del nodo raíz, el contenido se completará con componentes vue y el archivo creado se inyectado automáticamente, lo que significa que otro contenido que escribamos se mostrará en este div. Solo hay un archivo html en todo el proyecto, por lo que esta es una aplicación de una sola página. Cuando abrimos esta aplicación, puede haber muchas páginas en la superficie, pero en realidad están todas en un div.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>vuedemo</title>
  </head>
  <body>
      <!-- 定义的vue实例将挂载在#app节点下 -->
    <div id="app"></div>
  </body>
</html>

4.3 App.vue - [componente raíz]

Este archivo se denomina "componente raíz" porque en este componente se incluyen otros componentes. Un archivo .vue es un tipo de archivo personalizado, similar en estructura a html, y un archivo .vue es un componente de vue.

Una página vue generalmente consta de tres partes: plantilla (plantilla), js (script), estilo (estilo)

<!-- 模板 -->
<template>
  <div id="app">
    <img src="./assets/logo.png">
    <router-view></router-view>
  </div>
</template>

<!-- script -->
<script>
export default {
  name: 'app'
}
</script>

<!-- 样式 -->
<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

【plantilla】

La plantilla solo puede contener un nodo padre, es decir, solo puede haber un div de nivel superior (por ejemplo, en el código anterior, el nodo padre es el div cuyo nodo padre es #app, que no tiene nodos hermanos ). También hay una <div id="app"> aquí, pero no tiene nada que ver con la de index.html. Este id=app solo corresponde al siguiente CSS.
<router-view></router-view> es una vista de subenrutamiento y todas las páginas de enrutamiento posteriores se muestran aquí. Para hacer una metáfora, <router-view> es similar a una ranura: al saltar a una determinada ruta, la página debajo de la ruta se inserta en esta ranura para su renderización y visualización.

【guion】

El contenido de la etiqueta <script> es el script del componente, es decir, el código js. El valor predeterminado de exportación es la sintaxis de ES6, lo que significa exportar este componente como un todo, y luego puede usar import para importar el componente. El contenido entre llaves son las propiedades relevantes de este componente.
Vue generalmente se escribe en es6 y se exporta con la exportación predeterminada, que puede contener datos, ciclo de vida (montado, etc.), métodos (métodos), etc. Para obtener una sintaxis específica, consulte el documento vue.js.

【estilo】

El estilo está envuelto por la etiqueta de estilo, que afecta a todo el mundo de forma predeterminada. Si desea definir el alcance para que solo funcione bajo este componente, debe agregar el alcance a la etiqueta. Si desea importar archivos CSS externos, debe Primero debe instalar el paquete de dependencia css-loader del proyecto, abra cmd, ingrese al directorio del proyecto, ingrese npm install css-loader y presione Entrar. Una vez completada la instalación, puede importar los archivos CSS necesarios bajo la etiqueta de estilo, por ejemplo:

<style>
    import './assets/css/public.css'
</style>

4.4 main.js——[archivo de entrada]

main.js presenta principalmente el marco de Vue, los componentes raíz y la configuración de enrutamiento, y define la instancia de Vue. Los siguientes componentes: {App} es el componente raíz importado App.vue. Los complementos también se pueden introducir más adelante; por supuesto, los complementos deben instalarse primero.
Anteriormente dijimos que <div id="app"> en App.vue no tiene nada que ver con <div id="app"> en index.html, entonces, ¿cómo se conectan estos dos archivos? Veamos el código del archivo de entrada main.js.

/*引入vue框架*/
import Vue from 'vue'
/*引入根组件*/
import App from './App'
/*引入路由设置*/
import router from './router'

/*关闭生产模式下给出的提示*/ 
Vue.config.productionTip = false

/*定义实例*/ 
new Vue({
  el: '#app',
  router,
  template: '<App/>',
  components: { App }
})

Se importan varios módulos en la parte superior, entre los cuales el módulo vue está en node_modules, la aplicación es el componente definido en App.vue y el enrutador es la ruta definida en la carpeta del enrutador. Vue.config.productionTip = false, la función es evitar que vue genere sugerencias de producción al inicio. En este archivo js, ​​creamos un objeto Vue (instancia), y el atributo el proporciona un elemento DOM que ya existe en la página como destino de montaje del objeto Vue, aquí a través de <div id="app en index.html El id="app" en "><div> y "#app" aquí están montados. enrutador significa que el objeto contiene Vue Router y utiliza las rutas definidas en el proyecto. componentes indica los componentes de Vue contenidos en el objeto, y la plantilla utiliza una plantilla de cadena como identificador de la instancia de Vue, que es similar a definir una etiqueta html.

5. Instalación de paquetes relacionados

5.1 Instalar Element-UI

La dirección oficial de Element es http://element-cn.eleme.io/#/zh-CN
1. Instale Element
Según la descripción del documento oficial, en la carpeta del proyecto, ejecute npm i element-ui -S para llegar
aquí Insertar descripción de imagen
2. Importar elemento
La importación se divide en dos modos: importación completa e importación bajo demanda. La importación bajo demanda puede reducir el tamaño del proyecto. Aquí elegimos importación completa.
Según la documentación, necesitamos modificar main.js de la siguiente manera

import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

5.2 instalar axios

Vaya a la carpeta del proyecto y ejecute
npm install --save axios para instalar este módulo.

5.3 Instalar Vuex

Vuex, es una solución de gestión de estado especialmente desarrollada para Vue, donde podemos definir las variables y métodos que deben pasarse y usarse en cada componente. No lo he usado antes, por lo que es un dolor de cabeza pasar valores de diferentes componentes, y tengo que escribir mucho código redundante para llamar a los valores de diferentes componentes, así que te recomiendo que te familiarices. con este método de gestión desde el principio.

ejecute npm install vuex --save

Después de eso, cree un almacén de carpetas en el directorio src, cree un nuevo archivo index.js en el directorio e introduzca vue y vuex en el archivo. El código es el siguiente:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

5.4 Instalar VueRouter

npm instala vue-router --save-dev

Vue-router es el complemento de enrutamiento oficial de Vue.js, está profundamente integrado con vue.js y es adecuado para crear aplicaciones de una sola página. La aplicación de una sola página de Vue se basa en enrutamiento y componentes, y el enrutamiento se utiliza para establecer rutas de acceso y mapear rutas y componentes.

Debajo de la carpeta del enrutador, hay un index.js, que es el archivo de configuración de enrutamiento. Se pueden configurar varias rutas, como '/index', '/list', etc. Por supuesto, primero se debe introducir el componente y luego se debe configurar la ruta para el componente.

5.5 Instalar fuente impresionante

npm instala fuente impresionante

2. Diseño de la página de inicio de sesión

1. Diseño de estilo de página

Para diseñar la interfaz, debemos centrarnos en el html dentro de la etiqueta <template> y el CSS dentro de la etiqueta <style>. Generalmente usamos Form para crear el cuadro de inicio de sesión, abrimos el documento del componente Element (http://element-cn.eleme.io/#/zh-CN/component/) y descubrimos que nos proporciona una gran cantidad de componentes de Form. , podemos hacer clic en "Mostrar código" para copiar la pieza que necesitamos.

Sin embargo, parece que no existe ningún formulario que sea particularmente adecuado para nuestro escenario de aplicación, o estos son relativamente complicados y solo necesitamos una pequeña parte de ellos. Despliega la página y podrás ver la documentación sobre las propiedades, eventos, métodos, etc. de este componente. De acuerdo con esta documentación, podemos construir el formulario requerido por nosotros mismos.

2. Código de la página de inicio de sesión: vistas/Login.vue

El código de verificación devuelve una imagen a través del backend. Los formularios unen reglas a través de reglas, agregan atributos a elementos a través de accesorios y escriben reglas en reglas. Método de validación: this.$refs.loginForm.validate.

/captcha devuelve información

/login mensaje de retorno de inicio de sesión

Después de iniciar sesión correctamente, almacene el token de usuario en sessionStorage; juzgue si el token existe en el interceptor de solicitudes y luego verifique el token para cada solicitud. Si existe, solicite llevar el token y colóquelo en el parámetro de Autorización; el backend verifica la ficha.

Una vez que el inicio de sesión de front-end sea exitoso, use this.$router.replace('/home') para saltar a la página de inicio. Una vez reemplazado el método de reemplazo, al hacer clic en el botón Atrás del navegador no se saltará a la página de inicio de sesión. Si el inicio de sesión falla, el backend devuelve el motivo del error.

Cuando el usuario no ha iniciado sesión, si el usuario no visita la página de inicio de sesión con http://localhost:8080/#/ , pero visita una ruta a la que solo se puede acceder después de iniciar sesión, como http://localhost:8080 /#/sys/básico . Es necesario discutirlo según la situación: 1. El usuario puede ingresar la dirección de la página de inicio o una dirección incorrecta y permitirle saltar a la página de inicio después de iniciar sesión exitosamente; 2. De lo contrario, saltará a la dirección que ingresó exitosamente. .

this.$router.replace((ruta === '/' || ruta === indefinida)? '/home': ruta)

<template>
  <div>
    <el-form
      v-loading="loading"
      element-loading-text="正在登录......"
      element-loading-spinner="el-icon-loading"
      element-loading-background="rgba(0, 0, 0, 0.8)"
      ref="loginForm" :model="loginForm" :rules="rules" class="loginContainer">
      <h3 class="loginTitle">系统登录</h3>
      <el-form-item prop="username">
        <el-input type="text" v-model="loginForm.username" placeholder="请输入用户名"></el-input>
      </el-form-item>
      <el-form-item prop="password">
        <el-input type="password" v-model="loginForm.password" placeholder="请输入密码"></el-input>
      </el-form-item>
      <el-form-item prop="code">
        <el-input type="text" v-model="loginForm.code" placeholder="点击图片更换验证码"
                  style="width: 250px;margin-right: 5px;"></el-input>
        <img :src="captchaUrl" @click="updateCaptcha">
      </el-form-item>
      <el-button type="primary" style="width: 100%" @click="submitLogin">登录</el-button>
    </el-form>
  </div>
</template>
<script>
  export default {
    name: 'Login',
    components: {},
    props: [],
    data() {
      return {
        // 验证码
        captchaUrl:'api/captcha?time=' + new Date(),//获取响应码后端接口
        loginForm: {
          username: 'admin',
          password: '123',
          code: '',
        },
        loading: false, // 加载中
        checked: true,
        //校验规则,与表单绑定
        rules: {
          username: [{required: true, message: '请输入用户名', trigger: 'blur'}],
          password: [{required: true, message: '请输入密码', trigger: 'blur'}],
          code: [{required: true, message: '请输入验证码', trigger: 'blur'}]
        }
      }
    },
    mounted(){

    },
    methods: {
      // 点击刷新验证码
      updateCaptcha() {
      this.captchaUrl="api/captcha?time="+new Date();

      },
      submitLogin() {
        // 登录
        this.$refs.loginForm.validate((valid) => {
          if (valid) {
            this.loading = true;//准备调登录接口时,出现正在加载
            //第一个参数请求后端的地址,第二个参数,传给后端的数据
            this.postRequest('/login', this.loginForm).then(resp => {
              this.loading = false;//登录成功后关闭
              if (resp) {
                // 存储用户 token 到 sessionStorage
                const tokenStr = resp.obj.tokenHead + resp.obj.token;
                window.sessionStorage.setItem('tokenStr', tokenStr);
                // 跳转到首页
                // this.$router.push('/home') // 路由跳转,可以回退到上一页
                this.$router.replace('/home') // 路径替换,无法回退到上一页

                // 页面跳转
                // 拿到用户要跳转的路径
                let path = this.$route.query.redirect;
                // 用户可能输入首页地址或错误地址,让他跳到首页,否则跳转到他输入的地址
                this.$router.replace((path === '/' || path === undefined) ? '/home' : path)
              }

            })
          } else {
            this.$message.error('请输入所有字段!');
            return false;
          }
        })
      }
    }
  }
</script>
<style>
  .loginContainer {
    border-radius: 15px;
    background-clip: padding-box;
    /*属性规定背景的绘制区域 背景被裁剪到内边距框。 margin: 180 px auto;*/
    margin: 180px auto;
    width: 350px;
    padding: 15px 35px;
    background: #fff;
    border: 1px solid #eaeaea;
    box-shadow: 0 0 25px #cac6c6;
    /*  X轴偏移量 Y轴偏移量 [阴影模糊半径] [阴影扩展] [阴影颜色] [投影方式]; */
  }

  .loginTitle {
    margin: 0 auto 40px auto;
    text-align: center;
  }

  .loginRemember {
    text-align: left;
    margin: 0 0 15px 0;
  }

  /*验证码*/
  .el-form-item__content {
    display: flex;
    align-items: center;
  }
</style>

 En SessionStorage.setItem(), para permitir que axios obtenga autenticación de token al realizar la siguiente solicitud, después de iniciar sesión, obtenga el token y colóquelo en sessionStrorage.         

    // Almacena el token de usuario en sessionStorage

                const tokenStr = resp.obj.tokenHead + resp.obj.token;

                ventana.sessionStorage.setItem('tokenStr', tokenStr);

3. Configurar el enrutamiento de páginas: router/index.js

import Vue from 'vue'
import Router from 'vue-router'
import Login from "@/views/Login";

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'Login',
      component: Login,
      hidden: true // 不会被循环遍历出来
  },
  ]
})

4. Resolver dominios cruzados de front-end y back-end

El puerto de front-end está predeterminado en 8080. Suponiendo que el puerto de back-end es 8081, ¿cómo accede 8080 a los datos de 8081? Implementamos el reenvío automático de puertos a través de Node.js. La política del mismo origen del navegador: dos páginas deben tener el mismo protocolo (protocolo) host (host) número de puerto (puerto).

Al solicitar una interfaz, aparecen Access-Control-Allow-Origin, etc., lo que indica que la solicitud es entre dominios. La forma de resolver dominios cruzados en vue: configure el archivo vue.config.js; si no, cree uno nuevo usted mismo.

principio:

1. Envíe el nombre de dominio al servidor local (localhost:8080)

2. Luego el servidor local solicita el servidor real.

3. Debido a que la solicitud se envía desde el servidor, no hay ningún problema entre dominios.

En vue lo hace automáticamente node.js

4.1 Proxy inverso frontal

Modificar main.js

Modifique el código src\main.js de la siguiente manera:

import Vue from 'vue'
import App from './App'
import router from './router'
// 设置反向代理,前端请求默认发送到 http://localhost:8081/api
var axios = require('axios')
axios.defaults.baseURL = 'http://localhost:8081/api'
// 全局注册,之后可在其他组件中通过 this.$axios 发送数据
Vue.prototype.$axios = axios
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})

Modificar vue.config.js 

Modifique la dirección de solicitud de proxyTable para que sea proxy de la dirección de backend 8081 después de node.js


    proxyTable: {
      '/': {
        changeOrigin: true, //跨域
        target: 'http://localhost:8081',
        pathRewrite: {
          // '^/api': ''
        }
      },
    
    },

5. Interceptor de inicio de sesión

Los interceptores, como su nombre lo indica, interceptan solicitudes, que son interceptores de solicitudes e interceptores de respuestas. El orden de ejecución es: interceptor de solicitudes -> solicitud de API -> interceptor de respuestas. La función del interceptor: a. Contar el tiempo necesario para que la API devuelva los datos de la solicitud; b. Configurar el encabezado de la solicitud pública, cargar la ventana emergente, etc.; c. Interceptar el código de estado de respuesta y devolver 400 o 500 en comparación con el código de estado del backend, devuelve el mensaje de error correspondiente.

5.1 solicitud de interceptor de solicitudes de axios

En el proyecto Vue, generalmente usamos axios para interactuar con los datos de fondo. Axios es una biblioteca basada en promesas que se puede ejecutar en entornos de navegador y nodos. La función del interceptor de solicitudes: realizar ciertas operaciones de manera uniforme antes de enviar la solicitud y, a menudo, se usa para procesar tokens en el encabezado de la solicitud, etc. 

Cómo agregar un interceptor de solicitudes

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

5.2 Respuesta del interceptor de respuesta de Axios

La respuesta del objeto devuelto contiene Response.status: código de respuesta HTTP; Response.data: el objeto Json devuelto por el backend, incluido el código de respuesta de lógica empresarial Response.data.code, Response.data.message: el mensaje de solicitud de respuesta devuelto por el backend. ;

Agregar método interceptor de respuesta

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

5.3 Solicitud de paquete

En el proyecto, no usaremos axios directamente, sino que lo encapsularemos en una capa. Exporte la solicitud encapsulada mediante exportación, como definiendo un método postRequest para recibir la URL y los parámetros, y luego el objeto axios. Realice la operación de llamada de interfaz real en axios.

export const postRequest = (url, params) => {
    return axios({
        method: 'post',
        url: `${base}${url}`,
        data: params
    })
}

 5.4 Implementación de código src/utils/api.js

import axios from "axios";
import {Message} from "element-ui";
import router from "@/router";

// 请求拦截器
axios.interceptors.request.use(config => {
    // 如果存在 token,请求携带这个 token( 登录的时候 把 token 存入了 sessionStorage )
    if (window.sessionStorage.getItem("tokenStr")) {
        // token 的key : Authorization ; value: tokenStr
        config.headers['Authorization'] = window.sessionStorage.getItem('tokenStr')
    }
    return config;
},error => {
    console.log(error)
})

// 响应拦截器 - 统一处理消息提示
axios.interceptors.response.use(success => {
    // 业务逻辑错误
    if (success.status && success.status === 200) { // 调到接口
        // 后端:500 业务逻辑错误,401 未登录,403 无权访问;
        if (success.data.code === 500 || success.data.code === 401 || success.data.code === 403) {
            Message.error({message: success.data.message})
            return
        }
        if (success.data.message) { // 输出后端 添加成功 之类的信息
            Message.success({message: success.data.message})
        }
    }
    return success.data
}, error => { // 没访问到后端接口
    if (error.response.code === 504 || error.response.code === 404) {
        Message.error({message: '服务器不存在'})
    } else if (error.response.code === 403) {
        Message.error({message: '权限不足,请联系管理员!'})
    } else if (error.response.code === 401) {
        Message.error({message: '您还未登录,请登录!'})
        router.replace('/') // 路由替换
    } else {
        if (error.response.data.message) {
            Message.error({message: error.response.data.message})
        } else {
            Message.error({message: '未知错误!'})
        }
    }
    return
})

// 预备前置路径
let base = '';

// 传送 json 格式的 post 请求
export const postRequest = (url, params) => {
    return axios({
        method: 'post',
        url: `${base}${url}`,
        data: params
    })
}

// 传送 json 格式的 get 请求
export const getRequest = (url, params) => {
    return axios({
        method: 'get',
        url: `${base}${url}`,
        data: params
    })
}

// 传送 json 格式的 put 请求
export const putRequest = (url, params) => {
    return axios({
        method: 'put',
        url: `${base}${url}`,
        data: params
    })
}

// 传送 json 格式的 delete 请求
export const deleteRequest = (url, params) => {
    return axios({
        method: 'delete',
        url: `${base}${url}`,
        data: params
    })
}

5.5 main.js introduce globalmente solicitudes de encapsulación

El método se introduce globalmente a través de main.js y luego se utiliza a través de un complemento. Utilice el formulario this.putRequest(url, params) al llamar

import {postRequest} from "@/utils/api";
import {putRequest} from "@/utils/api";
import {getRequest} from "@/utils/api";
import {deleteRequest} from "@/utils/api";
Vue.prototype.postRequest = postRequest
Vue.prototype.putRequest = putRequest
Vue.prototype.getRequest = getRequest
Vue.prototype.deleteRequest = deleteRequest

6. Protector de navegación de enrutamiento frontal

El desarrollo de la página de inicio de sesión parece estar relativamente completo, pero en realidad no está terminado, porque esta página de inicio de sesión es en realidad inútil y otros pueden omitir la página de inicio de sesión ingresando directamente la URL de la página de inicio. Para que esto funcione, también necesitamos desarrollar un interceptor. Utilice la función de enlace para determinar si interceptar la función y la función que se llamará en determinados momentos. Aquí usamos router.beforeEach(), lo que significa llamar antes de visitar cada ruta. to es la ruta a seguir; from es la ruta desde donde; next() se libera.

Obtenga el token del usuario a través de sessionStorage.getItem('usuario'). Si el token no existe, debe iniciar sesión.

Al juzgar si se trata de una página de destino if (to.path == '/'), en caso afirmativo, déjela ir; de lo contrario, inicie sesión de acuerdo con la ruta especificada por el usuario;

Suplemento main.js

// 使用 router.beforeEach 注册一个全局前置守卫
router.beforeEach((to, from, next) => {
  // to 要去的路由; from 来自哪里的路由 ; next() 放行
  // 用户登录成功时,把 token 存入 sessionStorage,如果携带 token,初始化菜单,放行
  if (window.sessionStorage.getItem('tokenStr')) {
      // 如果用户不存在
         //待首页功能部分完善后补充
  } else {
      if (to.path === '/') {
          next()
      } else {
          next('/?redirect=' + to.path)
      }
  }
})

7. Ejecute el proyecto

Próximo

B station cloud E office Vue + SpringBoot proyecto de separación de front-end y back-end: el front-end obtiene dinámicamente el directorio del menú

Supongo que te gusta

Origin blog.csdn.net/qq_36384657/article/details/124525482
Recomendado
Clasificación