Vue学习系列(一)——初识Vue.js核心

前言

vue.js是一套构建用户界面的渐进式框架,vue.js的目标是通过尽可能简单的API实现响应的数据绑定和组合的视图组件。

vue通过DOM事件操作和指令来进行视图层和模型层的相互通讯,会为每一处需要动态更新的DOM节点创建一个指令对象。每当一个指令对象观测的数据变化时,它便会对所绑定的目标节点执行相应的DOM操作。基于指令的数据绑定使得具体的DOM操作都被合理地封装在指令定义中,业务代码只需要涉及模板和对数据状态的操作即可,这使得应用的开发效率和可维护性都大大提升。

因此,数据绑定,组件是整个vue的核心。响应的数据绑定就是数据驱动视图的概念。它让你在写 Web 应用介面时,只需要关注两件事:数据如何展示和数据如何变化。一旦数据发生变化时,比如用户输入,或者 ajax 请求返回后数据发现修改,对应的视图介面会自动的进行更新。

原理

vue.js是MVVM的架构,如图:

从图中可以看出视图层和模型层的相互传递,通过用户操作来绑定一些DOM事件来重新渲染到视图层。具体的内部架构如下图:

开始

一、 数据绑定:

实现方式:数据绑定即是视图层和模型层的双向绑定。即数据的改变驱动了视图的自动更新。

通过ViewModel控制,修改数据,从而控制View的展示,实现MVVM的思想。

里面的两个属性getter和setter,在这两个函数内部实现依赖的收集和触发,而且完美支持嵌套的对象结构。对于数组,则通过包裹数组的可变方法(比如push)来监听数组的变化。这使得操作Vue.js的数据和操作原生对象几乎没有差别。

  • Obejct.defineProperty 【提供getter 和 setter】
  • Observer 【提供getter 和 setter】—— 订阅者模式,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知,用来实时事件处理系统。
  • watcher 【提供getter 和 setter】 —— 模板和 Observer 对象结合在一起的纽带
  • Dep 【负责收集watcher】
  • Directive 【处理Vue模板指令】

    observe -> 触发setter -> watcher -> 触发update -> Directive -> 触发update -> 指令(如上图流程所示)

<span>Hello, this is {{name}}</span>
<script>
var app = new Vue({
    el : ‘#app‘,
    data : {
        name: ‘i3yuan‘
    }
})

</script>

new Vue 执行时做了什么

function Vue(option) {
  var data = option.data
  this.data = data
  // 挂载 getter 和 setter
  observe(data, this)
  var id = option.el
  // 编译 模板
  var dom = new Compile(document.querySelector(id), this)
  // 把编译好的模板挂载到 #app 上
  document.querySelector(id).appendChild(dom)
}
//observe构造函数
function observe(obj, vm) {
  Object.keys(obj).forEach(key => {
    defineReactive(vm, key, obj[key])
  })
}
//defineReactive
function defineReactive(vm, key, val) {
  // 为每个变量分配一个 dep实例
  var dep = new Dep()
  // 配置getter和setter并且挂载到vm上
  Object.defineProperty(vm, key, {
    get() {
      if ( Dep.target ) {
        // JS的浏览器单线程特性, 保证整个全局变量在同一时间内, 只有一个监听器使用
        dep.addSub(Dep.target)
      }
      return val
    },
    set(newVal) {
      if ( newVal == val ) return;
      val = newVal;
      // 作为发布者发出通知
      dep.notify()
    }
  })
}

//Dep构造函数
function Dep() {
  // 存放watcher
  this.subs = []
}

Dep.prototype = {
  // 添加watcher, 也就是添加订阅
  addSub(sub) {
    this.subs.push(sub)
  },
  // 通知所有watcher
  notify() {
    this.subs.forEach(sub => {
      sub.update()
    })
  }
}

function Compile(node, vm) {
  if(node) {
    this.$frag = this.nodeToFragment(node, vm)
    return this.$frag
  }
}

//watcher构造函数
function Watcher(vm, node, name, type) {
  // 单例, 使用原因未知
  Dep.target = this
  // 姓名
  this.name = name;
  // 呵呵哒 uid
  this.id = ++uid;
  // 与变量相关的Node节点
  this.node = node;
  // vm 实例
  this.vm = vm;
  // 变量类型  nodeValue  || value
  this.type = type;
  // 触发自己原型上的update方法
  this.update()
  // Watcher 实例创建结束就把单例置空
  Dep.target = null
}

Watcher.prototype = {
  update() {
    this.get()
    if(!batcher) {
      // bastcher 单例
      batcher = new Batcher()
    }
    // 加入队列
    batcher.push(this)
  },
  // 获取新值挂到自己的实例上
  get() {
    this.value = this.vm[this.name]  // 触发getter
  }
}

整个流程:

new Vue –> Observe 挂载 setter 和 getter –> Compile 编译模板 –> 为每个指令分配一个watcher –> 创建时会调用一次watcher.update 将自己加入到batcher的队列 –>
并且此时会触发 getter 将watcher加入dep –> batcher 统一来处理watcher后初始化自己 –> 当用户修改某个变量时 –> dep通知watcher –> watcher又被加入batcher处理 –> watcher 更新dom 

二、视图组件:

组件,相信大部分开发人员在开发现代框架的时候都或多或少的遇到一些组件,可想而知,现代框架已经走向了组件化的道路,虽然不同的主流框架都有不同封装组件的方式,但是核心思想都差不多一样。通过分离页面,使得整个页面由很多个组件构成,给我们的第一个印象就是,就像我们平时使用到的MVC中的分视图,或者子视图,但是又不一样,虽然组件是一部分,但是却是自己的一个整体,和其他组件相互独立,高内聚低耦合,可以通过自定义标签的形式来使用。

因此,在开发中, 把整一个网页的拆分成一个个区块,每个区块我们可以看作成一个组件。网页由多个组件拼接或者嵌套组成:

// 定义一个名为 Mycomponent  的新组件
Vue.component(‘Mycomponent‘, {
    // 模板
    template: ‘<div>{{msg}} {{privateMsg}}</div>‘,
    // 接受参数
    props: {
        msg: String
    },
    // 私有数据,需要在函数中返回以避免多个实例共享一个对象
    data: function () {
        return {
            privateMsg: ‘component!‘

        }
    }
})<Mycomponent msg="i3yuan"></Mycomponent>

组件的核心选项:

1 模板(template):模板声明了数据和最终展现给用户的DOM之间的映射关系。

2 初始数据(data):一个组件的初始数据状态。对于可复用的组件来说,这通常是私有的状态。

3 接受的外部参数(props):组件之间通过参数来进行数据的传递和共享。

4 方法(methods):对数据的改动操作一般都在组件的方法内进行。

5 生命周期钩子函数(lifecycle hooks):一个组件会触发多个生命周期钩子函数,最新2.0版本对于生命周期函数名称改动很大。

6 私有资源(assets):Vue.js当中将用户自定义的指令、过滤器、组件等统称为资源。一个组件可以声明自己的私有资源。私有资源只有该组件和它的子组件可以调用。

注意事项

  • 组件注册一定要在实例化Vue对象之前,否则会报错
  • 属性名为components,s千万别忘了
  • 不管是全局组件还是局部组件,data都必须是一个函数,且return不能换行
  • 因为this指向的问题,建议用es5的方式写方法

总结

1.通过官方文档的学习和总结,认识到了vue的框架和通讯方式,以视图组件和数据绑定为核心构建完整的渐进式的框架。

2.从上述的两大核心的描述,我们大体理解了Vue的构建方式,通过基本的指令控制DOM,实现提高应用开发效率和可维护性。

3.下一节我们将对Vue视图组件的核心概念进行详细说明。

原文地址:https://www.cnblogs.com/i3yuan/p/11664204.html

时间: 2024-11-06 17:16:25

Vue学习系列(一)——初识Vue.js核心的相关文章

vue学习笔记之初识vue——实例方法声明

如果需要在点击鼠标时,执行一个复杂的操作,那么采用单一的表达式 作为v-on指令值就不够了 -- 我们需要将复杂的操作封装为Vue实例的 一个方法,然后将v-on指令的值设置为这个方法. 使用methods配置项来声明Vue实例的方法.当Vue.js创建一个Vue实例时, 会将methods配置项中声明的方法,挂接到Vue实例对象上: 实例方法可以直接通过实例对象调用,例如,对于上图中的vm实例: vm.handler(); //正确 实例方法另一个常见的用途,是将方法名声明为v-on指令的值,

vue学习二:用 Vue.js + Vue Router 创建单页应用的几个步骤

通过vue学习一:新建或打开vue项目,创建好项目后,接下来的操作为: src目录重新规划——>新建几个页面——>配置这几个页面的路由——>给根实例注入路由配置 src目录重整 在项目中创建如下对应的文件 ├── App.vue // APP入口文件 ├── api // 接口调用工具文件夹 │ └── index.js // 接口调用工具 ├── components // 组件文件夹,目前为空 ├── config // 项目配置文件夹 │ └── index.js // 项目配置文

Vue学习系列(二)——组件详解

前言 在上一篇初识Vue核心中,我们已经熟悉了vue的两大核心,理解了Vue的构建方式,通过基本的指令控制DOM,实现提高应用开发效率和可维护性.而这一篇呢,将对Vue视图组件的核心概念进行详细说明. 什么是组件呢? 组件可以扩展HTML元素,封装可重用的HTML代码,我们可以将组件看作自定义的HTML元素. 为什么要用到组件呢? 为了可重用性高,减少重复性开发,让我们可以使用独立可复用的小组件来构建大型应用. 基本 一.组件注册 1.通过Vue.extend()创建,然后由component来

Vue学习系列(三)——基本指令

前言 在上一篇中,我们已经对组件有了更加进一步的认识,从组件的创建构造器到组件的组成,进而到组件的使用,.从组件的基本使用.组件属性,以及自定义事件实现父子通讯和巧妙运用插槽slot分发内容,进一步的认识到组件在Vue中的核心地位. 而今天,我们将对vue中的基本指令进行了解汇总,指令在Vue中是个很重要的功能,在Vue项目中是必不可少的.根据官网的介绍,指令 (Directives) 是带有 v- 前缀的特殊属性.指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM.

Vue学习系列(四)——理解生命周期和钩子

前言 在上一篇中,我们对平时进行vue开发中遇到的常用指令进行归类说明讲解,大概已经学会了怎么去实现数据绑定,以及实现动态的实现数据展示功能,运用指令,可以更好更快的进行开发.而在这一篇中,我们将通过实例,探究vue的生命周期. 万物皆有灵,世间万物都拥有灵魂,小到山河湖海,花草树木,蚂蚁到人类,以及所有的动植物,大到地球星空和宇宙,都拥有灵魂,可以说他们都是有生命的,只是他们的生命形态是我们人类所不能理解的存在.在生产中,生命周期通俗来讲,就是从自然中来回到自然中去的全过程,也就是从采集材料设

【Vue 学习系列 - 01】- 环境搭建(Win7)

1. 根据系统下载Node.js 下载地址:http://nodejs.cn/download 2. 安装Node.js 点击安装Node.js,在安装目录D:\Program Files\nodejs\下新建node_global和node_cache两个文件夹 设置global和cache npm config set prefix "D:\Program Files\nodejs\node_global" npm config set cache "D:\Program

hibernate学习系列-----(2)hibernate核心接口和工作机制

在上一篇文章hibernate学习系列-----(1)开发环境搭建中,大致总结了hibernate的开发环境的搭建步骤,今天,我们继续了解有关hibernate的知识,先说说这篇文章的主要内容吧: Configuration类 SessionFactory接口 Session接口 Transaction接口 Query和Criteria接口 下面就进行分类别地详细说明: Configuration类 功能描述:Configuration类负责管理Hibernate的配置信息作并根据配置信息启动H

Vue.js系列之一初识Vue

在看vue.js之前,可以先看这两篇文章,对于为什么要使用vue会有一定帮助 1.Vue.js !important 2.界面之下:还原真实的MV*模式 !important 3.web前端优化之reflow(减少页面的回流) 4.深度剖析:如何实现一个 Virtual DOM 算法 本系列文章是基于官方文档,整理的,旨在让新手快速上手.学习vue.js需要一定基础. 一.声明式渲染 1.实现Hello World的功能 还是熟悉的Hello World,下面用Vue.js的声明式渲染来实现 <

Vue学习系列---安装

一.前言 学任何东西都是有理由的,目前主要有Angular,React,Vue这三个前端MVVM框架.我选择vue原因很简单,“”入门简单“”,是的只是这个理由.相较于其他2个框架,vue的文档真的是太亲民的,入门曲线没有那么陡,对于我这种小菜鸟来说,是入门首选.等vue熟悉后,相信再看别的前端MVVM框架也是一通百通的效果. 目前流行的2套基于vue.js的UI框架element-ui(http://element-cn.eleme.io/#/zh-CN/component/installat