Skip to content

一. Vue中自定义指令


1.认识自定义指令

  • Vue的模板语法中我们学习过各种各样的指令:v-showv-forv-model等,除了使用这些指令之外,Vue也允许我们来自定义自己的指令
    • 注意:在Vue中,代码的复用和抽象主要还是通过组件
    • 通常在某些情况下,你需要对DOM元素进行底层操作,这个时候就会用到自定义指令
  • 自定义指令分为两种:
    • 自定义局部指令:组件中通过directives选项,只能在当前组件中使用
    • 自定义全局指令:appdirective方法,可以在任意组件中被使用
  • 比如我们来做一个非常简单的案例:当某个元素挂载完成后可以自定获取焦点
    • 实现方式一:如果我们使用默认的实现方式
    • 实现方式二:自定义一个v-focus的局部指令
    • 实现方式三:自定义一个v-focus的全局指令

2.实现方式一:聚焦的默认实现

image-20220927132230405

3.实现方式二:局部自定义指令

  • 实现方式二:自定义一个v-focus的局部指令

    • 这个自定义指令实现非常简单,我们只需要在组件选项中使用directives即可
    • 它是一个对象,在对象中编写我们自定义指令的名称(注意:这里不需要加v-
    • 自定义指令有一个生命周期,是在组件挂载后调用的mounted,我们可以在其中完成操作
    image-20220816184053318

4.方式三:自定义全局指令

  • 自定义一个全局的v-focus指令可以让我们在任何地方直接使用
image-20220816184137240

5.指令的生命周期

  • 一个指令定义的对象,Vue提供了如下的几个钩子函数:
    • created:在绑定元素的attribute或事件监听器被应用之前调用
    • beforeMount:当指令第一次绑定到元素并且在挂载父组件之前调用
    • mounted:在绑定元素的父组件被挂载后调用
    • beforeUpdate:在更新包含组件的VNode之前调用
    • updated:在包含组件的VNode及其子组件的VNode更新后调用
    • beforeUnmount:在卸载绑定元素的父组件之前调用
    • unmounted:当指令与元素解除绑定且父组件已卸载时,只调用一次

6.指令的参数和修饰符

  • 如果我们指令需要接受一些参数或者修饰符应该如何操作呢?
    • info是参数的名称
    • aaa-bbb是修饰符的名称
    • 后面是传入的具体的值
  • 在我们的生命周期中,我们可以通过bindings获取到对应的内容:
image-20220816184539225

7.自定义指令练习

  • 自定义指令案例:时间戳的显示需求:
    • 在开发中,大多数情况下从服务器获取到的都是时间戳
    • 我们需要将时间戳转换成具体格式化的时间来展示
    • Vue2中我们可以通过过滤器来完成
    • Vue3中我们可以通过 计算属性computed或者 自定义一个方法methods来完成
    • 其实我们还可以通过一个自定义的指令来完成
  • 我们来实现一个可以自动对时间格式化的指令v-format-time
    • 这里我封装了一个函数,在首页中我们只需要调用这个函数并且传入app即可
image-20220816184714870

二. Vue内置组件Teleport


1.认识Teleport

  • 在组件化开发中,我们封装一个组件A,在另外一个组件B中使用:
    • 那么组件Atemplate的元素,会被挂载到组件Btemplate的某个位置
    • 最终我们的应用程序会形成一颗DOM树结构
  • 但是某些情况下,我们希望组件不是挂载在这个组件树上的,可能是移动到Vue app之外的其他位置:
    • 比如移动到body元素上,或者我们有其他的div#app之外的元素上
    • 这个时候我们就可以通过teleport来完成
  • Teleport是什么呢?
    • 它是一个Vue提供的内置组件,类似于reactPortals
    • teleport翻译过来是心灵传输、远距离运输的意思
      • 它有两个属性:
        • to:指定将其中的内容移动到的目标元素,可以使用选择器
        • disabled:是否禁用teleport的功能
image-20220816184942988

2.和组件结合使用

  • 当然,teleport也可以和组件结合一起来使用:
    • 我们可以在teleport中使用组件,并且也可以给他传入一些数据
image-20220816185025626

3.多个teleport

  • 如果我们将多个teleport应用到同一个目标上(to的值相同),那么这些目标会进行合并:
image-20220816185100208
  • 实现效果如下:
image-20220816185115937

三. Vue内置组件Suspense


  • 注意:目前Suspense显示的是一个实验性的特性,API随时可能会修改

  • Suspense是一个内置的全局组件,该组件有两个插槽:

    • default:如果default可以显示,那么显示default的内容

    • fallback:如果default无法显示,那么会显示fallback插槽的内容

      image-20220918212950104

四. Vue中安装插件的方式


1.认识Vue插件

  • 通常我们向Vue全局添加一些功能时,会采用插件的模式,它有两种编写方式:
    • 对象类型:一个对象,但是必须包含一个install的函数,该函数会在安装插件时执行
    • 函数类型:一个function,这个函数会在安装插件时自动执行
  • 插件可以完成的功能没有限制,比如下面的几种都是可以的:
    • 添加全局方法或者 property,通过把它们添加到config.globalProperties上实现
    • 添加全局资源:指令/过滤器/过渡等
    • 通过全局mixin来添加一些组件选项
    • 一个库,提供自己的 API,同时提供上面提到的一个或多个功能

2.插件的编写方式

image-20220816185530361

五. Vue中渲染函数的使用


1.认识h函数

  • Vue推荐在绝大数情况下使用模板template来创建你的HTML,然后一些特殊的场景,你真的需要JavaScript的完全编程的能力,这个时候你可以使用渲染函数,它比模板更接近编译器
  • 前面我们讲解过VNodeVDOM的概念:
    • Vue在生成真实的DOM之前,会将我们的节点转换成VNode,而VNode组合在一起形成一颗树结构,就是虚拟DOM(VDOM)
    • 事实上,我们之前编写的**template中的HTML 最终也是使用render渲染函数生成对应的VNode**
    • 然后交给diff算法对新旧VNode来进行对比,然后决定对具体的VNode所映射的真实dom来进行更新
    • 那么,如果你想充分的利用js的编程能力,我们可以自己来编写createVNode函数,生成对应的VNode
  • 那么我们应该怎么来做呢?使用h函数:
    • h函数是一个用于创建vnode的一个函数
    • 其实更具体的命名是 createVNode函数,但是为了简便在Vue将之简化为h函数

2.h函数如何使用呢?

  • h函数如何使用呢?它接受三个参数:

image-20220816202723335

  • 注意事项:
    • 如果没有props,那么通常可以将children作为第二个参数传入
    • 如果会产生歧义,可以将null作为第二个参数传入,将children作为第三个参数传入

3.h函数的基本使用

  • h函数可以在两个地方使用:

    • render函数选项中
    image-20220816203041304
    • setup函数选项中(setup本身需要是一个函数类型,函数再返回h函数创建的VNode

      image-20220816203122269

六. Vue中编写jsx的语法


1.jsxbabel配置

  • 如果我们希望在项目中使用jsx,那么我们需要添加对jsx的支持:

    • jsx我们通常会通过Babel来进行转换(React编写的jsx就是通过babel转换的)
    • 对于Vue来说,我们只需要在Babel中配置对应的插件即可
  • 安装Babel支持Vuejsx插件:

    js
    	npm i @vue/babel-plugin-jsx -D
  • 如果是Vite环境,需要安装插件:

    js
    	npm i @vitejs/plugin-vue-jsx -D
  • babel.config.js配置文件中配置插件:

image-20220816203413810

2.jsx计数器案例

  • options api中使用:

    image-20220816203708161
  • composition api中使用:

    image-20220816203825452

Released under the MIT License.