美文网首页
前端系统学习 10. Vue高级用法

前端系统学习 10. Vue高级用法

作者: stanf1l | 来源:发表于2022-02-22 23:00 被阅读0次

Vue 高级用法

动画特效

  1. transition 实现路由切换动画
  • App.vue
  • Home -> List -> Detail 页面从右往左出现
  • Detail -> List -> Home 页面从左往右出现

插槽 - Slot

当某些组件或页面的宏观布局确定,局部子组件需要经常变化的时候,十分适合使用 Slot

父组件和子组件的变量作用域都是创建时的作用域,但是父组件可以向 slot 子组件传递数据

  • 默认 slot
  • 具名 slot
  • 作用域 slot
  • 语法糖:#。#defaut
  1. slot 实现原理

slot 本质上是一个返回 VNode 的函数,一般情况下,Vue 中的组件要渲染到页面上需要经过 template -> render function -> VNode -> DOM 的过程

比如一个带 slot 的组件

Vue.component('button-counter', {
  template: '<div> <slot>我是默认内容</slot></div>'
})
 
new Vue({
    el: '#app',
    template: '<button-counter><span>我是slot传入内容</span></button-counter>',
    components:{buttonCounter}
})

经过 vue 编译,组件渲染函数会变成

(function anonymous(
) {
with(this){
  return _c('div',[_t("default",[_v("我是默认内容")])],2)}
})

而这个_t就是 slot 渲染函数

function resolveSlots (
    children,
    context
  ) {
    if (!children || !children.length) {
      return {}
    }
    var slots = {};
    for (var i = 0, l = children.length; i < l; i++) {
      var child = children[i];
      var data = child.data;
      // remove slot attribute if the node is resolved as a Vue slot node
      if (data && data.attrs && data.attrs.slot) {
        delete data.attrs.slot;
      }
      // named slots should only be respected if the vnode was rendered in the
      // same context.
      if ((child.context === context || child.fnContext === context) &&
        data && data.slot != null
      ) {
        // 如果slot存在(slot="header") 则拿对应的值作为key
        var name = data.slot;
        var slot = (slots[name] || (slots[name] = []));
        // 如果是tempalte元素 则把template的children添加进数组中,这也就是为什么你写的template标签并不会渲染成另一个标签到页面
        if (child.tag === 'template') {
          slot.push.apply(slot, child.children || []);
        } else {
          slot.push(child);
        }
      } else {
        // 如果没有就默认是default
        (slots.default || (slots.default = [])).push(child);
      }
    }
    // ignore slots that contains only whitespace
    for (var name$1 in slots) {
      if (slots[name$1].every(isWhitespace)) {
        delete slots[name$1];
      }
    }
    return slots
}

Mixin

本质就是一个 js 对象,它可以包含我们组件中任意功能选项,如 data、components、methods、created、computed等等

我们只要将公用的功能以对象的方式传入 mixins 选项中是,当组件使用 mixins 对象时所有 mixins 对象的选项都将被混入该组件本身的选项中来

在 Vue 中我们可以局部混入和全局混入,全局混入常用来编写插件。

  • 当组件存在与 mixin 对象同名的数据的时候,进行递归合并的时候组件的数据会覆盖 mixin 的数据
  • 如果相同数据为声明周期钩子的时候,会合并成一个数组,先执行 mixin 钩子,在执行组件的钩子。(mounted / beforeDestroy 都是一样的)
  1. mixin 实战
  2. mixin 实现原理
  • 优先递归处理 mixins
  • 先遍历合并 parent 中的 key,调用 mergeField 方法进行合并,然后再保存在变量 options
  • 再遍历 child,合并补上 parent 中没有的 key,调用 mergeField 方法进行合并,保存在变量 options
  • 通过 mergeField 函数进行了合并
export function mergeOption (
  parent: Object,
  child: Object,
  vm?: Component
): Object {
  // 判断有有没有 mixin 也就是 mixin里面挂 mixin 的情况,有的化递归合并
  if (child.mixins) {
    for (let i = 0, l = child.mixins.length; i < l; i++) {
      parent = mergeOptions(parent, child.mixins[i], vm)
    }
  }

  const options = {}
  let key
  for (key in parent) {
    // 先遍历 parent 的 key 调对应的 strats[xxx]方法进行合并
    mergeField(key)
  }

  for (key in child) {
    if (!hasOwn(parent, key)) {
      处理 parent 没有处理的 key
      mergeField(key)
    }
  }

  function mergeField (key) {
    const strat = strats[key] || defaultStrat
    options[key] = strat(parent[key], child[key], vm, key)
  }

  return options
}

其主要逻辑就是合并 mixin 和当前组件的各种数据,细分为四种策略:

  • 替换型策略 - 同名的 props、methods、inject、computed 会被后来者替代

  • 合并型策略 - data,通过 set 方法进行合并和重新赋值

  • 队列型策略 - 生命周期钩子、watch。将函数存入一个数组,顺序执行

  • 叠加型策略 - components、directives、filters,通过原型链层层叠加

插件

插件就是指对 Vue 的功能的增强或补充

  1. 什么是插件?如何编写一个插件
MyPlugin.install = function (Vue, options) {
  // 1. 添加全局方法或 property
  Vue.myGlobalMethod = function () {}

  // 2. 添加全局资源
  Vue.directive('my-directive', {
    bind (el, binding, vnode, oldVNode) {}
  })

  // 3. 注入组件选项
  Vue.mixin({
    created: function () {}
  })

  // 4. 添加实例方法
  Vue.prototype.$myMethod = function (options) {

  }

}

Vue.use(plugin, options)
  1. Vue.use做了什么
  • 判断当前插件是否已经安装过,防止重复安装
  • 处理参数,调用插件的 install 方法。第一个参数是 Vue 实例。
Vue.use = function (plugin, options) {
  const installedPlugins = this._installedPlugins || (this._installedPlugins = [])

  if (installedPlugins.indexOf(plugin) > -1) return this

  // init plugin.install()
  const args = Array.prototype.slice.call(arguments, 1)
  args.unshift(this)

  if (typeof plugin.install === 'function') {
    plugin.install.apply(plugin, args)
  } else if (typeof plugin === 'function') {
    plugin.apply(null, args)
  }

  installedPlugins.push(plugin)
  return this
}

相关文章

  • 前端系统学习 10. Vue高级用法

    Vue 高级用法 动画特效 transition 实现路由切换动画 App.vue Home -> List ->...

  • vue(3) - 收藏集 - 掘金

    Vue2.0 Transition 常见用法全解惑 - 前端 - 掘金Vue2.0的过渡系统(transition...

  • vue资源推荐

    vue资源推荐 写给初中级前端的高级进阶指南。写给初中级前端的高级进阶指南这篇文章不错 推荐给大家 vue技术揭秘...

  • Vue 进阶系列(一)之响应式原理及实现

    Vue进阶系列汇总如下,欢迎阅读,欢迎加高级前端进阶群一起学习(文末)。 Vue 进阶系列(一)之响应式原理及实现...

  • Vue 进阶系列(三)之Render函数原理及实现

    Vue进阶系列汇总如下,欢迎阅读,欢迎加高级前端进阶群一起学习(文末)。 Vue 进阶系列(一)之响应式原理及实现...

  • Vue 进阶系列(二)之插件原理及实现

    Vue进阶系列汇总如下,欢迎阅读,欢迎加高级前端进阶群一起学习(文末)。 Vue 进阶系列(一)之响应式原理及实现...

  • Vue框架使用总结

    Vue是目前比较流行的web前端框架,所以趁着暑假学习一波,于是写了自己的博客系统项目地址: 前端 后端因为Vue...

  • vue高级用法

    Vue 插件 plugin 1, Vue 插件 plugin 安装 Vue.js 插件。如果插件是一个对象,必须提...

  • Vue的模板语法

    Vue的基本用法 ?Vue.js官网:https://cn.vuejs.org/ 介绍 前端的JavaScript...

  • 详解Vue的slot新用法

    摘要: 理解Vue插槽。 作者:前端小智 原文:vue 2.6 中 slot 的新用法 Fundebug经授权转载...

网友评论

      本文标题:前端系统学习 10. Vue高级用法

      本文链接:https://www.haomeiwen.com/subject/itmnlrtx.html