MVVM

  • M - Model,模型,数据
  • V - View,视图
  • VM - ViewModel

采用数据双向绑定(data-binding):View的变动,自动反映在 ViewModel,反之亦然

Vue

官网

  • v2.x
  • v3.x

Vue 不支持 IE8 及以下版本,因为 Vue 使用了 IE8 无法模拟的 ECMAScript 5 (Object.defineProperty())特性

安装两种版本:

  • 开发版本:包含了警告与调试信息
  • 生产版本:删除了与调试相关的信息,作了压缩混淆

声明式渲染

Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统

<div id="app">
    {{ message }}
</div>

<script>
    const vm = new Vue({
      el: '#app', // element,代表了 view
      data: { // 代表了 Model
        message: 'Hello'
      }
    })
</script>
  • el 表示关联的视图
  • data 表示要渲染的数据
  • 创建的 Vue() 实例相当于是 MVVM 架构中的 VM (ViewModel)
  • 所有东西都是响应式的(数据被修改后,视图会自动重新渲染)

Vue 实例

数据与方法

数据:

  • 当一个 Vue 实例被创建时,它将 data 对象中的所有的 property 加入到 Vue 的响应式系统中,即会将 data 中定义的各属性直接挂载到 Vue 实例下,可以使用 Vue 实例直接调用到 data 中定义的各属性(如果 data 对象中有以 $_ 开头的属性,不会直接挂载到 Vue 实例下),当data中数据被更新时,会自动更新页面渲染。
  • 只有当实例被创建时就已经存在于 data 中的 property 才是响应式的。
  • 在 vue 实例下有 $data 属性,代表的就是 data 对象。
  • 在 vue 实例下有 $options 属性,代表的是创建 Vue 实例时的选项对象。

方法:

  • 创建 Vue 实例时,在 methods 选项中定义的方法也会被直接挂载到 Vue 实例下。

模板语法

插值

文本
{{ expression }}

双花括号之间书写的是 JS 表达式,主要用于绑定渲染文本数据。

双大括号会将数据解释为普通文本,而非 HTML 代码。(对于 HTML 文本,{{ }} 语法会进行转义处理,目的是为了避免出现 XSS 攻击)

html

v-html 指令

attributes

v-bind 指令

指令

就是在 HTML 标签中新添加的一些(以 v-* 开头的)有特殊意义的属性,利用这些属性,在 Vue 中可以实现相应的功能处理。

  • v-html: 渲染 HTML 文本

  • v-text: 渲染纯文本

  • v-bind: 动态绑定属性值,在标签中绑定属性值是不能使用 {{}} 语法,而是需要使用 v-bind 指令。可简写为 :

  • v-on: 注册事件监听,可简写为 @

  • 与条件渲染相关:

    • v-if: 操作的是 DOM 树中节点的销毁、重建
    • v-else-if:
    • v-else:
    • v-show: 操作的是 CSS 样式中的 display
  • v-if vs v-show(面试)v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

  • 与列表渲染相关:

    • v-for:
    <li v-for="item in array"></li>
    <li v-for="item of array"></li>
    <li v-for="(item, index) in array"></li>
    <li v-for="(item, index) of array"></li>
    
    <li v-for="value in object"></li>
    <li v-for="value of object"></li>
    <li v-for="(value, key) in object"></li>
    <li v-for="(value, key) of object"></li>
    <li v-for="(value, key, index) in object"></li>
    <li v-for="(value, key, index) of object"></li>
    
    <li v-for="n in number"></li>
    <li v-for="n of number"></li>
    
    • v-for 与 v-if 一起使用**(面试)**:不推荐同时使用 v-ifv-for。2.x 中当 v-ifv-for 一起使用时,v-for 具有比 v-if 更高的优先级;而 3.x 的版本中则反过来。
    • 建议尽可能在使用 v-for 时提供 key attribute,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。
  • v-once: 只渲染元素和组件一次

  • v-pre: 原样显示

  • v-cloak: 这个指令保持在元素上直到关联实例结束编译。通常结合 css 规则:[v-cloak] { display: none } 一起使用,避免看到未经编译的视图模板内容。

  • v-model: v-model 指令在表单 <input><textarea><select> 元素上创建双向数据绑定。

  • v-slot: 具名插槽使用,可简写为 #

计算属性与侦听器

计算属性

特点:

  • 对复杂的逻辑表达式进行简化运算,方便阅读
  • 计算属性值能够被缓存,只要依赖项不发生变化,就会一直使用缓存的值。只在相关响应式依赖发生改变时它们才会重新求值。
vs method(面试)
  • 计算属性可被缓存,方法不能被缓存
为什么需要缓存?

假设我们有一个性能开销比较大的计算属性 A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A。如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用方法来替代。

侦听器(侦听属性)

当需要在数据变化时执行异步或开销较大的操作时,使用侦听器这个方式是最有用的。

vs 计算属性(面试)
  • 计算属性可被缓存,侦听属性不能被缓存
  • 侦听属性中可包含异步操作等副作用动作,而计算属性中不能包含
  • 计算属性通常是由一个或多个响应式数据计算出一个值返回;而侦听属性通常是监听一个数据的变化,由这一个数据的变化可能影响到另外的一个或多个数据的变化

class 与 style 绑定

vue 对节点绑定 class 与 style 进行了功能增加,除了可以绑定字符串外,也可以绑定对象或数组。

条件渲染

v-if、v-show 指令

列表渲染

v-for 指令

绑定 key

数组更新检测

变更方法(变异方法)

调用这些方法后,原数组本身会受影响:

  • push()
  • pop()
  • unshift()
  • shift()
  • splice()
  • sort()
  • reverse()

调用变更方法后修改数组后,页面会响应式渲染

替换数组

如 slice() 、concat() 这类方法,调用后原数组本身不受影响,页面没有响应式渲染,如果需要将调用结果响应式渲染,可使用替换数组的方式,即利用 = 赋值运算符重新将数组数据值修改。

事件处理

v-on 指令

内联处理器中的方法

可以传递 $event 代表事件对象

事件修饰符:

  • .stop
  • .prevent

按键修饰符:

  • tab
  • enter

表单处理

v-model 指令

v-model 是语法糖。

v-model 在内部为不同的输入元素使用不同的 property 并抛出不同的事件:

  • text 和 textarea 元素使用 value property 和 input 事件;
  • checkbox 和 radio 使用 checked property 和 change 事件;
  • select 字段将 value 作为 prop 并将 change 作为事件。

组件系统

组件系统是 Vue 的另一个重要概念,因为它是一种抽象,允许我们使用小型、独立和通常可复用的组件构建大型应用。

在 Vue 里,一个组件本质上是一个拥有预定义选项的一个 Vue 实例。

定义组件

选项
const options = {
    // template 是关联视图的html模板
    template: `
		<h1>自定义的组件</h1>
	`
}
注册组件

全局:

Vue.component(name, options)

局部:

// 定义组件的选项对象
const options = {
  // template 是关联视图的html模板
  template: `
    <h1>自定义的组件</h1>
  `,
  components: {
    'sub-header': subOptions
  }
}

在父组件的选项对象中添加 components 字段,注册父组件中可以使用到的子组件(即局部注册)

使用组件

将组件名作为自定义标签名来使用,使用标签名时,采用短横线命名规范(即多个单词之间使用 - 分隔)

单文件组件

后缀名为 *.vue 的文件,在 webpack 中处理该类型的文件,会使用 vue-loaderloader 来处理。

<template>
	<!-- View 布局结构 -->
</template>

<script>
	// JS 交互逻辑
</script>

<style lang="scss">
	/* 样式 */
</style>

在 vs-code 中可安装 Vetur 插件,在 *.vue 文件中才会有代码高亮及部分代码提示功能。

data 为什么必须是一个函数(面试)

组件是可被复用的,同一个组件创建出的不同实例彼此之间应该是相互独立的。对象是引用数据类型,如果组件选项中的 data 属性是一个普通对象,则同一个组件所创建出来的所有实例会共享(共用)同一个data对象的数据,则任意一个实例对 data 中数据修改时,其它实例都会受影响。

将 data 定义为一个函数,在该函数体内部返回一个普通对象,这样,当创建组件实例时,会调用 data() 方法,获取返回的新数据对象,则各组件实例间就有自己独立的数据对象了(互不受影响),这与实际开发更符合。

组件通信(面试)

组件与组件之间传递数据

父子组件通信:
  • **父传子:**利用 props 属性传递

  • **子传父:**利用事件。在父组件中使用子组件时,绑定一个自定义事件;在子组件中需要传递数据时,触发($emit())在父组件中绑定的事件 即可。

跨组件跨层级通信:
  • 转换为父子组件通信
  • event-bus(事件总线):借助事件,将数据从一个组件中传递到另一个组件中。
    • 利用 Vue 对象实例的 $on()$emit() 方法
    • $on() 用于注册事件监听
    • $emit() 用于触发指定的事件
    • 通信(传递数据):在 Vue 原型上添加 b u s 属性;在需要接收数据的组件中,调用 ‘ bus 属性;在需要接收数据的组件中,调用 ` bus属性;在需要接收数据的组件中,调用on()注册事件监听,在需要传递数据的组件中,调用$emit()` 触发事件并传递数据
  • vuex

Props 属性

props 是组件从父组件接收到的数据:

{
    props: ['propName1', 'propName2']
}
  • 可以简单定义一个数组,声明组件所能接收并处理的属性名称。
  • 组件 props 属性中接收到的数据也会被直接挂载到组件实例下。
{
  props: {
    // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
    propA: Number,
    // 多个可能的类型
    propB: [String, Number],
    // 必填的字符串
    propC: {
      type: String,
      required: true
    },
    // 带有默认值的数字
    propD: {
      type: Number,
      default: 100
    },
    // 带有默认值的对象
    propE: {
      type: Object,
      // 对象或数组默认值必须从一个工厂函数获取
      default: function () {
        return { message: 'hello' }
      }
    },
    // 自定义验证函数
    propF: {
      validator: function (value) {
        // 这个值必须匹配下列字符串中的一个
        return ['success', 'warning', 'danger'].indexOf(value) !== -1
      }
    }
  }
}
  • 也可以将 props 定义为一个对象,可实现对属性的验证

注意:

  • props 应该是只读的,即不要修改组件获得到的属性值
  • 如果业务中涉及到可能修改属性的值,则需要尝试转换为 data 或 computed 计算属性的方式重新设计。

插槽

作用:在使用组件时,向组件内部分发内容。

使用:<slot>

<slot> 相当于是一个占位符

命名插槽(具名插槽)

<slot name="slot-name">

在使用具名插槽分发内容时,可以使用 slot 属性或 v-slot 指令

  • slot 属性是 v2.6 之前版本中使用的
  • v-slot 指令是 v2.6 中新增的语法,现在推荐使用 v-slot 指令
    • v-slot 指令需要用在 <template> 标签内部,即:<template v-slot:slotName>
    • v-slot 可以简写为 #

生命周期

生命周期:指的是一个 Vue 实例或组件从开始创建,到最终销毁,全阶段所经历的所有过程。

生命周期钩子(函数)(面试)

就是在组件正常的生命周期过程中,提供了一些回调函数,在这些回调函数中可以添加用户自己的代码,完成特定的自定义功能。

create 阶段
  • beforeCreate()
  • created() - 可以使用实例直接调用到 data 中的数据
mount 阶段
  • beforeMount()
  • mounted() - 到该生命周期钩子函数中,才可以获取到渲染后的 DOM 节点
update 阶段

当数据发生变化时,会进行 update 更新阶段

  • beforeUpdate()
  • updated()
destroy 阶段

通常在销毁阶段会销毁哪些资源(面试):启动的定时器、主动注册的事件监听、未完成的网络请求、打开的 socket 连接等

  • beforeDestroy()
  • destroyed()
keep-alive 组件
  • activated(): 被 keep-alive 缓存的组件激活时调用
  • deactivated():被 keep-alive 缓存的组件失活时调用。

渲染函数(render)-了解

render(createElement) {
    // render
}
  • createElement() 创建的虚拟节点元素
  • createElement() 有三个参数:标签、属性、孩子节点

虚拟DOM

<div class="container">
    <span title="提示" class="_span">span_1</span>
    <a href="/">链接</a>
</div>

会被编译为 render() 渲染函数中的内容:

render(createElement) {
    return createElement(
        'div',
        { className: 'container' },
        [
            createElement(
                'span',
                { title: '提示', className: '_span' },
                ['span_1']
            ),
            createElement(
                'a',
                { href: '/' },
                ['链接']
            ),
        ]
    )
}

调用后,返回一个对象:

{
    tag: 'div',
    props: { className: 'container' },
    children: [
        {
            tag: 'span',
           	props: { title: '提示', className: '_span' },
            children: ['span_1']
        },
        {
            tag: 'a',
           	props: { href: '/' },
            children: ['链接']
        },
    ]
}

这是一个保存在内存中的虚拟 DOM 元素结构,这个结构与实体 DOM 树结构映射。

响应式原理(了解)

数据劫持

v2.x 版本中,使用 Object.defineProperty() 实现数据劫持

v3.x 版本中,使用 Proxy 实现数据劫持

过滤器

作用:可被用于一些常见的文本格式化。

过滤器可以用在两个地方:双花括号插值和 v-bind 表达式

过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”(|)符号指示。

全局

Vue.filter()

局部

options = {
    filters: {}
}

keep-alive

<keep-alive> 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。

当组件在 <keep-alive> 内被切换,它的 activateddeactivated 这两个生命周期钩子函数将会被对应执行。

nextTick()–面试

在下次 DOM 更新循环结束之后执行延迟回调。

在修改数据之后立即使用这个方法,获取更新后的 DOM。

Vue Devtools

开发工具

Vue CLI

Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统,其内部封装了 webpack 的相关配置。

安装

版本问题:

2.x 版本创建的项目,会在项目根目录中有多余的关于 webpack 配置的目录及文件。通常是 configbuild 目录及目录内的文件。

3.x/4.x 版本创建的项目,是将 webpack 的配置专门封装到npm包中,在项目根目录下没有相关的 webpack 配置文件存在。

全局安装 vue-cli:

$ npm install -g @vue/cli

安装成功后,可在 cmd 命令提示符下执行 vue --version 测试查看版本信息:

$ vue --version

创建项目

图形化用户界面(GUI):

$ vue ui

命令行:

  1. 执行创建项目命令:
$ vue create vue-cli-demo
  1. 开始利用向导选择项目中使用到的特性:
Please pick a preset:

> Manually select features
  1. 确认项目中的特性:
Check the features needed for your project: (Press <space> to select, <a> to toggle all, <i> to invert selection)

>(*) Choose Vue version
>(*) Babel
>(*) CSS Pre-processors
>(*) Linter / Formatter
  1. 选择 vue 版本:
Choose a version of Vue.js that you want to start the project with (Use arrow keys)
> 2.x
  1. 选择 css 预处理器:
Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): (Use arrow keys)
> Sass/SCSS (with node-sass)
  1. 选择 ESLint
Pick a linter / formatter config: (Use arrow keys)
> ESLint + Standard config
  1. 保存代码时验证代码是否符合规范
Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection)
>(*) Lint on save
  1. 选择在独立文件中保存配置文件
Where do you prefer placing config for Babel, ESLint, etc.? (Use arrow keys)
> In dedicated config files
  1. 是否将此前步骤中的选择保存为模板供以后创建项目使用
Save this as a preset for future projects? (y/N) N
  1. 自动根据前述选择,开始创建项目结构并安装依赖资源

package.json

npm scripts

{
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
}
  • serve:启动开发环境的任务,会打开开发环境下的 webpack-dev-server 服务器,默认监听 8080 端口
  • build:启动构建任务,主要用于构建生产环境下的代码
  • lint:启动规范格式化任务,可将不满足规范的代码格式化

可以使用 npm run 执行

关于 @vue/cli-service 包

内部封装了 webpack 配置,npm scripts 中的任务执行就依赖于这个包。

项目目录结构

|--project
|--public # 单页面应用页面所在目录
|--src # 源代码
|--|--main.js # 应用的入口JS文件
|--|--App.vue # 单文件组件
|--.eslintrc.js # eslint 规范配置文件
|--babel.config.js # babel 配置文件
|--package.json # 应用配置文件

Vuex

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式

采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化

通常使用 vuex 来管理应用中各组件会共享共用的数据。

概念

  • store:仓库,是一个容器,包含着你的应用中大部分的状态 (state)

  • state:状态,组件需要共享的数据

  • getter:是 store 中的计算属性,相当于组件中的 computed

  • mutation:是函数结构,修改状态数据,用于进行 state 的同步更新,约定,mutation 是唯一能够进行状态更新的位置

  • action:是函数结构,可包括异步任务,action 中不能直接更新状态,而是需要通过提交 mutation 来实现

  • module:模块,可将 store 分割成一个个的小的 module,各 module 有自己的 state、getter、mutation、action,甚至子 module

使用

安装

$ npm i vuex

创建 store

import Vue from 'vue'
import Vuex from 'vuex'

// 使用核心插件 Vuex
Vue.use(Vuex)

// 创建 Store
const store = new Vuex.Store({
  state: {},
  getters: {},
  mutations: {},
  actions: {},
  modules: {}
})

// 导出
export default store

注入到 Vue 根实例中

import Vue from 'vue'
import store from './store'

new Vue({
    // ...
    store
})

将 store 注入 Vue 根实例后,在所有的组件实例中,都可以使用 this.$store 调用到 store 对象

编写 state及更新 state 的mutation

// 略

组件中调用 state 及 mutation

{
    computed: {
        todos() {
            this.$store.state.todos
        }
    },
    methods: {
        handler() {
            this.$store.commit('mutation-type', 'payload')
        }
    }
}

注意,在组件中不能直接调用到 mutation 方法,而是需要使用 $store.commit() 来提交 mutation (类似于使用 $emit() 触发事件)

SPA

Single Page Application

单页面应用

是只有一张Web页面的应用,是加载单个HTML 页面并在用户与应用程序交互时动态更新该页面的Web应用程序。

浏览器一开始会加载必需的HTML、CSS和JavaScript,所有的操作都在这张页面上完成,都由JavaScript来控制。

前端路由

前端路由,不会发送 html 页面请求到服务器,就能直接实现界面切换(是在 JS 中完成)。

由于是单页面应用,服务器上只保存了一个 html 页面,所以浏览器访问到该页面时,也会将引用的 js 下载到浏览器本地。

在页面中仍然存在超级链接可以点击切换页面,但这种切换页面并不是真正访问服务器上的 html 页面,而是通过 JS 来实现界面切换(DOM操作)。

模式

  • hash:在URL中采用#号来作为当前视图的地址,改变#号后的参数,页面并不会重载。
  • history:利用 h5 中 history 新增的 API: pushState()、replaceState() ,在调用这些 API 时不会发送新的请求到后端(页面不会重新加载)。
    • history 模式的路由表面上与访问服务端的路由一致(相比 hash 模式来说,没有 #
    • history 模式的路由使用需要在服务器上进行相关配置

Vue Router

Vue.js 官方的路由管理器

使用

安装

$ npm i vue-router

创建 VueRouter 实例

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home'
import About from '../views/About'
import Profile from '../views/Profile'

// 使用 vue-router 核心插件
Vue.use(VueRouter)

// 创建 VueRouter 实例
const router = new VueRouter({
  mode: 'hash', // 前端路由模式:hash、history
  routes: [ // 静态路由配置信息
    {
      path: '/home',
      component: Home
    }
  ]
})

export default router

注入到 Vue 根实例中

import Vue from 'vue'
import App from './App.vue'
import router from './router'

Vue.config.productionTip = false

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

将 router 注入 Vue 根实例后,可在后代组件中使用到两个属性(面试):

  • $router:指代的是 VueRouter 实例
  • $route:当前激活的路由

两个组件

  • <router-link>:链接,导航,默认会渲染为 <a> 超级链接
  • <router-view>:占位,将满足路径中当前访问路由对应的 component 组件进行渲染。

路由元信息

在进行路由相关功能开发时,需要与当前路由相关使用到的数据,可以携带在元信息中,使用 meta 字段表示。

命名视图

有时候想同时 (同级) 展示多个视图,而不是嵌套展示,例如创建一个布局,有 sidebar (侧导航) 和 main (主内容) 两个视图,这个时候命名视图就派上用场了。

<router-view /> 组件添加 name 属性(即命名视图),可使用对应名称指定在 <router-view /> 视图中渲染的组件。如果 <router-view > 没有 name 属性,其 name 值默认为 default

命名路由

是在路由配置项中添加 name 属性,有时候,通过一个名称来标识一个路由显得更方便一些,特别是在链接一个路由,或者是执行一些跳转的时候

编程式的导航

除了使用 <router-link /> 创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。

router.push(location) - 会添加历史记录
router.replace(location) - 不会添加历史记录
router.back()
router.forward()
router.go()

参数 location:

  • 可取字符串
  • 可取对象
    • {path, query}
    • {name, params}
    • 注意:params 必须与 name 配合,不能与 path 共存。
    • 通常 query 这个单词与传递查询字符串(?)参数有关,params 这个单词与传递动态路径参数(/path/to/:params)有关

嵌套路由

通常对应组件的嵌套结构

导航守卫

作用:守卫导航

导航守卫主要用来通过跳转或取消的方式守卫导航

钩子函数

全局
  • beforeEach(callback) - 全局前置守卫,可以在这个钩子函数中进行用户权限拦截
    • 回调函数有三个参数:to、from、next
    • to:即将进入的目标路由对象
    • from:正要离开的路由
    • next:下一步,是在导航解析流程中的“下一步”,是一个函数结构。
      • next():正常走下一步
      • next(false):中断导航
      • next(path):重新跳转到新地址
      • 确保 next 函数在任何给定的导航守卫中都被严格调用一次。它可以出现多于一次,但是只能在所有的逻辑路径都不重叠的情况下,否则钩子永远都不会被解析或报错
  • beforeResolve()
  • afterEach()
路由独享
  • beforeEnter()
组件内
  • beforeRouteEnter() - 不能独 this 获取到组件实例,如果需要使用组件实例,则在 next(callback) 的回调函数中会传递组件实例作为参数

  • beforeRouteUpdate() - 在重用的组件中被调用到

  • beforeRouteLeave()

UI 组件库

常见UI组件库

PC端

移动端

使用

以 Element-UI 组件库为例:

安装

$ npm i element-ui

引入

全部引入

将组件库中的所有组件一次性引入项目中,在使用组件时,不需要再考虑引入哪些就可以直接使用。

缺点:在打包构建时,项目中未使用到的组件也会打包进最后的 bundle 中,会增大代码包的体积。

// 在 main.js 中引入:
// ......
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

Vue.use(ElementUI)
按需引入

是组件库中使用到哪个组件时,才引入使用,未使用到的不需要引入。

优点:可以有效的保证打包后代码包的体积最优

缺点:比较繁琐

安装 babel 插件包:

$ npm install babel-plugin-component -D

配置 babel 相关(修改 babel.config.js 配置文件):

module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset'
  ],
  plugins: [
    [
      'component',
      {
        libraryName: 'element-ui',
        styleLibraryName: 'theme-chalk'
      }
    ]
  ]
}

在自定义的组件中引入 ElementUI 组件:

// main.js
// 按需引入
import {
  Button,
  DatePicker,
  Badge
} from 'element-ui'

// 全局注册组件
Vue.component(Button.name, Button)

// 也可以写作:
Vue.use(DatePicker)
Vue.use(Badge)

// 在组件中仍然使用 <el-xxx> 来使用到 ElementUI 组件

注意:全部引入与按需引入通常不能共存

vue-element-admin

文档

演示地址

网络请求

axios

  • 浏览器中对 XMLHttpRequest 进行封装
  • 支持 Promise API
  • 支持请求/响应拦截处理
  • 支持取消请求

Logo

前往低代码交流专区

更多推荐