首页 > 其他分享 >vue中的几个高级概念

vue中的几个高级概念

时间:2023-02-28 11:14:49浏览次数:52  
标签:vue 过渡 钩子 高级 概念 指令 mixin 组件 name

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0NEJeurD-1677552905427)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/bf111c39bc8742218da6ffaf54a81f70~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.awebp?)]

混入mixins

官方解释

混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。

简单的来说就是 Mixins 是我们可以重用的代码块,在实际开发中,如果有些代码重复性比较高,这时候可以考虑 Mixins 这个特性。

简单的mixin示例

export default {
  data() {
    return {
      name: '来自mixin的name',
      arr: [
        1,
        {
          arrName: '来自mixin',
          arrMixin: '来自mixin'
        },
        1233
      ],
      obj: { name: '来自mixin', value: '来自mixin', mixin: '只有mixin才有的字段' }
    }
  },
  created() {
    console.log('我是mixin的created---')
  },
  mounted() {
    console.log('我是mixin的mounted---')
    this.getInfo()
  },
  methods: {
    getInfo() {
      console.log('我是mixin, getInfo:', this.name)
      console.log('我是mixin的obj:', this.obj)
      console.log('我是mixin的arr:', this.arr)
    }
  }
}

组件中使用

import mixinDemo from './mixin.js'
export default {
  name: '',
  mixins: [mixinDemo],
  components: {},
  data() {
    return {
      name: '组件中的name',
      arr: [
        2,
        {
          arrName: '来自组件的arrName',
          title: '来自组件的独有字段title'
        }
      ],
      obj: { name: '来自组件name', value: '来自组件value', title: '只有组件才有的title字段' }
    }
  },
  computed: {},
  watch: {},
  created() {
    console.log('---我是组件的created---')
  },
  mounted() {
    console.log('---我是组件的mounted---')

    this.getInfo()
  },
  methods: {
    getInfo() {
      console.log('我是组件的, getInfo:', this.name)
      console.log('我是组件的obj:', this.obj)
      console.log('我是组件的arr:', this.arr)
    }
  }
}

控制台结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bbt0x2P1-1677552905430)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d7ba6545f4ce466b904c6a1bc6452a6a~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.awebp?)]

通过以上结果可以发现

  • 生命周期钩子函数会合并起来,都会执行先执行mixins的钩子函数 再 执行组件的钩子函数

  • data 的同名数据,要分情况讨论

如果是基本类型,会用组件的同名数据覆盖mixin的数据。

但是如果是对象,数据对象在内部会进行递归合并,并在发生冲突时以组件数据优先。类似 Object.assign(mixinObj, componentObj);

数组的话则直接以组件中的数据优先

  • methods的方法也是一样,会用组件的方法覆盖mixin的同名方法。

  • 除了上面这些,还有例如 methodscomponentsdirectives,将被合并为同一个对象。两个对象键名冲突时,取组件对象的键值对,同名的会覆盖,以组件的为优先

全局混入

混入也可以进行全局注册。使用时格外小心!一旦使用全局混入,它将影响每一个之后创建的 Vue 实例。使用恰当时,这可以用来为自定义选项注入处理逻辑。

混入造成的问题

用得太多的话,容易混乱。后期维护的时候,不容易查找变量或者方法。

自定义指令 directive

简介

除了核心功能默认内置的指令 (v-modelv-show),Vue 也允许注册自定义指令。注意,在 Vue2.0 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。

比如项目中常用的水印功能。我们对一个 div 范围内添加水印样式。可以用到自定义指令。

首先看看效果图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mO66R3Mu-1677552905432)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fca9143907544d649f2dd573a78924d9~tplv-k3u1fbpfcp-zoom-in-crop-mark:4536:0:0:0.awebp?)]

生成水印有许多方法。我们现在通过自定义指令的方式来操作,以便熟悉自定义指令的使用。

先上代码

方法文件

function addWaterMarker(str, parentNode, font, textColor) {
  // 水印文字生成方法 略
}

const waterMarker = {
  name: 'waterMarker',
  bind: function(el, binding) {
    addWaterMarker(binding.value, el)
  },
  update: function(el, binding) {
    if (binding.oldValue !== binding.value) {
      addWaterMarker(binding.value, el)
    }
  }
}

export default waterMarker
注册自定义指令
import Vue from 'vue'
import waterMarker from './watermark.js'
Vue.directive(waterMarker.name, waterMarker)
main.js全局调用
import './directive.js'
组件中使用

指令需要用 v- + 指令名 方式引用

<div v-waterMarker="'我是水印'" class="wrapper"></div>

指令的钩子函数

一个指令定义对象可以提供如下几个钩子函数 (均为可选):

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。

  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。

  • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。

  • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。

  • unbind:只调用一次,指令与元素解绑时调用。

参考 前端进阶面试题详细解答

指令钩子函数会被传入以下参数:

  • el:指令所绑定的元素,可以用来直接操作 DOM。

  • binding:一个对象,包含以下 property:

    • name:指令名,不包括 v- 前缀。
    • value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2
    • oldValue:指令绑定的前一个值,仅在 updatecomponentUpdated 钩子中可用。无论值是否改变都可用。
    • expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"
    • arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"
    • modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }
  • vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。

  • oldVnode:上一个虚拟节点,仅在 updatecomponentUpdated 钩子中可用。

组件中局部自定义指令

export default {
  directives: {
    waterMarker: {
      // 当前指令的钩子函数 略
      bind() {}
    }
  }
}

过滤器 filter

Vue过滤器本质上是一个函数,它接受一个值,处理它,然后返回处理过的值。

过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持)。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道 ( | ) ”符号指示

组件中使用
<div class="btn-list">
  {{ btn | btnFilter }}
</div>
<div class="btn-list" :id="btn2 | btnFilter">id</div>
组件中定义过滤器
const filterList = [
  { key: 1, text: '提交' },
  { key: 2, text: '查看' },
  { key: 3, text: '编辑' },
  { key: 4, text: '删除' }
]
export default {
  filters: {
    btnFilter(val) {
      return filterList.find(item => item.key === val).text
    }
  },
  data() {
    return {
      btn: 1,
      btn2: 3
    }
  }
}

全局定义过滤器

import Vue from 'vue'
Vue.filter('btnFilter', function (value) { 
    // 逻辑代码...
}) 


--------
// 再到main.js引用即可

过滤器可以 串联 使用

{{ btn | btnFilter | newBtnFilter}}

上述 btn 作为参数传入到 btnFilter 中,然后继续调用 newBtnFilter,此时将以 btnFilter 的结果作为参数使用

过滤器是 JavaScript 函数,因此可以 接收参数

{{ btn | btnFilter('arg1', 'arg2')}}

这里的 btnFilter 相当于是接收三个参数的函数,其中 btn 为第一个参数, 'arg1' 为第二个参数, 'arg2' 为第三个参数。

过渡

Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。包括以下工具:

  • 在 CSS 过渡和动画中自动应用 class
  • 可以配合使用第三方 CSS 动画库,如 Animate.css
  • 在过渡钩子函数中使用 JavaScript 直接操作 DOM
  • 可以配合使用第三方 JavaScript 动画库,如 Velocity.js

Vue 提供了 transition 的封装组件,在下列情形中,可以给任何元素和组件添加进入/离开过渡

  • 条件渲染 (使用 v-if)
  • 条件展示 (使用 v-show)
  • 动态组件
  • 组件根节点

示例

<div class="btn-list" @click="show">
  {{ btn | btnFilter }}
</div>
<transition name="a">
  <p v-if="isShow">过渡动画呀</p>
</transition>
export default {
  data() {
    return {
      isShow: true
    }
  },
   methods: {
    show() {
      this.isShow = !this.isShow
    }
  }
}
.a-enter-active,
.a-leave-active {
  transition: opacity 0.5s;
}
.a-enter,
.a-leave-to {
  opacity: 0;
}

当插入或删除包含在 transition 组件中的元素时,Vue 将会做以下处理:

  1. 自动嗅探目标元素是否应用了 CSS 过渡或动画,如果是,在恰当的时机添加/删除 CSS 类名。
  2. 如果过渡组件提供了 JavaScript 钩子函数,这些钩子函数将在恰当的时机被调用。
  3. 如果没有找到 JavaScript 钩子并且也没有检测到 CSS 过渡/动画,DOM 操作 (插入/删除) 在下一帧中立即执行。(注意:此指浏览器逐帧动画机制,和 Vue 的 nextTick 概念不同)

过渡的类名

在进入/离开的过渡中,会有 6 个 class 切换。

  1. v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。
  2. v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
  3. v-enter-to2.1.8 版及以上定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除。
  4. v-leave:定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。
  5. v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
  6. v-leave-to2.1.8 版及以上定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除。

<transition> 中的 name 对应上述类名的 v , 如: name="a" 则对应类名为 a-enter 等。如果你使用一个没有名字的 <transition>v- 是这些类名的默认前缀。

如此,我们就可以通过编写不同的 css 动画样式,配合<transition>来达到不同的效果。

JavaScript 钩子

  <transition
      v-on:before-enter="beforeEnter"
      v-on:enter="enter"
      v-on:after-enter="afterEnter"
      v-on:enter-cancelled="enterCancelled"
      v-on:before-leave="beforeLeave"
      v-on:leave="leave"
      v-on:after-leave="afterLeave"
      v-on:leave-cancelled="leaveCancelled"
    >
      <!-- ... -->
    </transition>

此时可以在不同的钩子中,使用 Velocity 等动画库来实现我们需要的动画效果。

标签:vue,过渡,钩子,高级,概念,指令,mixin,组件,name
From: https://www.cnblogs.com/yyds2026/p/17163259.html

相关文章

  • 滴滴前端常考vue面试题
    Computed和Methods的区别可以将同一函数定义为一个method或者一个计算属性。对于最终的结果,两种方式是相同的不同点:computed:计算属性是基于它们的依赖进行缓存......
  • 美团前端常见vue面试题(必备)
    v-model是如何实现的,语法糖实际是什么?(1)作用在表单元素上动态绑定了input的value指向了messgae变量,并且在触发input事件的时候去动态把message设置为目标值:<in......
  • vue源码分析-响应式系统(三)
    上一节,我们深入分析了以data,computed为数据创建响应式系统的过程,并对其中依赖收集和派发更新的过程进行了详细的分析。然而在使用和分析过程中依然存在或多或少的问题,这......
  • 字节前端一面常见vue面试题(必备)
    Vue为什么没有类似于React中shouldComponentUpdate的生命周期考点:Vue的变化侦测原理前置知识:依赖收集、虚拟DOM、响应式系统根本原因是Vue与React的变化侦测方式......
  • 密码学基础概念
    把一段原始数据通过某种算法处理成另外一种数据(原始数据为明文,处理后的数据为密文)。明文->密文:称之为加密。密文->明文:称之为解密。图1在加密过程中我们需要知道下面的......
  • VUE2 键盘事件
    常规用法<inputtype="text"@keyup="showInfo"></input>methods:{showInfo(e){console.log(e.target.value)//这种情况会是输入框中实时输入什么,就......
  • VUE2 滚动事件
    滚动条的滚动事件<ul@scroll="gundong"><li>1</li><li>2</li><li>3</li></ul>鼠标滚轮的滚动事件<ul@wheel="gundong"><li>1</li><li>2<......
  • vue3 门户网站搭建5-图标
    奈何element自带的图标太少,不够用,故打算使用 vite-plugin-svg-icons组件来封装svg-icon。ps:ui框架选用的 element-ui,为了能跟vue3更好的结合,还得装个 elemen......
  • 百度前端一面高频vue面试题汇总
    什么是递归组件?举个例子说明下?分析递归组件我们用的比较少,但是在Tree、Menu这类组件中会被用到。体验组件通过组件名称引用它自己,这种情况就是递归组件<template><......
  • 2023前端vue面试题及答案
    Vue3.0为什么要用proxy?在Vue2中,0bject.defineProperty会改变原始数据,而Proxy是创建对象的虚拟表示,并提供set、get和deleteProperty等处理器,这些处理器可在访......