Acerca de la organización del conocimiento de vue

El ciclo de vida de VUE

  1. ¿Qué es el ciclo de vida de vue?

  • El ciclo de vida de Vue se refiere al proceso desde la creación del objeto de instancia de Vue hasta su destrucción. La realización de todas las funciones de Vue se lleva a cabo alrededor de su ciclo de vida. Llamar a la función de enlace correspondiente en diferentes etapas del ciclo de vida puede realizar el componente gestión de datos y representación DOM Dos funciones importantes.

1. beforeCreate (antes de la creación) es una función que se activa antes de que se cree el objeto Vue

2. creado (después de la creación) una función activada cuando se crea el objeto Vue

3. beforeMount (antes de cargar) es una función que se activa cuando el objeto Vue comienza a montar datos

4. Montado (después de la carga) es una función que se activa cuando se completan los datos de montaje del objeto Vue

5. beforeUpdate (antes de la actualización) es una función que se activa antes de que cambien los datos en el objeto Vue

6. actualizado (actualizado) Los datos de datos en el objeto Vue cambian para completar la función de activación

7. beforeDestroy (antes de la destrucción) es una función que se activa antes de que se destruya el objeto Vue

8. destruido (después de la destrucción) la función activada por la finalización de la destrucción del objeto Vue

  1. Las ocho fases del ciclo de vida de vue

  • 1.beforeCreate: se llamará inmediatamente después de que se complete la inicialización de la instancia, después de que se analicen los accesorios y antes de que se procesen opciones como data() y cómputo. El nodo DOM no se puede obtener en este momento.
  • 2.creado: en esta etapa, se ha creado la instancia de vue y se ha establecido el siguiente contenido: datos de respuesta, propiedades computadas, métodos y oyentes. Sin embargo, en este momento la fase de montaje aún no ha comenzado, por lo que la propiedad $el aún no está disponible. Todavía no puedo obtener el elemento DOM.
  • 3.beforeMount: una función que se ejecuta automáticamente antes de que el contenido del componente se represente en la página.El componente ha completado su configuración de estado de respuesta, pero aún no ha creado un nodo DOM.
  • 4.montado: una función que se ejecuta automáticamente después de renderizar el componente. Generalmente, nuestras solicitudes asincrónicas se escriben aquí. En esta etapa, se han renderizado tanto los datos como el DOM.
  • 5.beforeUpdate: una función que se ejecuta automáticamente cuando los datos cambian.En este momento, los datos modificados no se han representado en la página.
  • 6. actualizado: una función que se ejecuta automáticamente después de que los datos cambian, y los datos modificados se han representado en la página en este momento.
  • 7.beforeUnmount: una función que se ejecuta automáticamente cuando se destruye la aplicación Vue.
  • 8.desmontado: una función que se ejecuta automáticamente cuando se destruye la aplicación Vue y el dom se destruye por completo.
  1. La diferencia entre computado y reloj de vue.

Tanto calculado como observado son atributos que se utilizan para monitorear los cambios de datos en el marco vue

propiedades calculadas calculadas

  1. Si la propiedad de la que depende la función no ha cambiado, léala desde el caché

  1. Tiene que haber un regreso

  1. El método de uso es el mismo que el de los datos en los datos, pero similar a un método de ejecución

reloj oyente

El nombre de la función del reloj debe ser coherente con el nombre de los datos en data

La función en el reloj tiene dos parámetros, antiguo y nuevo.

Las funciones en el reloj no necesitan ser llamadas

Solo monitoreará si el valor de los datos ha cambiado, pero no monitoreará si la dirección de los datos ha cambiado. Para monitorear profundamente, debe cooperar con el atributo deep:true

inmediato: verdadero Hacer un seguimiento cuando la página se carga por primera vez

la diferencia

Función: computado es un atributo computado, el reloj es para monitorear un cambio de valor y ejecutar la devolución de llamada correspondiente

Si llamar al caché: se llamará al caché cuando las propiedades de las que depende la función calculada permanezcan sin cambios; se llamará a la devolución de llamada cada vez que cambie el valor monitoreado del reloj

Ya sea para devolver la llamada: computado debe tener; el reloj no puede

Escenario de uso: se calcula cuando un atributo se ve afectado por varios atributos, como la liquidación del producto del carrito de la compra; observe cuándo un dato afecta a varios datos, como un cuadro de búsqueda

Si admitir asincronía: las funciones computadas no pueden tener asincronía; el reloj puede

  1. Proceso de inicio de sesión de Vue

Proceso de implementación detallado de la función de inicio de sesión de Vue

1. Al iniciar sesión por primera vez, el front-end ajusta la interfaz de inicio de sesión del back-end y envía el nombre de usuario y la contraseña

2. El backend recibe la solicitud, verifica el nombre de usuario y la contraseña y devuelve un token al frontend si la verificación es exitosa.

3. El front-end obtiene el token, lo almacena en localStorage y vuex, y salta a la página de enrutamiento

4. Cada vez que el front-end salta a la ruta, juzga si hay un token en localStorage. Si no hay token, saltará a la página de inicio de sesión y, si lo hay, saltará a la página de enrutamiento correspondiente.

5. Cada vez que ajuste la interfaz de back-end, debe agregar un token en el encabezado de la solicitud

6、后端判断请求头中有无token,有token,就拿到token并验证token,验证成功就返回数据,验证失败(例如:token过期)就返回401,请求头中没有token也返回401

7、如果前端拿到状态码为401,就清除token信息并跳转到登录页面

补充:

  • 创建store是必须的!

  • token一定要存在storage缓存中,否则刷新一下,store会重新被加载,token就没了;

  • 那存在store是不是多余了,这个也是为了数据统一管理吧,也是数据可视化,因为缓存中的数据代码中是看不见的。(为了代码更容易让别人理解所以加上vuex,不加也不影响做登录)

npm install axios; // 安装axios
npm install vuex  // 安装vuex

创建store

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
// 用Vuex.Store对象用来记录token
const store = new Vuex.Store({
  state: {
    // 存储token
    token:"",
    userName:"" // 可选
  },
  getters: {
    getToken(state){
        return state.token || localStorage.getItem("token") || "";
    }
  },
  mutations: {
    // 修改token,并将token存入localStorage
    setToken(state,token) {
      state.token = token;
      localStorage.setItem('token', token);
      console.log('store、localstorage保存token成功!');
    },
    delToken(state) {
      state.token = "";
      localStorage.removeItem("token");
    },
    // 可选
    setUserInfo(state, userName) {
      state.userName = userName;
    }
  },
 actions: {
   // removeToken: (context) => {
     // context.commit('setToken')
   // }
 },
});
export default store;

引用到main.js

import store from './store'
new Vue({
  router,
  store,
  render: h => h(App),
}).$mount('#app')

封装axios

request.js文件用来封装我们的axios

qs vue 插件

里面有用到qs,这里我门讲解下他的作用:

get方法:我们通过定义一个get函数,get函数有两个参数,第一个参数表示我们要请求的url地址,第二个参数是我们要携带的请求参数。get函数返回一个promise对象,当axios其请求成功时resolve服务器返回 值,请求失败时reject错误值。最后通过export抛出get函数。

post方法:原理同get基本一样,但是要注意的是,post方法必须要使用对提交从参数对象进行序列化的操作,所以这里我们通过node的qs模块来序列化我们的参数。这个很重要,如果没有序列化操作,后台是拿不到你提交的数据的。这就是文章开头我们import QS from ‘qs’;的原因。

简单来说,qs 是一个增加了一些安全性的查询字符串解析和序列化字符串的库。

在项目中使用命令行工具输入:npm install qs

安装完成后在需要用到的组件中:import qs from 'qs’

具体使用中我查看了:qs.parse()和qs.stringify()

这两种方法虽然都是序列化,但是还是有区别的。

qs.parse()是将URL解析成对象的形式

qs.stringify()是将对象 序列化成URL的形式,以&进行拼接

// 封装axios
import axios from 'axios'
// 序列化
import QS from 'qs';
// vuex
import store from '../store/index'
//这一步的目的是判断出当前是开发环境还是生成环境,方法不止一种,达到目的就行
// if(process.env.NODE_ENV=="development"){
//   baseURL=''
// }else{
//   baseURL=''
// }
// 使用自定义的配置文件发送请求
const instance = axios.create({
    baseURL: '',
    timeout: 80000,
    headers: {
        // 'Content-Type': 'application/json;charset=UTF-8',
        // 'custome-header':'tianliangjiaoyu'
    }
});
// post请求的时候,我们需要加上一个请求头,所以可以在这里进行一个默认的设置,即设置post的请求头为
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
// 添加请求拦截器
instance.interceptors.request.use(function (config) {
    // 每次发送请求之前判断vuex中是否存在token        
    // 如果存在,则统一在http请求的header都加上token,这样后台根据token判断你的登录情况
    // 即使本地存在token,也有可能token是过期的,所以在响应拦截器中要对返回状态进行判断 
    const token = store.getters.getToken;
    if (token) {
        // 已经登录成功,统一添加token
        config.headers.Authorization = `Bearer ${token}`
    }
    // token && (config.headers.Authorization = token);
    return config;
}, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
});
// 这里说一下token,一般是在登录完成之后,将用户的token通过localStorage或者cookie存在本地,
// 然后用户每次在进入页面的时候(即在main.js中),会首先从本地存储中读取token,如果token存在说明用户已经登陆过,
// 则更新vuex中的token状态。然后,在每次请求接口的时候,都会在请求的header中携带token,
// 后台人员就可以根据你携带的token来判断你的登录是否过期,如果没有携带,则说明没有登录过。
// 添加响应拦截器
instance.interceptors.response.use(function (response) {
    if (response.status === 200) {
        return Promise.resolve(response);
    } else {
        return Promise.reject(response);
    }
}, function (error) {
    // 对响应错误做点什么
    if (error.response.status) {
        switch (error.response.status) {
            // 401: 未登录
            // 未登录则跳转登录页面,并携带当前页面的路径
            // 在登录成功后返回当前页面,这一步需要在登录页操作。                
            case 401:
                router.replace({
                    path: '/login',
                    query: {
                        redirect: router.currentRoute.fullPath
                    }
                });
                break;
            // 403 token过期
            // 登录过期对用户进行提示
            // 清除本地token和清空vuex中token对象
            // 跳转登录页面                
            case 403:
                this.$message({
                    message: '登录过期,请重新登录',
                    duration: 1000,
                    type: 'success'
                });
                // 清除token
                localStorage.removeItem('token');
                store.commit('loginSuccess', null);
                // 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面 
                setTimeout(() => {
                    router.replace({
                        path: '/login',
                        query: {
                            redirect: router.currentRoute.fullPath
                        }
                    });
                }, 1000);
                break;
            // 404请求不存在
            case 404:
                this.$message({
                    message: '网络请求不存在',
                    duration: 1500,
                    type: 'success'
                });
                break;
            // 其他错误,直接抛出错误提示
            default:
                this.$message({
                    message: error.response.data.message,
                    duration: 1500,
                    type: 'success'
                });
        }
        return Promise.reject(error.response);
    }
});
/** 
 * get方法,对应get请求 
 * @param {String} url [请求的url地址] 
 * @param {Object} params [请求时携带的参数] 
 */
export function get(url, params) {
    return new Promise((resolve, reject) => {
        instance.get(url, {
            params: params
        })
            .then(res => {
                resolve(res.data);
            })
            .catch(err => {
                reject(err.data)
            })
    });
}
/** 
 * post方法,对应post请求 
 * @param {String} url [请求的url地址] 
 * @param {Object} params [请求时携带的参数] 
 */
export function post(url, params, headers) {
    return new Promise((resolve, reject) => {
        instance.post(url, QS.stringify(params), headers)
            .then(res => {
                resolve(res.data);
            })
            .catch(err => {
                reject(err.data)
            })
    });
}

要注意的是,上面的this.$message方法,是引入的element库中的轻提示组件,你根据你的ui库,对应使用你的一个提示组件。

这里说一下token,一般是在登录完成之后,将用户的token通过localStorage或者cookie存在本地,然后用户每次在进入页面的时候(即在main.js中),会首先从本地存储中读取token,如果token存在说明用户已经登陆过,则更新vuex中的token状态。然后,在每次请求接口的时候,都会在请求的header中携带token,后台人员就可以根据你携带的token来判断你的登录是否过期,如果没有携带,则说明没有登录过。

axios.get()方法和axios.post()在提交数据时参数的书写方式还是有区别的。区别就是,get的第二个参数是一个{},然后这个对象的params属性值是一个参数对象的。而post的第二个参数就是一个参数对象。两者略微的区别要留意哦

api.js的作用

这里我们补充一个知识点:

api文件的作用就是接口统一管理

这里我们定义了一个postLogin方法,这个方法有一个参数p,p是我们请求接口时携带的参数对象。而后调用了我们封装的post方法,post方法的第一个参数是我们的接口地址,第二个参数是postLogin的p参数,即请求接口时携带的参数对象。最后通过export统一导出apiFun对象

import {get,post} from './request'
let apiFun = null;
apiFun.postLogin = p => post('api/v1/users/my_address/address_edit_before', p)
export default apiFun;

然后在我们的mian.js文件中定义成全局变量,方便调用

import apiFun from "./network/api";
Vue.prototype.$apiFun = apiFun;//请求接口api

然后在我们的页面中可以这样调用我们的api接口:

// 调用api接口,并且提供了两个参数                
           this.$apiFun.postLogin({                    
                type: 0,                    
                sort: 1                
            }).then(res => {
                // 获取数据成功后的其他操作
                ………………                
            })

api接口管理的一个好处就是,我们把api统一集中起来,如果后期需要修改接口,我们就直接在api.js中找到对应的修改就好了,而不用去每一个页面查找我们的接口然后再修改会很麻烦.

路由拦截

import Vue from "vue"
import Router from "vue-router"
import Home from '../views/Home.vue'
import store from '../store/index'
Vue.use(Router)
let routes = [
    {
        path: '/',
        name: 'Home',
        component: Home,
        // 重定向
        redirect: '/publiccloud',
        children: [
            {
                path: '/publiccloud',
                name: '公有云用户管理',
                component: () => import('../views/publicCloud/PublicCloud.vue')
            },
            {
                path: '/admin',
                name: '管理员管理',
                component: () => import('../views/admin/Admin.vue')
            }
        ]
    },
    // 登陆页面
    {
        path: "/Login",
        name: "登录页面",
        component: () => import('../views/login/Login.vue')
    },
];
let router = new Router({
    routes,
    mode: 'history',
    // 全局配置激活路由的class类名,处与活跃(动态)就会用上这个类名
    linkActiveClass: 'active'
})
// 设置路由守卫,在进页面之前,判断有token,才进入页面,否则返回登录页面
if (storage.get("token")) {
    store.commit("setToken", localStorage.getItem("token"));
  }
router.beforeEach((to, from, next) => {
    // 设置路由守卫,在进页面之前,判断有token,才进入页面
        if (token) {
            next('/')
        } else {
            // 没有token就调用后端接口,跳转地址
            getAddress().then((res) => {
              if (res.data.code === 200) {
                location.href = res.data.data.redirectUri
              }
            })
        }
});
export default router

登录页面实际使用

submitForm(formName) {
      this.$refs[formName].validate(valid => {
        if (valid) {
          let that = this;
          // console.log('username',this.loginForm.username)
          // 通过校验规则后进入校验用户名密码是否正确
          // 没有后台接口可以自定义一个函数来模拟,替换postLogin
          this.$apiFun.postLogin(this.loginForm.username, this.loginForm.password)
            .then(res => {
              console.log(res);
               that.$store.commit("setToken", res.data.token);
               that.$store.commit("setUserInfo", res.data.account);
              this.$notify({
                title: "登录成功",
                type: "success",
                showClose: false,
                duration: 1000
              });
              setTimeout(() => {
                // 此时要判断/login后面的参数redirect,若无参数,进入主页;
                this.$router.push("/index");
                // 若有参数则参数为未有权限的那个路由,跳转到那个路由
                // this.$router.push(***); -- 具体要自己在这实现
              }, 1000);
            })
            .catch(error => {
            // 错误分为 status-请求错误 和 code-账号密码错误
              this.$message.error(error);
              console.log(error);
            });
        } else {
        // 不符合前端校验
          this.$message.error('format error:'+error);
          console.log('format error:',error);
          return false;
        }
      });
    }
  1. Vue+Vux实现登录功能

准备工作

  1. 安装 NodeJS

  1. 安装 vue-cli

1.vue-cli 2.x 升级到 3.x

(1)卸载 2.x 版本

npm uninstall -g vue-cli

(2)安装

npm install-g @vue/cli

(3)查看版本

vue -V
vue -V@vue/cli5.0.8

创建项目

1.vue-cli 2.x 项目

(1)创建

vue init webpack test2.0

创建完成后,项目目录结构如下:

(2)启动

cd test2.0
npm install
npm run dev

(3)安装 vux ①不使用模板安装

npm install vux --save
npm install vux-loader --save-dev
npm install less less-loader --save-dev

修改 build\webpack.base.conf.js :

const vuxLoader = require('vux-loader')
 
const originalConfig = {
...
 
const webpackConfig = originalConfig // 原来的 module.exports 代码赋值给变量 webpackConfig
 
module.exports = vuxLoader.merge(webpackConfig, {
  plugins: ['vux-ui']
})

src 下创建 views 目录,新建 test.vue 文件:

<template>
  <div style="padding: 15px;">
    <button-tab>
      <button-tab-item selected>{
    
    { today }}</button-tab-item>
      <button-tab-item>{
    
    { week }}</button-tab-item>
      <button-tab-item>{
    
    { month }}</button-tab-item>
    </button-tab>
  </div>
</template>

<script>
  import {ButtonTab, ButtonTabItem} from 'vux'
  export default {
    components: {
      ButtonTab,
      ButtonTabItem
    },
    data () {
      return {
        today: '今天',
        week: '本周',
        month: '本月'
      }
    }
  }
</script>

<style scoped>

</style>

配置路由 router\index.js :

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Test from '@/views/test'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld
    },
    {
      path: '/test',
      name: 'test',
      component: Test
    }
  ]
})

常见错误:

  1. Module build failed: TypeError: this.getOptions is not a function

解决方法:

less 和 less-loader 版本过高,安装低版本:

npm install [email protected] [email protected] --save-dev
  1. You may use special comments to disable some warnings.

Use // eslint-disable-next-line to ignore the next line.

Use /* eslint-disable */ to ignore all warnings in a file.

解决方法:

原因是开启了 eslint 编码规范检查,修改 build\webpack.base.conf.js ,注释掉以下一行代码:

//...(config.dev.useEslint ? [createLintingRule()] : []),

②使用模板安装

vue init airyland/vux2 test-t2.0

官网模板的路由是以常量的形式写在 main.js 中,我们改造到 router/index.js 中去:

修改 main.js:

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import FastClick from 'fastclick'
import router from './router'
// import VueRouter from 'vue-router'
import App from './App'
// import Home from './components/HelloFromVux'
//
// Vue.use(VueRouter)
//
// const routes = [{
//   path: '/',
//   component: Home
// }]
//
// const router = new VueRouter({
//   routes
// })

FastClick.attach(document.body)

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  router,
  render: h => h(App)
}).$mount('#app-box')

修改 index.js:

import Vue from 'vue'
import Router from 'vue-router'
// import HelloWorld from '@/components/HelloWorld'
import Hello from '@/components/HelloFromVux'
import Test from '@/views/test'
 
Vue.use(Router)
 
export default new Router({
  routes: [
    {
      path: '/',
      name: 'Hello',
      component: Hello
    },
    {
      path: '/test',
      name: 'test',
      component: Test
    }
  ]
})

启动:

cd test-t2.0
npm install
npm run dev

(4)安装 axios

npm install axios --save-dev

(5)安装 vuex

npm install vuex --save-dev
  1. vue-cli 3.x 项目

(1)创建

vue create test

创建登录页

  1. main.js 中引入全局 ToastPlugin、LoadingPlugin 插件

import  { ToastPlugin, LoadingPlugin } from 'vux'
Vue.use(ToastPlugin)
Vue.use(LoadingPlugin)
  1. views 下创建 login\login.vue

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Test from '@/views/test'
Vue.use(Router)
export default new Router({
  routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld
    },
    {
      path: '/test',
      name: 'test',
      component: Test
    }
  ]
})
  1. localstorage和sessionstorage的区别

localStorage(本地存储)和sessionStorage(会话存储)。

1、生命周期:localStorage:localStorage的生命周期是永久的,关闭页面或浏览器之后localStorage中的数据也不会消失。localStorage除非主动删除数据,否则数据永远不会消失。

作用域: 相同浏览器的不同标签在同源情况下可以共享localStorage

sessionStorage的生命周期是在仅在当前会话下有效。sessionStorage引入了一个“浏览器窗口”的概念,sessionStorage是在同源的窗口中始终存在的数据。只要这个浏览器窗口没有关闭,即使刷新页面或者进入同源另一个页面,数据依然存在。但是sessionStorage在关闭了浏览器窗口后就会被销毁。同时独立的打开同一个窗口同一个页面,sessionStorage也是不一样的。

作用域:只在当前标签可用,当前标签的iframe中且同源可以共享

2、存储大小:localStorage和sessionStorage的存储数据大小一般都是:5MB

3、存储位置:localStorage和sessionStorage都保存在客户端,不与服务器进行交互通信。

4、存储内容类型:localStorage和sessionStorage只能存储字符串类型,对于复杂的对象可以使用ECMAScript提供的JSON对象的stringify和parse来处理

5、获取方式:localStorage:window.localStorage;;sessionStorage:window.sessionStorage;。

6、应用场景:localStoragese:常用于长期登录(+判断用户是否已登录),适合长期保存在本地的数据。sessionStorage:敏感账号一次性登录;

常用的四个 API 也很简单 :

JavaScript 代码:
// 增加了一个 localStorage ‘myCat’ 数据项
localStorage.setItem('myCat', 'Tom');
 
// 读取 localStorage ‘myCat’ 数据项
let cat = localStorage.getItem('myCat');
 
// 移除 localStorage ‘myCat’ 数据项
localStorage.removeItem('myCat');
 
// 移除所有的 localStorage 数据项
localStorage.clear();

Supongo que te gusta

Origin blog.csdn.net/snow_living/article/details/128904014
Recomendado
Clasificación