vue 衍生知识

前后端的交互方式


使用 json-server 来快速搭建后台服务器

所有的数据可以存放在 server 中创建的 db.json 文件中

在前端的 app 文件中,可以在 index.html 中通过 CDN 的方式引入 Bootstrap 以及 jQuery


Ajax 发送请求

为了方便 ,则使用 jQuery 中所提供的 $.ajax 方法来发送请求

需要 先引入 jquery

  methods: {
    getInfo() {
      // 发送 Ajax 请求
       $.ajax({
         url: "http://localhost:3000/users",
         type: "GET",
         success: (data) => {
           this.stuInfo = data;
         },
       });
    }
  }

Fetch 发送请求

Web 提供的一个可以获取 异步资源的 api (应用程序接口)

所提供的 api 返回的是 Promise 对象

  fetch('http://localhost:3000/stu')
    .then(res=>res.json())
    .then(text=>{
      this.stuInfo = text;
    })

拿到响应对象 res 后,调用 json 方法从响应对象中将 json 数据流转换为一个被解决为 js 对象的 Promise,成功后会再次进入到 then 方法,进入时会传入转换好的 js 对象

Fetch 的 post 请求

fetch("/search/project/", {
    method: "POST",  //请求方法
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: "q=参数q"    //请求体
}).then(function(response) {
});



补充:Promise

主要用于异步编程计算

异步回调的问题:

  • 之前处理异步是通过纯粹的回调函数的形式进行处理
  • 很容易进入到回调地狱中,剥夺了函数return的能力
  • 问题可以解决,但是难以读懂,维护困难
  • 稍有不慎就会踏入回调地狱 - 嵌套层次深,不好维护

Promise 的三种状态

  • pending: 初始状态,不是成功或失败状态。
  • fulfilled: 意味着操作成功完成。
  • rejected: 意味着操作失败。

Promise 优缺点

优点:

将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数,解决回调函数 的 回调地狱

Promise 对象提供统一的接口,使得控制异步操作更加容易

缺点:

一旦新建它就会立即执行,无法中途取消

不设置回调函数,Promise 内部抛出的错误,不会反应到外部

Pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)

Promise的创建

可以使用 new 来调用 Promise 的构造器来进行实例化

var promise = new Promise(function(resolve, reject) {
    // 异步处理
    // 处理结束后、调用resolve 或 reject
});

promise.then() 是 promise 最为常用的方法

实例化过的 promise 对象可以调用 promise.then() 方法,传递 resolve 和 reject 方法作为回调

Promise.reject() 方法返回一个带有拒绝原因的Promise对象


vue-resource 发送请求

vue 是数据驱动的,这使得我们并不需要直接操作 DOM

vue-resourcevue 的一款插件 ,它的 api(应用程序接口) 更为简洁

Fetch 不同,vue-resource 返回的响应对象中的 body 对应的值 直接就是数据,不再需要使用 json 方法来解析一次。


Axios 发送请求

Axios 是一个基于 promisehttp

可以用在浏览器和 node.js

// 引入 axios
import axios from 'axios'
// 配置路径
axios.defaults.baseURL = 'http://localhost:3000/'
// 配置 vue 原型
Vue.prototype.http = axios;
this.http.get('/stu')
    .then(res=>{
      this.stuInfo = res.data;
    })

从响应对象的 data 属性中就可以直接拿到需要的数据


Axios 拦截器

分为请求拦截和响应拦截

请求拦截

在请求发出之前,对请求做一些额外处理,一般是配置统一的 token

响应拦截

在请求返回时,对返回的数据进行一些处理,主要用于获取状态值

如果为 401(约定为 token 失效,需要登录)


路由使用

路由,主要用于 路径的匹配,通过引入 vue-router 文件的方式来实现组件的切换

// 对路由进行注册
Vue.use(Router);
export default new Router({
    // 此对象进行路由配置
    routes : [{
            path : '/comone',
            component : Comone  // 组件首字母大写
        },
        {
            path : '/comtwo',
            component : Comtwo  // 组件首字母大写
}]
});

hashhistory 模式

实现对地址 的切换 ,从而进行不同地址访问

hash 方式:

会在访问地址末尾加 #name

不会被包含在 http 请求中,对后端没有影响,hash 改变不会重新加载页面

history 方式:

没有# ,通过 backforwordgo 等方法控制页面跳转,会请求后端接口,需要后台配置支持

充分利用 history.pushState API 来完成 URL 跳转而实现和hash一样无须重新加载页面

history弊端 :

在history下,可以自由的修改path,当刷新时,如果服务器中没有相应的响应或者资源,会报404


router-link 配置

router-link 用来实现跳转。最终,router-link 会被渲染为 a 标签

    <router-link to="/comone">组1</router-link>
    <router-link to="/comtwo">组2</router-link>

绑定变量

除了在 router-link 中直接为 to 属性指定要切换的组件以外,也通过使用data数据绑定一个变量

      <!-- 要切换的组件来自于变量所对应的值 -->
      <router-link :to="test1">内容1</router-link>
      <router-link :to="test2">内容2</router-link>
 data () {
      return {
        test1: '/com1',
        test2: '/com2'
      }
    }

设置 tag 值指定生成标签

router-link 最终在 html 中生成的是 a 标签

通过 tag 属性,我们可以指定生成为所需要的标签。

<!-- 通过tag 设定后,所生成的就变为div标签 -->     
<router-link :to="test1" tag='div'>内容1</router-link>

设置 router-link 的激活样式

在路由文件中 ,通过 linkActiveClass 可以配置指定的样式

// 设置激活样式
linkActiveClass: '样式名'

更改切换的事件

设置 event 属性,属性值为 mouseover,表示鼠标移入时就会切换组件

<router-link :to="test1" event="mouseover">内容1</router-link>

命名路由

在路由中,可以通过设置name 属性,来代替路径

                {
                    path: 'one',
                    component: One,
                    name: 'childname'  // 命名路由
                }

要实现路劲匹配时,可直接使用 name

    <router-link :to="{name:'childname'}">one</router-link>

命名视图

可以使一个路径显示出 所有的组件

        {  // 命名视图
            path: '/comthree',
            components: {
                default: Comone,
                sider: Comtwo
            }
        }
    <router-link to="/comone">组1</router-link>
    <router-link to="/comtwo">组2</router-link>
    <router-link to="/comthree">组3</router-link>
    <div>
        <router-view name='default'></router-view>
        <router-view name='sider'></router-view>
    </div>

声明式导航

其特点就是要在 router-link 中书写跳转链接,然后通过生成 a 标签的形式来进行跳转。

<router-link :to="test1">内容1</router-link>

编程式导航

就是 vue-router 中给我们提供的一堆方法,让我们可以通过在 js编写代码来实现导航切换

方法包括:backforwardgopushreplace

push

router.push 方法,会向 history 栈 **添加 **一个新的记录

        // 向当前的 history 栈推入一个新的路由
        this.$router.push('/user/two');

replace

类似push,但不会向 history 添加新记录,而是跟它的方法名一样:**替换 **掉当前的 history 记录

        // 替换当前 history 栈中的路由
        this.$router.replace('/user/two');

动态路由

动态路由的匹配

当有带有id的组件时,可以通过动态路由来找到相对应的路径,来进行对应的渲染。

在路由后面添加 /:id,表示路由后面接收一个参数

  path: '/user/:id',

想要有无参数都可以映射到 User 组件,可以在后面添加一个问号(?

  path: '/user/:id?',

获取动态参数

在组件中书写 wathch 方法来进行监听

在组件中,添加 watch 监听方法,当 $route 后面的参数发生改变时会触发此方法

  // 之后对路由进行监听,如果后面的参数发生变化,会触发 $route 方法
  // to 为新的路由,from 为旧的路由
  watch: {
    $route(to, from) {
      let id = to.params.id;
      this.userInfo = userData.filter((item)=>{
        return item.id == id;
      })
      console.log(this.userInfo);
    }
  }



导航守卫

就是 vue-router生命周期钩子函数,主要用来通过跳转或取消的方式来守卫导航

方式:

全局的, 单个路由独享的, 或者组件级的

参数或查询的改变并不会触发进入/离开的导航守卫

可以通过观察 $route 对象响应路由参数的变化)来应对这些变化,或使用 beforeRouteUpdate 的组件内守卫。


全局前置守卫

使用 router.beforeEach 注册

当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于 等待中

守卫方法接收三个参数:

  • to: Route: 即将要进入的目标 路由对象
  • from: Route: 当前导航正要离开的路由
  • next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。

next():

进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。

next(false):

中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。

next('/') 或者 next({ path: '/' }):

跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。

next(error):

(2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError()注册过的回调。

注意:确保 next 函数在任何给定的导航守卫中都被严格调用一次。它可以出现多于一次,但是只能在所有的逻辑路径都不重叠的情况下,否则钩子永远都不会被解析或报错

// BAD
router.beforeEach((to, from, next) => {
  if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
  // 如果用户未能验证身份,则 `next` 会被调用两次
  next()
})
// GOOD
router.beforeEach((to, from, next) => {
  if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
  else next()
})

全局解析守卫

router.beforeResolve 注册一个全局守卫

与 router.beforeEach 的区别:

区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。


全局后置钩子

进入路由之后触发

钩子不会接受 next 函数也不会改变导航本身

router.afterEach((to, from) => {
  // ...
})

路由独享的守卫

对应的路由配置上直接定义 beforeEnter 守卫

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        // ...
      }
    }
  ]
})

组件内的守卫

在路由组件内直接定义

beforeRouteEnter
beforeRouteUpdate (2.2 新增)
beforeRouteLeave
const Foo = {
  template: `...`,
  beforeRouteEnter(to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不能!访问/获取组件实例 `this`
    // 因为当守卫执行前,组件实例还没被创建
  },
  beforeRouteUpdate(to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  },
  beforeRouteLeave(to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 `this`
      //用来禁止用户在还未保存修改前突然离开
  const answer = window.confirm('Do you really want to 		   leave? you have unsaved changes!')
  if (answer) {
    next()
  } else {
    next(false)
  }
  }
}

完整的导航解析流程

  1. 导航被触发。
  2. 在失活的组件里调用 beforeRouteLeave 守卫。
  3. 调用全局的 beforeEach 守卫。
  4. 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
  5. 在路由配置里调用 beforeEnter
  6. 解析异步路由组件。
  7. 在被激活的组件里调用 beforeRouteEnter
  8. 调用全局的 beforeResolve 守卫 (2.5+)。
  9. 导航被确认。
  10. 调用全局的 afterEach 钩子。
  11. 触发 DOM 更新。
  12. 调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。



Vuex

专为 Vue.js 应用程序开发的状态管理模式,也称为 状态机

采用 集中式存储管理 应用的所有组件的状态,组件就直接都和 store 通讯

在构建中大型的单页面应用程序时使用


vuex的核心概念

state

只负责保存仓库的状态(数据)

Getters

可以将对仓库值的修改统一写在 Getter 所对应的函数里面,通过它来获取数据

其他组件中要使用修正后的数据的话,直接从 this.$store.getters 中拉取数据即可

Mutation

通过它组件可以更新仓库里面的数据

    mutations: {
        changeCount(state, payload) {
            state.count += payload;
        }
    },

当其他的组件中,出发了点击事件等,那么在触发事件 methods 中会 commitstore.js 中所定义的 mutation

 methods: {
    clickHandle() {
      //如何修改仓库的数据
      //其实就是调用mutation中的方法
      // 2 作为第二个参数,对面的 payload 会接收此参数
      this.$store.commit("changeCount",2);
    },
  },

Action

Mutation 中混合异步调用会导致你的程序很难调试,异步回调太多,不容易区分时候回调和哪个先回调。

所以在 Vuex 中,将全部的改变都用同步方式实现。将全部的异步操作都放在 Actions

组件 使用 dispatch 来调用在 store.js 中的 action

   this.$store.dispatch("ageChange", age);

MutationAction 的区别

流程顺序:

首先视图先触发action,然后 action再来触发 Mutation

角色的定位:

Mutation:专注于修改 State,理论上是修改 State 的唯一途径。

Action:业务代码、异步请求。

角色限制不同:

Mutation:必须同步执行。

Action:可以异步,但不能直接操作 State

Module

store 分割成模块,减少代码臃肿

每个模块有自己的 state、mutation、action、getter

在 store文件中 使用 modules 整合上面的状态模块

export default new Vuex.Store({  // 使用 modules 整合上面的状态模块  modules: {    students: moduleA,    teachers: moduleB  }})
    // 组件
f01() {
      // this.$store.state 指向 modules
      return this.$store.state.teachers.f01;
    },

辅助函数

简化代码,减少重复和冗余

// 使用之前,需要从 vuex 中引入辅助函数
import { mapState } from "vuex";
    // 使用 mapState 辅助函数之后,一行代码即可获得所有的状态
    ...mapState(["stu1", "stu2"])

前台,后台,前端,后端的区别

前台: 游客、用户能看到的界面

后台: 游客和用户不能够看到的页面,管理员界面,如外卖商家添加商品的界面

前后 与 后台 都是属于 前端的

前端: 就是客户端 ,用HTML CSS JavaScript写的直接看到的界面。如果是三层架构,那就是界面表现层

后端: 就是服务端 ,处理逻辑的处理数据的,如果是三层架构,就是业务逻辑层和数据访问持久层


vue-element-admin

是一个后台前端解决方案,基于 vue 和 element-ui实现,使用了最新的前端技术栈

内置了 i18 国际化解决方案,动态路由,权限验证,提炼了典型的业务模型,提供了丰富的功能组件


目录结构

 build                      构建相关
 mock                       项目mock 模拟数据
 plop-templates              基本模板
 public                      静态资源
    favicon.ico             favicon图标
    index.html              html模板
 src                         源代码
    api                     所有请求
    assets                 主题 字体等静态资源
    components              全局公用组件
    directive               全局指令
    filters                 全局 filter
    icons                   项目所有 svg icons
    lang                    国际化 language
    layout                  全局 layout
    router                  路由
    store                   全局 store管理
    styles                 全局样式
    utils                   全局公用方法
    vendor                  公用vendor
    views                   views 所有页面
    App.vue                 入口页面
    main.js                 入口文件 加载组件 初始化等
    permission.js          权限管理
 tests                       测试
 .env.xxx                    环境变量配置
 .eslintrc.js                eslint 配置项
 .babelrc                    babel-loader 配置
 .travis.yml                 自动化CI配置
 vue.config.js               vue-cli 配置
 postcss.config.js          postcss 配置
 package.json                package.json

路由和侧边栏

实现页面之间的进行跳转,

路由和侧边栏是组织起一个后台应用的关键骨架。

路由的写法:

      {
        path: 'index',
        name: 'Stu',
        component: () => import('@/views/stuboard/index'),
        meta: { title: 'Stu', icon: 'form', breadcrumb: false,affix: true,noCache: true },
      }

路由的配置项目:

当设置 true 的时候该路由不会在侧边栏出现

hidden: true // (默认 false)

当设置 noRedirect 的时候该路由在面包屑导航中不可被点击

redirect: 'noRedirect'

可以设置 alwaysShow: true,这样它就会忽略之前定义的规则,一直显示根路由

alwaysShow: true

和服务端进行交互

处理流程

UI 组件交互操作
调用统一管理的 api service 请求函数
使用封装的 request.js 发送请求
获取服务端返回
更新 data

统一的请求处理都放在 @/api 文件夹中,并且一般按照 model 纬度进行拆分文件

通过环境变量设置多个 baseURL,从而请求不同的 api 地址


快捷导航(标签栏导航)

功能:

添加标签

复制 *admin* 项目中的文件

修改文件



基于 Vue 的前端权限管理

前后端权限控制概述

传统的前后端不分离的开发中,权限管理主要通过过滤器或者拦截器来进行

权限管理框架本身通过过滤器来实现功能

前端所有的菜单显示或者隐藏目的不是为了实现权限管理,而是为了给用户一个良好的体验,不能依靠前端隐藏控件来实现权限管理,即数据安全不能依靠前端。

真正的 数据安全管理 和 权限校验 是在后端实现的,前端则是起到了辅助作用,只要是为了提高用户体验**


后端动态返回

流程:

用户登录成功之后,可以查询到用户的角色,

再根据用户角色去查询出来用户可以操作的 资源,

然后把这些可以操作的资源,组织成一个 JSON 数据,返回给前端,

前端再根据这个 JSON 渲染出相应的菜单。


前端动态渲染

在前端把所有页面都在路由表里边定义好,然后在 meta 属性中定义每一个页面需要哪些角色才能访问

仅用于简单的项目,

弊端:

菜单和角色的关系在前端代码中写死,不方便日后调整


前端权限控制意义

提升突破权限的门槛,手动输 url、控制台发请求、开发者工具改数据这种级别的入侵可以防范掉

过滤越权请求,减轻服务端压力,不该发的请求干脆就让他发不出去

提升用户体验,避免在界面上给用户带来困扰


前端权限控制具体指什么

所有的请求发起都触发自前端路由或视图

路由方面
用户登录后只能看到自己有权访问的导航菜单,也只能访问自己有权访问的路由地址,否则将跳转 4xx 提示页

视图方面
用户只能看到自己有权浏览的内容和有权操作的控件

请求方面
最后再加上请求控制作为最后一道防线,路由可能配置失误,按钮可能忘了加权限,这种时候请求控制可以用来兜底,越权请求将在前端被拦截。



渲染函数

比模板更接近编译器,减少模板的代码冗余

通过 render 函数来实现渲染函数

Vue 的 执行流程:

首先是模板通过编译生成 AST,
再由 AST 生成 Vue 的 render 函数(渲染函数),
渲染函数结合数据生成 Virtual DOM 树,
Diff 和 Patch 后生成新的 UI。

解释:

模板: Vue 的模板基于纯 htmlVue 的模板语法,我们可以比较方便地声明数据和 UI 的关系。

AST: AST 是 Abstract Syntax Tree(抽象语法树)的简称,Vue 使用 htmlParserhtml 模板解析为 AST,并且对 AST 进行一些优化的标记处理,提取最大的静态树,以便更快的生成 Virtual DOM

**渲染函数:**渲染函数是用来生成 Virtual DOM 的。Vue 推荐使用模板来构建我们的应用界面,在底层实现中 *Vue* 会将模板编译成渲染函数,当然我们也可以不写模板,直接写渲染函数,以获得更好的控制。

**Virtual DOM:**虚拟 DOM 树,VueVirtual DOM Patching 算法是基于 Snabbdom 的实现,并在些基础上作了很多的调整和改进。

**Watcher:**每个 Vue 组件都有一个对应的 watcher,这个 watcher 将会在组件 render 的时候收集组件所依赖的数据,并在依赖有更新的时候,触发组件重新渲染。


虚拟 DOM

函数被调用的时候就会渲染并且返回一个虚拟 *DOM* 的树

当重新进行渲染之后,会生成一个新的树,将新的树与旧的树进行对比,就可以最终得出应施加到真实 *DOM* 上的改动。最后再通过 *Patch* 函数施加改动。


SSR

Server Side Render 服务器端渲染

就是服务端渲染好 html 字符串直接返回给前端浏览器展示


传统的服务端渲染

前端发送请求,服务端完成 html 字符串的渲染直接返回给前端,每个页面的请求都如此,浏览器拿到的是全部的 dom 结构,开发模式上前后端不分离


单页应用(SPA

Single Page App 单页,整个项目就一个html页面,通过 js 去监听地址栏的变化来实现页面的dom切换

渲染的流程:

客户端向服务端发送url请求,服务端返回html空壳,客户端再加载JS ,然后向服务发送AJAX请求,拿到服务端返回的json以后,再将其渲染在页面上。


服务端渲染(Server Side Render

后端渲染出完整的首屏 dom 结构返回,前端拿到的内容包括首屏及完整 spa 结构,应用激活后依然按照 spa 方式运行。

渲染的流程:

客户端向服务端发送url请求,服务端通过url ,确定要展示的组件并返回,返回有内容的HTML(首屏),客户端拿到后展示页面,激活spa。


服务器端渲染优缺点

优点:

在服务端生成对应的 html 字符串,客户端接收到对应的 html 字符串,能立即渲染 dom,这可以将首屏耗时降到最低。

更好的 SEO (搜索引擎),服务端直接生成了对应的 html 字符串,对 SEO 也非常友好,因为搜索引擎爬虫抓取工具可以直接查看完全渲染的页面。

更快的内容到达时间,无需等待所有的 JavaScript 都完成下载并执行,才显示服务器渲染的标记,可以产生更好的用户体验

缺点:

开发条件所限,一些外部扩展库(external library)可能需要特殊处理,才能在服务器渲染应用程序中运行

涉及构建设置和部署的更多要求,服务器渲染应用程序,需要处于 Node.js 的服务器运行环境

更多的服务器端负载



Nuxt 框架

是一个 Vue 的通用框架,最常用的就是用来做 SSR(服务器端渲染)

补充:next.js ,是一个用于 生产环境的 React 框架

目录结构

.nuxt                Nuxt自动生成,临时的用于编辑的文件,build
assets               用于组织未编译的静态资源入LESS、SASS 或 JavaScript
components           用于自己编写的Vue组件,比如滚动组件,日历组件,分页组件
layouts              布局目录,用于组织应用的布局组件,不可更改。
middleware           用于存放中间件
pages                用于存放写的页面,我们主要的工作区域
plugins              用于存放JavaScript插件的地方
static               用于存放静态资源文件,比如图片
store                用于组织应用的Vuex 状态管理。
.editorconfig        开发工具格式配置
.eslintrc.js         ESLint的配置文件,用于检查代码格式
.gitignore           配置git不上传的文件
nuxt.config.json     用于组织Nuxt.js应用的个性化配置,已覆盖默认配置
package-lock.json    npm自动生成,用于帮助package的统一性设置的,yarn也有相同的操作
package.json         npm包管理配置文件
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值