zoukankan      html  css  js  c++  java
  • web前端知识点(VUE篇)

    vue是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。

    vue是一个MVVM框架,MVVM是一个MVC框架的改进版,由model-view-viewModel三块组成,由viewModel来是实现数据(model)和视图(view)之间的通信。

    生命周期

    生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑。

    beforeCreate、created、beforeMounted、mounted、beforeUpdate、updated、beforeDestroy、destroyed。

    底层实现原理

    vue是一个MVVM的单向数据流,数据双向绑定的框架,2.0的双向数据绑定是由Object.defineProperty来实现,3.0是由Object.proxy来实现。

    具体实现流程:

    • Observer:核心是通过Obeject.defineProperty()来监听数据的变动,这个函数内部可以定义setter和getter,每当数据发生变化,就会触发setter,进行数据劫持,然后通知订阅者,订阅者就是Watcher。
    • Watcher:订阅者作为Observer和Compile之间通信的桥梁。在收到属性变化的通知后,调用自身的更新函数,触发Compile中绑定的回调函数。

    • Compile:主要做的事情是解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图。

    虚拟 DOM 

    虚拟DOM本质上就是一个普通的JavaScript对象,里面能很好的表示DOM元素需要记录的信息:节点名称、属性,文本,子节点等。比如下:

    {
        // 节点类型
        type: 'ul',
        // 节点的属性,包括dom原生属性和自定义属性
        props: {
            class: 'list',
            style: 'color:red;'
        },
        // 子节点数组
        // 子对象结构也是一样,包含了type,props,children,没有子节点的话就是普通文本
        // 子对象拥有子节点时,继续往下扩展就行
        children: [
            {type: 'li',props: {class: 'list'},children: ['利群']},
            {type: 'li',props: {class: 'list'},children: ['玉溪']},
            {type: 'li',props: {class: 'list'},children: ['黄鹤楼']}
        ]
    }

    虚拟DOM的必要性:

    virtual-dom(后文简称vdom)的概念大规模的推广还是得益于react出现,virtual-dom也是react这个框架的非常重要的特性之一。相比于频繁的手动去操作dom而带来性能问题,vdom很好的将dom做了一层映射关系,进而将在我们本需要直接进行dom的一系列操作,映射到了操作vdom,而vdom上定义了关于真实dom的一些关键的信息,vdom完全是用js去实现,和宿主浏览器没有任何联系,此外得益于js的执行速度,将原本需要在真实dom进行的创建节点,删除节点,添加节点等一系列复杂的dom操作全部放到vdom中进行,这样就通过操作vdom来提高直接操作的dom的效率和性能。

    Virtual DOM 算法实现的大致逻辑:

    • 用JavaScript对象结构DOM树的结构,然后用这个结构构建成一个真正的DOM树,并渲染到文档中去。
    • 当JavaScript对象发生变化,则重新构建一颗新的对象树,然后比较两个对象树,记录两棵树之间的差别。
    • 把记录的差别应用到步骤1所构建的DOM树上,完成更新。

    watcher与computed的区别

    watcher:一个值影响多个值;监听已有属性;允许异步操作

    computed:多个值影响一个值;生成一个新的属性;不允许异步操作;必须有依赖型数据;当依赖数据发生变化才会重新计算,否则用缓存;内部有getter和setter方法。

    created与mounted的区别

    主要的区别在于是否有渲染DOM树。

    • beforeCreate:DOM节点、data、methods都不能获取。
    • created:DOM节点不能获取,data、methods可以获取。
    • beforeMounted:DOM节点不能获取,data、methods可以获取。
    • mounted:DOM节点、data、methods都可以获取。

    v-for与v-if为什么避免一起使用

    v-for的优先级高于v-if,所以v-if会执行在每一个v-for的子元素中,从而降低性能。

    解决方法:

    • 将v-if置于v-for的上层
    • 将需要循环的属性通过computed进行过滤,然后v-for循环computed属性。

    循环指令中,key值的作用

    主要作用是用来提高虚拟DOM更新的效率,是在diff算法判断中,用来判断两个节点是否相同的一个很重要的标准。

    组件间的通信

    • 父传子props,v-model,子传父emit
    • 全局vuex,eventBus(Vue.prototype.bus = new Vue())

    vue.use的用途及原理

    use方法是用来扩展插件的。源码如下(src/core/global-api/use.js):

    export function initUse (Vue: GlobalAPI) {
      Vue.use = function (plugin: Function | Object) {
        const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
        // 如果当前plugin已经被use调用过了,则直接返回
        if (installedPlugins.indexOf(plugin) > -1) {
          return this
        }
    
        // additional parameters
        const args = toArray(arguments, 1)
        args.unshift(this)
        // 如果plugin对象中有install方法,则执行
        if (typeof plugin.install === 'function') {
          plugin.install.apply(plugin, args)
        // 如果plugin本身就是方法,则执行
        } else if (typeof plugin === 'function') {
          plugin.apply(null, args)
        }
        // 最后再将plugin缓存起来
        installedPlugins.push(plugin)
        return this
      }
    }

    vue.$nextTick方法的用途及原理

    以下为vue源码(src/core/util/next-tick.js):

    let timerFunc
    // 如果有Promise且是原生API,则选用Promise(微任务)
    if (typeof Promise !== 'undefined' && isNative(Promise)) {
      const p = Promise.resolve()
      timerFunc = () => {
        p.then(flushCallbacks)
        if (isIOS) setTimeout(noop)
      }
      isUsingMicroTask = true
      // 如果支持MutationObserver,则用MutationObserver(MutationObserver是用来监听DOM变化的API,为微任务)
    } else if (!isIE && typeof MutationObserver !== 'undefined' && (
      isNative(MutationObserver) ||
      // PhantomJS and iOS 7.x
      MutationObserver.toString() === '[object MutationObserverConstructor]'
    )) {
      let counter = 1
      const observer = new MutationObserver(flushCallbacks)
      const textNode = document.createTextNode(String(counter))
      observer.observe(textNode, {
        characterData: true
      })
      timerFunc = () => {
        counter = (counter + 1) % 2
        textNode.data = String(counter)
      }
      isUsingMicroTask = true
      // 如果支持setTmmediate,则用setTmmediate(可以看成setTimeout,兼容性不好,仅IE10+及nodejs支持,为宏任务)
    } else if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) {
      timerFunc = () => {
        setImmediate(flushCallbacks)
      }
    } else {
      // Fallback to setTimeout.
      // 最后的应急方案,setTimeout方法(宏任务)
      timerFunc = () => {
        setTimeout(flushCallbacks, 0)
      }
    }

    上面代码分析得出,在vue被实例化执行的时候,首先判断微任务(Promise > MutationObserver)是否支持,然后再判断宏任务(setImmediate)是否支持,最后采用setTimeout方法。具体之间的区别可以查下JavaScript的事件循环,微任务与宏任务的区别。

    mixin

    Mixins 使我们能够为 Vue 组件编写可插拔和可重用的功能。如果我们希望在多个组件间重用一组选项,比如data、computed、methods等,那么我们可以将其写成mixin,并在需要的地方引用它,然后通过mixin合并到当前组件。如果一个组件中有引入mixin,那么mixin中的生命周期hook将优先组件自己内的hook。

    vuex

    Vuex 是一个专为 Vue.js 应用程序开发的响应式状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

    规则:

    • 应用层级的状态应该集中到单个 store 对象中。
    • 提交 mutation 是更改状态的唯一方法,并且这个过程是同步的。
    • 异步逻辑都应该封装到 action 里面。

    5个核心概念:

    • state:单一的状态树对象,包含了全部的应用层级状态。可以简单的理解为整个状态管理的仓库地址,可以设置内部所有属性的初始值,并且整个store状态是响应式的,每当state内的属性值改变,监视的vue组件也会同步更新。
    • mutation:提交 mutation是更改 Vuex 的 store 中的状态的唯一方法,它是一个同步函数。
    • action:类似与mutation,不同的是action不能直接更改state,要通过提交mutation来更改。在action内可以执行任何异步任务,也可以通过dispath调用另一个action任务。
    • module:当项目很复杂的时候,我们可以使用module来进行模块划分。每个module内部都有自己的state,mutation,action,getter、对于模块内部的 mutation 和 getter,接收的第一个参数是模块的局部状态对象、action内部使用的根节点为context.rootState、getter使用的根节点为第三个参数。默认情况下,模块内部的state是注册在全局命名空间的,如果有使用namespaced为true,那么在引用的时候,需要在前面加上模块名称,如(this.$store.dispath('moduleName/actionFunction()'))。
    • getter:可以认为为store的计算属性,通过它可以对state状态的值进行重新计算缓存并返回。

    数据传输流程:

    • 在实例化Vuex.Store()的时候,创建一个全局仓库state,并将内部属性进行数据劫持。
    • state内部数据需要修改的时候需要遵循单项数据流,在组件中通过dispath方法调用action方法。
    • action内部方法处理完成后,然后再调用commit方法通知mutation。
    • mutation内部方法用来修改state中的数据。
    • state内部数据更改完成,因其数据为响应式,则组件中依赖的值也会相应变化

    未完待续......

  • 相关阅读:
    vue-cli webpack 全局引用jquery
    ELK日志框架(2):log4net.ElasticSearch+ Kibana实现日志记录和显示
    ELK日志框架(1):安装Elasticsearch组建单服务器多节点集群
    about-php
    Win7系统下,docker构建nginx+php7环境实践
    Windows7安装 docker-compose的过程
    Windows下docker的安装以及遇到的问题
    crontab的笔试题随想
    composer在update时提示file could not be downloaded: SSL operation failed with code 1. OpenSSL Error messages: error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO
    phpdocumentor 安装以及使用说明
  • 原文地址:https://www.cnblogs.com/kdcg/p/13247386.html
Copyright © 2011-2022 走看看