Vue learning --- enrutamiento frontal


Este artículo se basa en vue2.x VueRouter3 el entorno de desarrollo.

sobre el enrutamiento: La dirección en la barra de direcciones no cambia cuando se cambia el componente dinámico, y el enrutamiento puede resolver esta deficiencia

El proyecto que creamos a través de la herramienta de andamiaje vue-cil es una aplicación de una sola página. Llamamos a una aplicación de una sola página una aplicación de una sola página, o spa para abreviar. Una sola página significa que solo hay un código html.

El enrutamiento de Vue.js nos permite acceder a diferentes contenidos (diferentes componentes) a través de diferentes URL y realizar el efecto de cambio de varias páginas de una aplicación de una sola página. (Cambiando diferentes componentes cambiando la url)

El enrutamiento de Vue.js debe cargarse en vue-router la biblioteca. vue-router La biblioteca es independiente de vue y puede o no estar disponible. Si desea obtener diferentes URL para acceder a diferentes contenidos (diferentes componentes), puede usar vue-router, o si no usa vue-router Lo que se puede lograr con los componentes dinámicos es que la barra de direcciones no cambie o se pueda lograr el cambio de página.

1. Instalar vue-router

Cargue el archivo principal de vue-router detrás de vue, se instalará automáticamente:

<script src="/path/to/vue.js"></script>

<script src="/path/to/vue-router.js"></script>

O use la importación modular npm (entender)

npm install 'vue-router'

Si lo usa en un proyecto modular, Vue.use()la función de enrutamiento debe instalarse explícitamente a través de:

import Vue from 'vue'

import VueRouter from 'vue-router'

No es necesario si usa la etiqueta de secuencia de comandos global (instalada manualmente).

Si se trata de un proyecto creado en base a @vue/cli scaffolding, puede verificar VueRouter al crear el proyecto con vue create, para que VueRouter se introduzca automáticamente en el proyecto creado.

1.1 Pasos de instalación

Abra cmd para crear un proyecto en la carpeta donde se creará el proyecto

vue create vue-router-demo

Debe elegir al crear: funciones seleccionadas manualmente --> Babel, enrutador, preprocesadores CSS --> 2.x --> Sí --> Sass/SCSS (con dart-sass) --> En paquete.json - - > Sí

2. Cree un proyecto que contenga la biblioteca vue-router

Hay más carpetas de enrutadores que proyectos ordinarios

archivo index.js en la carpeta del enrutador

import Vue from 'vue'
// 1.导入vue-router插件
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue'
// 2.注册vue-router插件
Vue.use(VueRouter)

// 3.定义路由表
const routes = [
  {
    
    
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    
    
    path: '/about',
    name: 'about',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
  }
]

// 4.实例化路由对象
const router = new VueRouter({
    
    
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})
// 5.导出路由对象
export default router

El archivo index.js se usa en el archivo main.js

import Vue from 'vue'
import App from './App.vue'
// 1.导入路由对象
import router from './router'

Vue.config.productionTip = false

new Vue({
    
    
  router,//2.挂载路由对象到根实例上(在整个项目的所有组件中都可以通过组件实例this获取到这个路由对象:this.$router)
  render: h => h(App)
}).$mount('#app')

3. Ejemplo de enrutamiento básico

La colocación de dos enlaces de salto es un componente integrado del complemento vue-router

 <div id="app">
    <nav>
      <!-- router-link 是uve-router插件内置的组件,最终渲染为a标签,用于跳路由 , to表示要跳去往的地址 -->
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link>
    </nav>
    <router-view/>
  </div>

4. Núcleo de enrutamiento

El proceso de implementación de la operación: obtenga y haga clic en la dirección en el enlace del enrutador y colóquelo en la barra de direcciones, luego compare la dirección con la dirección que se puede cambiar en el futuro, y si es igual, el enlace del enrutador activo la clase se agregará automáticamente y, al mismo tiempo, a través de la clase router-link-exact-activ logrará un efecto de resaltado

Componentes relacionados con el enrutamiento

router-link El componente incorporado de la biblioteca de enrutamiento eventualmente se convertirá en una etiqueta en la que se puede hacer clic, haga clic para saltar la ruta y se puede usar en cualquier componente

El componente incorporado de la biblioteca de enrutamiento de la vista del enrutador es solo un componente de marcador de posición. El componente en sí no representará ninguna etiqueta. Los componentes que pueden coincidir correctamente con la dirección de enrutamiento actual se representarán en la vista del enrutador.

router-view es un componente dinámico, que se encarga de ocupar espacio y puede envolverse con componentes de animación

Objetos relacionados con el enrutamiento

Al pasar la instancia del enrutador en la configuración del enrutador de la instancia raíz de Vue, los siguientes miembros de atributos se inyectarán en cada subcomponente.

** objeto de gestión de enrutamiento del enrutador, con el que puede omitir el enrutamiento, ∗ ∗ Este objeto se puede obtener a través de instancias de componente en cualquier componente objeto de gestión de enrutamiento del enrutador, con el que puede omitir el enrutamiento, ** en cualquier componente obtenido a través de la instancia del componente.objeto de gestión de enrutamiento del enrutador ,Con la ayuda de este objeto, se puede saltar la ruta ,El objeto este enrutador se puede obtener a través de la instancia del componente en cualquier componente , y sus métodos principales son :

esto.$router.push()

esto.$router.go()

esto.$router.reemplazar()

$route objeto de enrutamiento, con el cual se pueden obtener parámetros de enrutamiento, sus propiedades principales son:

propiedades del objeto de ruta describir
$ruta.ruta La ruta correspondiente a la ruta actual, siempre resuelta como ruta absoluta
$ruta.parámetros Un objeto clave/valor, incluidos fragmentos dinámicos y fragmentos de coincidencia completa, si no hay un parámetro de enrutamiento, es un objeto vacío
$ruta.consulta Un objeto clave/valor que representa los parámetros de consulta de URL. Por ejemplo, para rutas /foo?user=1, hay $route.query.user == 1o un objeto vacío si no hay parámetros de consulta
$ruta.hash El valor hash (con #) de la ruta actual, o una cadena vacía si no hay ningún valor hash
$ruta.fullPath La URL después de completar el análisis, incluida la ruta completa de los parámetros de consulta y el hash
$ruta.nombre El nombre de la ruta actual, si la hay.
$ruta.redirectedFrom Si hay una redirección, el nombre de la ruta desde la que se originó la redirección

5. Tabla de enrutamiento

La tabla de enrutamiento se encuentra en el archivo index.js

Un objeto es una regla de enrutamiento

Debido a que las reglas de enrutamiento se definen en la tabla de enrutamiento de antemano, el enrutamiento se puede omitir

Una regla de enrutamiento tiene una dirección de enrutamiento, un nombre de enrutamiento e importa los componentes correspondientes a la dirección de enrutamiento

¿Por qué se puede realizar el salto de enrutamiento?: La causa raíz es que ya lo ha definido en la tabla de enrutamiento. Si el botón se puede resaltar o no, no tiene nada que ver con si hay una ruta de salto.

Hay dos formas de importar componentes correspondientes a direcciones de ruta:

1. Importación no dinámica, la característica principal es que todos los componentes se empaquetarán en un js y todos los componentes se cargarán al principio

 // import HomeView from '../views/HomeView.vue'
 component: HomeView//路由地址对应的组件

2. Importación dinámica, el contenido del componente se carga temporalmente cuando se salta la ruta real, lo que se denomina carga dinámica, carga diferida o carga retrasada

Importación dinámica: cuándo omitir rutas y cuándo cargar componentes, carga temporal

 component: () => import('../views/HomeView.vue')

Código de muestra

// 3.定义路由表
const routes = [
  {
    
    //一个对象,就是一个路由规则
    path: '/',//路由地址
    name: 'home',//路由名字
    // 路由地址对应的组件有两种写法
    // 第一种:非动态导入,主要特点所有组件会被打包成一个js,一开始就会将所有组件加载
    // component: HomeView//路由地址对应的组件
    // 第二种:动态导入组件:在实际跳路由的时候才会临时加载组件的内容,被叫做动态加载又叫懒加载又叫延迟加载
    component: () => import('../views/HomeView.vue')

  },
  {
    
    
    path: '/about',
    name: 'about',
    component: () => import('../views/AboutView.vue')
  }
]

Las direcciones de enrutamiento que comienzan con una barra inclinada son direcciones de enrutamiento absolutas

Los componentes colocados en vistas son componentes de nivel de ruta y los componentes colocados en componentes son componentes en la página

6. Dos formas de omitir el enrutamiento

devolver:@click='$router.go(-1)

** El primer tipo: ** enlace de enrutador, el elemento en el que se debe hacer clic debe estar envuelto con enlace de enrutador

 <router-link to="/index/home">首页</router-link>

**El segundo método: **Utilice el objeto de gestión de rutas this.$router para saltar la ruta a través del código js

<div @click="$router.push('/login')">去登陆</div>

Hay un total de formas de saltar rutas:

  1. router-link debe envolver el elemento en el que se hizo clic en router-link, y router-link eventualmente se convertirá en una etiqueta
  2. $router.push (dirección de enrutamiento) agregará un nuevo registro de historial al historial del navegador
  3. $router.replace() reemplazará el historial actual en el historial del navegador
  4. $router.go(n) Cambiar historial, cambiar en el historial existente del navegador

7. Tres formas de omitir los parámetros de enrutamiento

El papel de los parámetros de enrutamiento:

  1. Los componentes que se muestran después de saltar la ruta deben renderizarse dinámicamente;
  2. Los datos que el componente necesita para representar dinámicamente están relacionados con las operaciones del usuario. Cuando el contenido de la página se representa dinámicamente, la ruta de salto está relacionada con el clic después del clic y los parámetros se pasan después del clic.
  3. Pasar mas o menos parametros, puedes pasar todos los datos del producto o solo el id

**Tipo 1:**Enrutamiento dinámico, los parámetros de la página de actualización no se perderán, los parámetros se muestran en la barra de direcciones

En la tabla de enrutamiento:

{
    
    
    // 路由地址中带有 :xxx 的路由地址 都属于动态路由
    // path: '/detail/:name', // :name 是个占位符, 实际在跳路由的时候,会动态拼接参数 例如: '/detail/'+100
    path: '/detail/:name',
    name: 'detail',
    component: () => import('../views/Detail.vue')
  },

En el archivo vue:

<router-link :to="'/detail/'+888">详情</router-link>


<div @click="$router.push('/detail/'+888)">详情</div>

Obtener parámetros de enrutamientothis.$router.params.name

**El segundo tipo: **ruta + consulta, los parámetros no se perderán cuando se actualice la página y los parámetros se mostrarán en la barra de direcciones en forma de cadenas de consulta

En la tabla de enrutamiento:

{
    
    
    path: '/detail',
    name: 'detail',
    component: () => import('../views/Detail.vue')
  },

En el archivo vue:

<router-link :to="{path:'/detail',query:{name:888}}">详情</router-link>

<div @click="$router.push({path:'/detail',query:{name:888}})">详情</div>

Obtener parámetros de enrutamientothis.$router.query.name

**El tercer tipo: **nombre + parámetros, los parámetros se perderán cuando se actualice la página y no se podrán ver los parámetros

En la tabla de enrutamiento:

{
    
    
    path: '/detail',
    name: 'detail',
    component: () => import('../views/Detail.vue')
  },

En el archivo vue:

<router-link :to="{name:'detail',params:{name:888}}">详情</router-link>

<div @click="$router.push({name:'detail',params:{name:888 }})">详情</div>

Obtener parámetros de enrutamientothis.$router.params.name

8. Enrutamiento anidado

Para renderizar componentes en puntos de venta anidados, debe usar la configuración de niños en los parámetros de VueRouter:

var router = new VueRouter({
    
    
    routes:[
        {
    
    
            path:'/article',
            component:Article,
            /*通过children设置嵌套路由规则*/
      		 children:[
{
    
     path:'/article/cate',component: Cate },
{
    
     path:'/article/list',component: List }
]
}
    ]
});

9. Redirecciones y alias

//一级路由重定向
  {
    
    
    path:'/',
    redirect:'/index'  
  },
  //404路由
  {
    
    
    path:'*',
    component: () => import('../views/NotFound.vue') 
  }
//二级路由重定向
{
    
    
    path:'/index',
    redirect:'/index/home'  
  },
  //404路由
  {
    
    
    path:'*',
    component: () => import('../views/NotFound.vue') 
  }

10. Modo de enrutamiento

modo historial y modo hash

11. enrutador y enrutador yLa diferencia entre enrutador y ruta

$router: objeto de gestión de enrutamiento, responsable de gestionar el enrutamiento (responsable de saltar el enrutamiento)

$ruta: objeto de enrutamiento, que contiene toda la información del enrutamiento actual (dirección actual, parámetros transportados)

12. Función de protección de enrutamiento y metainformación

Para cualquier ruta legal, las rutas existentes en la tabla de enrutamiento pueden controlar si la ruta actual puede saltar, por ejemplo, al hacer clic para determinar si puede saltar, ¿dónde escribimos el código que puede saltar a la ruta después del juicio?

La función de guardia de la ruta provista en vue se puede usar para escribir el código para juzgar si la ruta se puede omitir

El método de instancia del enrutador (que debe agregarse a la instancia del enrutador) también se denomina método de protección de navegación.

  1. Método global de preguardia para el enrutamiento

    router.beforeEach((to, from, next) => {
          
          
      //参数一: to 新的路由对象
      //参数二: from 旧的路由对象
      //参数三: next 路由控制方法, 调用该方法则允许路由跳转, 未调用该方法则不允许路由跳转
      next();//必须手动调用该函数,否则无法完成路由跳转
    })
    
  2. Método global de posguardia para el enrutamiento

    router.afterEach((to,from)=>{
          
          
      console.log('afterEach');
    })
    
  3. Función de guardia exclusiva de ruta (recién agregada a una ruta para determinar si una sola ruta puede saltar)

    beforeEnter: (to, from, next) => {
          
          
        console.log('beforeEnter');
          next();
        }
    

Nota: La posición de escritura y el nombre de la función de guardia global y la función de guardia exclusiva son diferentes, pero las funciones son similares y todas son saltos de ruta de guardia.

12.1 Ejemplo de función de protección de enrutamiento

1. Actualizar dinámicamente el título de la página

Actualice dinámicamente el título de la página web: puede decirle al usuario en qué página se encuentra actualmente, usarlo con metainformación de enrutamiento y establecer el título actual a través de js

Para lograr las funciones anteriores, es necesario agregar metainformación de enrutamiento a cada objeto de enrutamiento, y la metainformación de enrutamiento siempre se guardará en el objeto de enrutamiento actual.

Por ejemplo:

{
    
    
    path: '/index',
    name: 'index',
    meta: {
    
     
        title:'index',
        auth:true//用户登录后才可以跳路由,没有加是不需要登录就可以
          }, //路由元信息( 会永远保存在当前路由对象身上 )
    component: () => import('../views/Index.vue'),
 }

Código de caso:

//路由的全局前置守卫方法
router.beforeEach((to, from, next) => {
    
    
	//因为这个函数跳任何一个路由都会执行,所以当路由跳转的时候就会执行将路由元信息中的title的值赋给网页的标题,这样就可以实现动态更新网页标题
  //动态更新网页标题
  document.title = to.meta.title;
	next();
})

2. Controlar el acceso a rutas individuales

Si desea saltar a la página de pedidos y a mi página, debe iniciar sesión antes de poder saltar

//路由的全局前置守卫方法
router.beforeEach((to, from, next) => {
    
    
  //参数一: to 新的路由对象
  //参数二: from 旧的路由对象
  //参数三: next 路由控制方法, 调用该方法则允许路由跳转, 未调用该方法则不允许路由跳转

  //获取localStorage中的登陆凭证
  var token = localStorage.getItem('token');

  //只有在登陆以后 才可以跳转到 订单页
  //if(to.path == '/index/order'){ //想要跳往 订单页

  /*  if(to.path == '/index/order' || to.path == '/index/mine'){ //想要跳往 订单页 或者 我的页面
    if( token ){ //已经登陆
      next();
    }else{ //未登录
      next('/login');
    }
  }else{ //其他页面( 非订单页 )
    next();//必须手动调用该函数, 否则无法完成路由跳转
  } */
  
})

3. Solo se puede acceder a voluntad a la página de inicio de sesión, y se debe iniciar sesión en otras páginas antes de poder acceder a ellas.

//路由的全局前置守卫方法
router.beforeEach((to, from, next) => {
    
    
  //参数一: to 新的路由对象
  //参数二: from 旧的路由对象
  //参数三: next 路由控制方法, 调用该方法则允许路由跳转, 未调用该方法则不允许路由跳转

  //获取localStorage中的登陆凭证
  var token = localStorage.getItem('token');
  
  // 对于后台管理系统这种应用, 只有登录页是可以随意访问的, 但是其他所有页面都是必须在登陆以后才可以访问
  if( to.path == '/login' ){
    
     //跳往 登录页
    if( token ){
    
     //已登录 , 重定向到 "/"
      next('/');
    }else{
    
     //未登录 , 允许跳往 登录页
      next(); 
    }
    // next();
  }else{
    
     //跳往 非登录页
    if( token ){
    
     //已登录 , 允许访问
      next(); 
    }else{
    
     //未登录 , 重定向到 "/login"
      next('/login');
    }
  }
})

código integrado

El archivo index.js en la carpeta del enrutador en la carpeta src del proyecto

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const routes = [ //定义多个一级路由
  {
    
    
    path: '/index',
    name: 'index',
    meta: {
    
     title:'index' }, //路由元信息( 会永远保存在当前路由对象身上 )
    component: () => import('../views/Index.vue'),
    children:[ //嵌套路由( 二级路由 )
      {
    
    
        path: '/index/home',
        name: 'home',
        meta: {
    
     title:'首页' }, //路由元信息( 会永远保存在当前路由对象身上 )
        component: () => import('../views/Index/Home.vue'),
      },
      {
    
    
        path: '/index/order',
        name: 'order',
        meta: {
    
     title:'订单' }, //路由元信息( 会永远保存在当前路由对象身上 )
        component: () => import('../views/Index/Order.vue')
      },
      {
    
    
        path: '/index/mine',
        name: 'mine',
        meta: {
    
     title:'我的' },
        component: () => import('../views/Index/Mine.vue')
      },
      //二级路由的重定向
      {
    
    
        path:'/index',
        redirect:'/index/home' 
      },
      //404路由
      {
    
    
        path:'*',
        component: () => import('../views/NotFound.vue') 
      }
    ]
  },
  {
    
    
    path: '/login',
    name: 'about',
    meta: {
    
     title:'登陆' },
    component: () => import('../views/Login.vue'),
    //路由独享的守卫函数
    // beforeEnter: (to, from, next) => {
    
    
    //   console.log('beforeEnter');
    //   next();
    // }
  },
  {
    
    
    // 路由地址中带有 :xxx 的路由地址 都属于动态路由
    // path: '/detail/:name', // :name 是个占位符, 实际在跳路由的时候,会动态拼接参数 例如: '/detail/'+100
    path: '/detail',
    name: 'detail',
    meta: {
    
     title:'详情' },
    component: () => import('../views/Detail.vue'),
    
  },
  //一级路由重定向
  {
    
    
    path:'/',
    redirect:'/index'  
  },
  //404路由
  {
    
    
    path:'*',
    component: () => import('../views/NotFound.vue') 
  }
]

const router = new VueRouter({
    
    
  mode: 'history', //设置路由模式, history , hash
  base: process.env.BASE_URL,
  routes
})

//设置实例方法( 导航守卫方法 )

//路由的全局前置守卫方法
router.beforeEach((to, from, next) => {
    
    
  //参数一: to 新的路由对象
  //参数二: from 旧的路由对象
  //参数三: next 路由控制方法, 调用该方法则允许路由跳转, 未调用该方法则不允许路由跳转

  //动态更新网页标题
  document.title = to.meta.title;

  //获取localStorage中的登陆凭证
  var token = localStorage.getItem('token');

  //只有在登陆以后 才可以跳转到 订单页
  //if(to.path == '/index/order'){ //想要跳往 订单页

  /*  if(to.path == '/index/order' || to.path == '/index/mine'){ //想要跳往 订单页 或者 我的页面
    if( token ){ //已经登陆
      next();
    }else{ //未登录
      next('/login');
    }
  }else{ //其他页面( 非订单页 )
    next();//必须手动调用该函数, 否则无法完成路由跳转
  } */
  
  // 对于后台管理系统这种应用, 只有登录页是可以随意访问的, 但是其他所有页面都是必须在登陆以后才可以访问
  if( to.path == '/login' ){
    
     //跳往 登录页
    if( token ){
    
     //已登录 , 重定向到 "/"
      next('/');
    }else{
    
     //未登录 , 允许跳往 登录页
      next(); 
    }
    // next();
  }else{
    
     //跳往 非登录页
    if( token ){
    
     //已登录 , 允许访问
      next(); 
    }else{
    
     //未登录 , 重定向到 "/login"
      next('/login');
    }
  }
})

//路由的全局后置守卫方法
// router.afterEach((to,from)=>{
    
    
//   console.log('afterEach');
// })

export default router

12.2 Componentes de inicio de sesión y registro autoencapsulados

El archivo de índice debajo del archivo del enrutador debajo del archivo src en el archivo del proyecto configura la tabla de enrutamiento

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const routes = [ //定义多个一级路由
  {
    
    
    path: '/index',
    name: 'index',
    meta: {
    
     title:'index' }, //路由元信息( 会永远保存在当前路由对象身上 )
    component: () => import('../views/Index.vue'),
    children:[ //嵌套路由( 二级路由 )
      {
    
    
        path: '/index/home',
        name: 'home',
        meta: {
    
     title:'首页' }, //路由元信息( 会永远保存在当前路由对象身上 )
        component: () => import('../views/Index/Home.vue'),
      },
      {
    
    
        path: '/index/order',
        name: 'order',
        meta: {
    
     title:'订单' }, //路由元信息( 会永远保存在当前路由对象身上 )
        component: () => import('../views/Index/Order.vue')
      },
      {
    
    
        path: '/index/mine',
        name: 'mine',
        meta: {
    
     title:'我的' },
        component: () => import('../views/Index/Mine.vue')
      },
      //二级路由的重定向
      {
    
    
        path:'/index',
        redirect:'/index/home' 
      },
      //404路由
      {
    
    
        path:'*',
        component: () => import('../views/NotFound.vue') 
      }
    ]
  },
  {
    
    
    path: '/login',
    name: 'about',
    meta: {
    
     title:'登陆' },
    component: () => import('../views/Login.vue'),
    //路由独享的守卫函数
    // beforeEnter: (to, from, next) => {
    
    
    //   console.log('beforeEnter');
    //   next();
    // }
  },
  {
    
    
    path: '/register',
    name: 'register',
    meta: {
    
     title:'注册' },
    component: () => import('../views/Register.vue')
  },
  {
    
    
    // 路由地址中带有 :xxx 的路由地址 都属于动态路由
    // path: '/detail/:name', // :name 是个占位符, 实际在跳路由的时候,会动态拼接参数 例如: '/detail/'+100
    path: '/detail',
    name: 'detail',
    meta: {
    
     title:'详情' },
    component: () => import('../views/Detail.vue'),
    
  },
  //一级路由重定向
  {
    
    
    path:'/',
    redirect:'/index'  
  },
  //404路由
  {
    
    
    path:'*',
    component: () => import('../views/NotFound.vue') 
  }
]

const router = new VueRouter({
    
    
  mode: 'history', //设置路由模式, history , hash
  base: process.env.BASE_URL,
  routes
})

//设置实例方法( 导航守卫方法 )

//路由的全局前置守卫方法
router.beforeEach((to, from, next) => {
    
    
  //参数一: to 新的路由对象
  //参数二: from 旧的路由对象
  //参数三: next 路由控制方法, 调用该方法则允许路由跳转, 未调用该方法则不允许路由跳转

  //动态更新网页标题
  document.title = to.meta.title;

  //获取localStorage中的登陆凭证
  var token = localStorage.getItem('token');

  //只有在登陆以后 才可以跳转到 订单页
  //if(to.path == '/index/order'){ //想要跳往 订单页

  /*  if(to.path == '/index/order' || to.path == '/index/mine'){ //想要跳往 订单页 或者 我的页面
    if( token ){ //已经登陆
      next();
    }else{ //未登录
      next('/login');
    }
  }else{ //其他页面( 非订单页 )
    next();//必须手动调用该函数, 否则无法完成路由跳转
  } */
  
  //对于后台管理系统这种应用, 只有登录页是可以随意访问的, 但是其他所有页面都是必须在登陆以后才可以访问
  if( to.path == '/register' ){
    
     //跳往 注册页 , 允许跳转
    next();
  }else{
    
    
    if( to.path == '/login' ){
    
     //跳往 登录页
      if( token ){
    
     //已登录 , 重定向到 "/"
        next('/');
      }else{
    
     //未登录 , 允许跳往 登录页
        next(); 
      }
      // next();
    }else{
    
     //跳往 非登录页
      if( token ){
    
     //已登录 , 允许访问
        next(); 
      }else{
    
     //未登录 , 重定向到 "/login"
        next('/login');
      }
    }
  }
})

//路由的全局后置守卫方法
// router.afterEach((to,from)=>{
    
    
//   console.log('afterEach');
// })

export default router

Cree un componente registrado en el archivo de vistas en la carpeta del proyecto

<template>
  <div class="register">
    <div class="title">注册页</div>
    <div class="block">
      <input type="text" v-model="formData.phone" placeholder="输入手机号">
    </div>
    <div class="block">
      <input type="password" v-model="formData.pass" placeholder="输入密码">
    </div>
    <div class="block">
      <input type="password" v-model="formData.checkpass" placeholder="输入确认密码 ">
    </div>
    <div class="block">
      <input type="button" class="btn" value="注册" @click="register">
      <input type="button" class="btn" value="登录" @click="login">
    </div>
  </div>
</template>

<script>
// 导入封装的请求函数
import {
    
    user_register} from '../utils/api'
import {
    
     Toast } from 'vant';

export default {
    
    
  data(){
    
    
    return {
    
    
      formData:{
    
    
        phone:'',
        pass:'',
        checkpass:''
      }
    }
  },
  methods:{
    
    
    // 点击时先对输入的内容进行判断如果都符号再去发请求
    register(){
    
    
      // 先对输入的手机号通过正则进行判断,如果不符合则弹出弹框
      if(/^1[3-9]\d{9}$/.test(this.formData.phone) == false){
    
    
        Toast.fail({
    
     message: '请输入合法的手机号' });
        // 对密码和确认密码进行判断是否为空为空就提示
      }else if( !this.formData.pass || !this.formData.checkpass ){
    
    
        Toast.fail({
    
     message: '请输入密码/确认密码' });
      }else{
    
    //验证通过
        Toast.fail({
    
     message: '密码和确认密码不一致' });
        // 因为注册请求时要传账号和密码,formData中多了一个确认密码需要将多的内容删掉

        // 深拷贝formData,防止对原数据进行修改
        var newFormData = JSON.parse(JSON.stringify(this.formData));
        // 删除对象的checkpass属性
        delete newFormData.checkpass;

        // 发起注册请求,账号phone,密码pass必须传
        user_register(newFormData).then((res)=>{
    
    
          if(res.data.code == 200){
    
    //注册成功
            Toast.success('登陆成功!')
            // 跳转到登录页
            this.$router.push('/login');
          }else{
    
    
            Toast.fail('登陆失败!')
          }
        })
        
      }
    },
    login(){
    
    
      this.$router.push('/login');
    }
  }
}
</script>

<style lang="scss" scoped>
.register{
    
    
  margin: 50px 20px;
}
.register .title{
    
    
  font-weight: bold;
  text-align: center;
  line-height: 40px;
  font-size: 32px;
}
.register .block{
    
    
  margin: 20px 0;
}
.register .block input{
    
    
  height: 40px;
  border: 1px solid #ccc;
  border-radius: 20px;
  padding-left: 20px;
  box-sizing: border-box;
  outline: none;
  width: 100%;
  margin-bottom: 10px;
  font-size: 14px;
  color: #ccc;
}


.register .block .btn{
    
    
  padding-left: 0;
  height: 40px;
  border: 1px solid #ccc;
  border-radius: 20px;
  box-sizing: border-box;
  outline: none;
  width: 100%;
  margin-bottom: 15px;
  color: black;
  font-size: 16px;
}
</style>

Cree un componente de inicio de sesión en el archivo de vistas en la carpeta del proyecto

<template>
  <div class="login">
    <div class="title">登陆页</div>
    <div class="block">
      <input type="text" v-model="formData.phone" placeholder="输入手机号">
    </div>
    <div class="block">
      <input type="password" v-model="formData.pass" placeholder="输入密码">
    </div>
    <div class="block">
      <input type="button" value="登陆" @click="login">
    </div>
  </div>
</template>

<script>

import {
    
     Toast } from 'vant';
import {
    
    user_login} from '../utils/api'

export default {
    
    
  data(){
    
    
    return {
    
    
      formData:{
    
    
        phone:'',
        pass:''
      }
    }
  },
  methods:{
    
    
    login(){
    
    
      if( /^1[3-9]\d{9}$/.test( this.formData.phone ) == false ){
    
    
        alert('请输入合法的手机号');
      }else if( !this.formData.pass ){
    
    
        alert('请输入密码')
      }else{
    
     //验证通过 
        //发起登陆请求
        user_login( this.formData ).then((res)=>{
    
    
          if( res.data.code == 200 ){
    
    
            //保存用户信息,token
            localStorage.setItem('token',res.data.token);
            localStorage.setItem('userinfo', JSON.stringify( res.data.userinfo ) );
            //自动跳转到首页
            this.$router.push('/');
            Toast.success('登陆成功!')
          }else{
    
    
            Toast.fail('登陆失败!')
          }
        })
      }
    }
  }
}
</script>

<style lang='scss' scoped> 
.login{
    
    
  margin: 50px 20px;
}
.login .title{
    
    
  font-weight: bold;
  text-align: center;
  line-height: 40px;
}
.login .block{
    
    
  margin: 20px 0;
}
.login .block input{
    
    
  height: 40px;
  border: 1px solid #ccc;
  border-radius: 20px;
  padding-left: 20px;
  box-sizing: border-box;
  outline: none;
  width: 100%;
}
</style>

Componente de inicio de sesión empaquetado con componentes de formulario

<template>
  <div class="login">
    <div class="title">登录页</div>
    <van-form @submit="login">
      <van-field
        class="input-box"
        v-model="formData.phone"
        placeholder="输入手机号"
        :rules="[{ required: true, pattern:/^1[3-9]\d{9}$/,message: '请输入手机号' }]"
      />
      <van-field
      class="input-box"
        v-model="formData.pass"
        type="password"
        placeholder="输入密码"
        :rules="[{ required: true, pattern:/^\d{6}$/, message: '请输入密码' }]"
      />
      <div style="margin: 16px;">
        <van-button round block type="info" native-type="submit">登录</van-button>
      </div>
    </van-form>
    <button round block @click="reguster" class="zhuce" >点此注册新账号</button>
  </div>
</template>

<script>

// 导入组件
import {
    
     Toast } from 'vant';
import {
    
    user_login} from '../utils/api'

export default {
    
    
  data(){
    
    
    return {
    
    
      formData:{
    
    
        phone:'',
        pass:'',
      }
    }
  },
  methods:{
    
    
    login(){
    
    
      // 发起登录请求
      user_login( this.formData ).then((res)=>{
    
    
        if( res.data.code == 200 ){
    
    
          //保存用户信息,token
          localStorage.setItem('token',res.data.token);
          localStorage.setItem('userinfo', JSON.stringify( res.data.userinfo ) );
        }else{
    
    
          Toast.fail('登陆失败!')
        }
      })
    },
    reguster(){
    
    
      this.$router.push('/register');
    }
  }
}
</script>

<style lang='scss' scoped> 

.login{
    
    
  margin: 50px 20px;
}
.login .title{
    
    
  font-weight: bold;
  text-align: center;
  line-height: 40px;
  font-size: 32px;
}


.login .input-box{
    
    
  border: 1px solid #ccc;
  margin: 30px 0;
  border-radius: 30px;
}

.zhuce{
    
    
  position: absolute;
  right: 20px;
  padding: 5px 20px;
  border: none;
  font-size: 14px;
  color: lightblue;
  background-color: white;
}


</style>

Encapsulación secundaria de axios en el proyecto, gestión unificada de solicitudes de API

Ambos archivos crean un archivo utils en el archivo src del proyecto

Cree un archivo en el archivo utils para implementar

archivo request.js

//对axios进行二次封装
import axios from 'axios'

import {
    
     Toast } from 'vant';

//实例化axios
var service = axios.create({
    
    
    timeout: 10*1000,
    baseURL: '/api'
})

//设置拦截器( 请求拦截器 )
service.interceptors.request.use((config)=>{
    
    
    //统一携带请求头
    config.headers['Authorization'] = 'Bearer' + ' ' + localStorage.getItem('token');
    //显示loading
    Toast.loading({
    
     message: '加载中...', duration: 0});
    
    return config;
},(error)=>{
    
    
    return Promise.reject(error);
})

//设置拦截器( 响应拦截器 )
service.interceptors.response.use((res)=>{
    
    
    //隐藏loading
    Toast.clear();

    return res;
},(error)=>{
    
    
    //隐藏loading
    Toast.clear();

    if( error.response.status == 401 ){
    
    
        alert('身份认证失败,登陆过期!')
    }
    else if( error.response.status == 404 ){
    
    
        alert('访问路径错误!')
    }
    else if( error.response.status == 500 ){
    
    
        alert('服务器内部错误')
    }
    return Promise.reject(error);
})

export default service;


api.js, debe importar la solicitud empaquetada al componente que desea usar y luego usarla

//导入设置过 拦截器的axios
import service from './request'

//一个请求封装一个函数
export function user_login( params = {
     
     } ){
    
    
    return service.post('/user/login', params );
}

export function user_register( params = {
     
     } ){
    
    
    return service.post('/user/register', params );
}

//...

//导出所有函数

Configure el proxy en el archivo vue.config.js del proyecto

const {
    
     defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
    
    
  transpileDependencies: true,
  devServer:{
    
    
    proxy:{
    
    
      '/api':{
    
    
        target:'http://waimai.yantianfeng.com/',
        changeOrigin:true,
        pathRewrite:{
    
    }
      }
    }
  }
})

Supongo que te gusta

Origin blog.csdn.net/m0_53181852/article/details/127587390
Recomendado
Clasificación