一、作用


1. 概念

vue 官方 将其定义为一个渐进式的 Javascript 框架,这点和 jQuery 是不同的,jQuery 被定义为一个 Javascript 库,库
一般是指第三方提供了一些方法,让我们按需调用,运行时我们是主动方,而框架相对复杂,框架会预先定义好一个流程,
运行时我们的代码要嵌套在其流程中的某个环节运行,我们是被动方,如下图:

库与框架的区别

2. 为何决定使用 Vue

既然已经知道 Vue 是一个框架,那么接下来就是讨论这个框架能够解决什么问题,从而让我决定使用它

社区活跃度、原理和性能先不做讨论,单纯站在开发人员使用的角度,我比较喜欢它如下几点:
(1) Vue 指令属性,丰富的 Vue 指令属性,让我们可以从繁琐的渲染逻辑中释放出来
(2) M-V-VM 模式,让我们从数据和视图的绑定操作中解脱
(3) 基于组件化的特性,再搭配 Vue-CLI 脚手架、Webpack 和 Vue-Loader 等,可以更简单的实现前端工程化


1. 丰富的 Vue 指令属性

Vue 的指令真的非常方便,可以减少很多渲染相关的工作量,让自己更专注于业务本身,

举个例子,需求:在页面渲染 <li>, 每个 <li> 的内容为数组中的元素

原生 JS 实现:

<ul></ul>
<script>
  let sports = ['篮球', '足球', '羽毛球', '乒乓球']
  const ul = document.querySelector('ul')
  for (index in sports) {
    const li = document.createElement('li')
    li.innerText = sports[index]
    ul.appendChild(li)
  }
</script>

通过上面代码可以看到,逻辑全是用来实现渲染的,真的很麻烦,况且这只是一个小例子,如果用 vue 的 v-for 指令实现如下:

Vue 实现 - 只展示核心部分:

<ul>
  <li v-for="item in sports">{{item}}</li>
</ul>

对比后,应该可以发现 Vue 指令真的能帮我们减轻很多渲染相关的工作量,而且 Vue 的指令集很丰富,后期笔记专
门记录、学习。


2. M-V-VM 模式

实际开发中,不管是页面渲染还是数据提交,我们总是不断的对元素进行取值和赋值,而 Vue 利用 M-V-VM 模式很
好的帮我们解决了这个问题,还是举个例子,需求:表单中显示服务器返回的数据,值修改后要做保存,义便提交给服务器

原生 JS 实现

<input type="text" />
<script>
  // 渲染
  window.onload = () => {
    const server = '服务器返回的数据'
    const input = (document.querySelector('input[type=text]').value = server)
  }
  // 值修改
  document.querySelector('input[type=text]').onblur = () => {
    const value = document.querySelector('input[type=text]').value
    console.log(value)
  }
</script>

Vue 实现 - 只展示核心部分:

<input type="text" v-model="server" />

对比结果,依然是 Vue 帮我们简化了工作量

理解 M-V-VM 模式

M-V-VM 模式是一种设计思路,很多框架都对这个思路做了具体的实现,而我们今天只讨论 M-V-VM 的思路,不会
研究 Vue 的 M-V-VM 是如何具体实现的

首先要知道它的全拼,Model-View-ViewModel (数据层 - 视图层 - 数据视图绑定层),它们之间的关系如下,
MVVM
从图中结构可以看出, Model 和 View 分别被 ViewModel 管理着,ViewModel 会监听 Model 中数据的变化,然后自
动渲染到 View ,ViewModel 还会监听 View 元素值的变化,然后自动刷新到 Model 层,这样就实现了 Model 和 View
的双向绑定,不管哪一层发生了变化,都会响应到另外一层。而且图中可以看到 Model 和 View 是不能直接通信的,一切都
交由 ViewModel 处理,这样做的好处就是我们不用再写大量的取值和赋值代码。

我们再看一下 Vue 官方中,关于 Vue 实现 M-V-VM 的图:
Vue - M-V-VM
虽然我们还未研究 Vue 关于 M-V-VM 是如何具体实现的,但依然不耽误我们来理解它的实现原理图,图中各部分都
是 Vue 自己封装的功能,我们现在对其进行简单分类,图中 Data 部分为 Model 层,Watcher 部分为 ViewModel 层,
Component Render Function 和 Virtual DOM Tree 属于 Vue 自己的渲染逻辑, 大概可以理解为 View 层,分完层再套用
M-V-VM 的原理是不是就一下看懂了呢


3. 前端工程化

如今的前端项目与以往不同,现在的前端项目往往体量更庞大、业务更复杂,所以企业内习惯将前端项目工程化,
而使用 Vue 生态系统中的 Vue-CLI、Vue-Loader 等插件,再搭配 Webpack 等构建工具可以非常简单的实现前端工程化

前端工程化、Vue-CLI 等概念及具体实现,都在后续的笔记中有专门记录


二、 Vue 的运用


1. 引用 Vue

不管是 Javascript 库还是 Javascript 框架,只要是第三方的东西,想使用第一件事儿就是引入,而引入的方式,
都大同小异,本地引入、CDN 引入、NPM 引入,本文先不讨论 NPM 引入,因为在后续笔记中会和 Vue-CLI 一起
做记录,来实现前端工程化


本地引入

第一步:vue.js 官网下载链接,vue 分别提供了开发版本和生产版本,自己按需下载就可以
本地引入

第二步:将 vue.js 复制到工程中,通过 <script> 脚本引入即可

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

CDN 引入:

进入 CDN 地址 - 官网提供,选择适合的 <script> 脚本复制,并粘贴到项目中
请添加图片描述

2. Vue 的基本代码结构

引入完毕后,要开始学习使用它,先看下其最基本的结构

<div id="app"></div>
<script>
  new Vue({
    el: 'app',
    data: {
      message: 'Hello, World!',
      users: [
        { name: 'ares5k', age: 27 },
        { name: '3s', age: 27 }
      ]
    },
    methods: {
      out: function () {
        alert(this.message)
      },
      func: function() {
        this.out()
      }
    }
  })
</script>

代码解释:
1. 定义一个元素,并设置其 id 属性
2. 创建 Vue 对象,并传入对象型构造参数,该参数常被称作为 options
3. el 属性:将 id 为 app 的元素托管给 Vue 对象Vue 对象 会解析该元素内的 Vue 语法
4. data 属性:将数据定义在 data 属性后,在被托管的元素中可以通过 Vue 语法 访问这些数据
5. methods 属性:将方法定义在 methods 属性后,在被托管的元素中可以通过 Vue 语法 访问这些方法
注意: options 各个属性间想互相访问, 必须使用 this,如上例中 this.messagethis.out()

例子
有了基本代码结构的基础,我们来看一个小例子,
需求:在画面中将变量打印,并在点击时弹出对话框显示

实现效果:
Vue 最基本结构
实现代码:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vue</title>
  </head>
  <body>
    <div id="app">
      <p @click="out">{{message}}</p>
    </div>
    <script src="vue.js"></script>
    <script>
      new Vue({
        el: '#app',
        data: {
          message: 'Hello, World!'
        },
        methods: {
          out: function () {
            alert(this.message)
          }
        }
      })
    </script>
  </body>
</html>

很简单:
id 为 app 的元素托管给 Vue 对象,然后在元素内使用 {{}} 语法来访问 options.data 中定义的数据,并在元素上添加 @click 属性,让元素单击事件与 options.methods 中的 out 方法绑定, {{}}@click 均为 Vue 语法, 后续笔记会详细介绍

3. Options 中的属性与生命周期钩子方法

疑问:
我学到这里时,一直很好奇,为啥定义在 options.dataoptions.methods 中的内容就可以通过 Vue 对象 访问,如果
定义在其他属性名中是否也可以, 比如把数据定义在 options.myDefined 中, 也能访问吗?

答案:
当然不能,这两个属性中的内容之所以能访问,是因为 Vue 框架 在开发时,就已经预先规定了要从options.data
访问数据, 从options.methods 中访问方法,所以我们在开发使用时才会写这两个属性,而不能乱写,而且 Vue 框架
仅仅规定了这两个,还有很多属性,在后续文章我也会记录一些重要属性的用法

证明:
通过阅读源码就能知道答案,我对这部分的源码进行简化,一看就明白了:

<script>
  // 定义 Vue 类
  function Vue(options) {
    this._init(options)
  }
  // 为 Vue 添加原型方法
  Vue.prototype._init = function (options) {
    callHook(options, 'beforeCreate')
    initState(options)
    callHook(options, 'created')
  }
  // 初始化相关
  function initState(options) {
    var opts = options.$options
    if (opts.props) {
      initProps(options, opts.props)
    }
    if (opts.methods) {
      initMethods(options, opts.methods)
    }
    if (opts.data) {
      initData(options)
    }
    if (opts.computed) {
      initComputed(options, opts.computed)
    }
  }
</script>

new Vue(options) 后,会执行原型方法 _init(options),并调用初始化相关函数 initState(options),这个函数就是对
我们传入的 options 进行解析, 如果有对应的 options 属性,就解析属性的内容,并添加到 Vue 对象中,所以我们使用时可以
直接通过 Vue 对象访问 datamethods 中的内容,而且不止 propsmethodsdatacomputed,我只是截取一小段源码
来说明意思


生命周期的钩子方法

原型方法 _init(options) 中,在 initState(options) 的前后分别调用了 callHook 函数,这个函数被称作 Vue 生命周期的钩子方法, 其实原理还是在传入的 options 中做匹配,比如 initState(options) 前,Vue 对象 要在 options 中找属性名为 beforeCreate 的方法并执行,initState(options) 后,Vue 对象 要找属性名为 created 的方法并执行。

Vue 有很多生命周期的钩子方法, 其意义为:在初始化 Vue 对象 的过程中,每经历一个重要步骤,都会留一个口给
开发人员,允许开发人员传入自己想做的事儿,下面来一张 Vue 官方的生命周期钩子方法图:

Vue 生命周期图
简述生命周期钩子方法的执行时机

生命周期钩子方法名执行时机
beforeCreate解析 options 前,既 data、methods 等都未与 Vue 对象绑定
created解析 options 后, 既 data、methods 等都与 Vue 对象绑定成功, computed 也执行了, 但是还没有挂载要托管的 el元素
beforeMount将数据填充到欲挂载的 el 元素之前
mounted数据填充到挂载的 el 元素之后
beforeUpdateModel 层 或 View 层变化后,未通知对方前
updatedModel 层 和 View 层同步后
beforeDestory组件销毁前
destoryed组件销毁后
Logo

前往低代码交流专区

更多推荐