重新认识一下 vue3 应用实例

重新认识一下 vue 应用实例

💕 创建应用实例

每个 Vue 应用都是通过 createApp 函数创建一个新的 应用实例

应用实例必须在调用了 .mount() 方法后才会渲染出来。该方法接收一个“容器”参数,可以是一个实际的 DOM 元素或是一个 CSS 选择器字符串

// main.js
import App from './App.vue'
import { createApp } from 'vue'const app = createApp(App)
app.mount('#app')

在这里插入图片描述

因此我们可以在入口文件中,通过创建多个 DOM 节点,并在 main.js 文件中创建多个应用实例


💕 app.createApp()、app.createSSRApp()

createApp: 除了可以传递第一个参数是根组件外,还可以传递第二个参数(可选),它是要传递给根组件的 props

// main.js
import App from './App.vue'
import { createApp } from 'vue'const app = createApp(App, { msg: '我是通过 createApp 传递给到 根组件 的' })
app.mount('#app')
// App.vue
const props = defineProps({msg: {type: String}
})
onMounted(() => {console.log(props.msg) // 我是通过 createApp 传递给到 根组件 的
})

createSSRApp():以 SSR 激活模式创建一个应用实例。用法与 createApp 完全相同。


💕 app.mount()、app.unmount()

mount:将应用实例挂载在一个容器元素中。对于每个应用实例,mount 仅能调用一次

参数可以是一个实际的 DOM 元素或一个 CSS 选择器 (使用第一个匹配到的元素)

app.mount('#app')
app.mount(document.body.firstChild) // 挂载到一个实际的 DOM 元素

unmount:卸载一个已挂载的应用实例。卸载一个应用会触发该应用组件树内所有组件的卸载生命周期钩子

import App from './App.vue'
import { createApp } from 'vue'const app = createApp(App)
app.mount('#app')// 2s 后 销毁掉 应用实例
setTimeout(() => {app.unmount()
}, 2000)

在组件 HelloWorld 中,当应用挂载完成后,2s 后销毁应用,可以发现其应用组件树内所有组件的卸载生命周期钩子都会触发

<script setup>
import { onBeforeMount, onBeforeUnmount, onMounted, onUnmounted } from 'vue'
onMounted(() => {console.log('HelloWorld Mounted')
})
onBeforeMount(() => {console.log('HelloWorld BeforeMount')
})
onBeforeUnmount(() => {console.log('HelloWorld BeforeUnmount')
})
onUnmounted(() => {console.log('HelloWorld UnMounted')
})
</script>

在这里插入图片描述


💕 app.component()

component:用于全局组件的注册,后续在该应用实例下的所有组件都可以使用该组件,无需再次局部注册

import App from './App.vue'
import { createApp } from 'vue'
import HelloWorld from './components/HelloWorld'
const app = createApp(App)
app.mount('#app')// 注册全局组件
app.component('HelloWorld', HelloWorld)

但全局注册有以下几个问题:

  • ✨如果你全局注册了一个组件,即使它并没有被实际使用,它仍然会出现在打包后的 JS 文件中(tree-shaking
  • ✨在父组件中使用子组件时,不太容易定位子组件的实现。和使用过多的全局变量一样,这可能会影响应用长期的可维护性

相比之下,局部注册的组件需要在使用它的父组件中显式导入,并且只能在该父组件中使用。它的优点是使组件之间的依赖关系更加明确,并且对 tree-shaking 更加友好。

<script setup>
import HelloWorld from './components/HelloWorld.vue'
</script>
<template><HelloWorld />
</template>

💕 app.directive()

directive:全局注册自定义指令

👨:什么是自定义指令

🧒:利用组件的生命周期钩子函数重用涉及普通元素的底层 DOM 访问的逻辑。vue 提供了内置指令(如:v-modelv-showv-if

在组件中:实现自定义指令

<script setup>
const customFocus = {// 组件挂载时,自动获取焦点  mounted: (el) => el.focus()
}
</script>
<template>
<input custom-focus />
</template>

全局注册(这里实现一个权限控制的自定义指令)

<button v-auth="['importUser']"></button>
// authBtn.js
import store from '@/store'function checkPermission (el, binding) {// 获取绑定的值,此处为权限 value: ['importUser']const { value } = binding// 获取所有的功能指令(后端请求回来的数据)const points = store.getters.userInfo.permission.points// 当传入的指令集为数组时if (value && value instanceof Array) {// 匹配对应的指令const hasPermission = points.some(point => {return value.includes(point)})// 如果无法匹配,则表示当前用户无该指令,那么删除对应的功能按钮if (!hasPermission) {// 移除节点el.parentNode && el.parentNode.removeChild(el)}} else {// eslint-disabled-next-linethrow new Error('v-permission value is ["admin","editor"]')}
}export default {// 在绑定元素的父组件被挂载后调用mounted (el, binding) {checkPermission(el, binding)},// 在包含组件的 VNode 及其子组件的 VNode 更新后调用update (el, binding) {checkPermission(el, binding)}
}
// 指令入口文件,将定义的组件进行抛出
import authBtn from './authBtn'
export default app => {app.directive('v-auth', authBtn)
}
import App from './App.vue'
import { createApp } from 'vue'
import HelloWorld from './components/HelloWorld'
const app = createApp(App)
app.mount('#app')
// main.js
import installDirective from '@/directives'
installDirective(app)

💕 app.use()

use:安装一个插件

👨:如何安装一个插件

🧒:安装一个插件的本质是通过传递应用实例对象给到自定义插件中,在插件中针对这个对象进行操作

👨:那它是通过什么方式将应用实例对象进行传入的

🧒:通过 use 方法进行安装,默认会调用插件的 install 方法,有点 component 的使用方式

import App from './App.vue'
import { createApp } from 'vue'
import myPlugin from './plugin'const app = createApp(App)
// 安装插件
app.use(myPlugin, {type: '参数类型',msg: '自定义插件'
})app.mount('#app')
const myPlugin = {install: (app, options) => {console.log('安装自定义的组件')console.log(app, '应用实例对象')console.log(options, '配置参数')// 进行安装操作。。。。// 如挂载一个全局变量,注册全局组件,依赖注入等}
}export default myPlugin

在这里插入图片描述


💕 app.mixin()

mixin:应用一个全局 mixin (适用于该应用的范围)。一个全局的 mixin 会作用于应用中的每个组件实例。

不推荐

Mixins 在 Vue 3 支持主要是为了向后兼容,因为生态中有许多库使用到。在新的应用中应尽量避免使用 mixin,特别是全局 mixin

// main.js
import App from './App.vue'
import { createApp } from 'vue'
const app = createApp(App)const myMixin = {data() {return {message: 'Hello World'}},created() {console.log('Mixin created');},methods: {someMethod() {console.log('Mixin method');},}
}// 注入 mixin
app.mixin(myMixin)app.mount('#app')
<!-- HelloWorld -->
<div>{{ message }}<button @click="someMethod">测试</button>
</div>
<script>
export default {created() {console.log('Component created')},methods: {componentMethod() {console.log('Component method');}}
}
</script>

💕 app.provide()

provide:提供一个值,可以在应用中的所有后代组件中注入使用

import App from './App.vue'
import { createApp } from 'vue'
const app = createApp(App)// 全局注入
app.provide('msg', 'hello')
app.mount('#app')

在应用的某个组件中:

<!-- HelloWorld -->
<script setup>
import { inject } from 'vue'
const msg = inject('msg')    
</script>
<template>
{{ msg }}
</template>

同理:在某个组件中,也可以通过provide 的方式将变量(方法)进行注入

<script setup>
import { provide } from 'vue'
const location = ref('North Pole')
const updateLocation = () => {location.value = 'South Pole'
}
provide('location', {location,updateLocation
})
</script>
<script setup>
import { inject } from 'vue'const { location, updateLocation } = inject('location')
</script><template><button @click="updateLocation">{{ location }}</button>
</template>

💕 app.runWithContext()

runWithContext:使用当前应用作为注入上下文执行回调函数(vue3.3 以上)

import { inject } from 'vue'app.provide('id', 1)const injected = app.runWithContext(() => {return inject('id')
})console.log(injected) // 1

💕 app.version

version:提供当前应用所使用的 Vue 版本号

通过判断当前 vue 版本,执行不同的安装插件方式

export default {install(app) {const version = Number(app.version.split('.')[0])if (version < 3) {console.warn('This plugin requires Vue 3')}}
}

💕 app.config.globalProperties

globalProperties:用于注册能够被应用内所有组件实例访问到的全局属性的对象

app.config.globalProperties.$msg = '123'
<template><HelloWorld :msg="$msg" />
</template>

💕 不常用 app.config.optionMergeStrategies

optionMergeStrategies:一个用于定义自定义组件选项的合并策略的对象

const app = createApp({// 自身的选项msg: 'Vue',// 来自 mixin 的选项mixins: [{msg: 'Hello '}],mounted() {// 在 this.$options 上暴露被合并的选项console.log(this.$options.msg)}
})// 为 `msg` 定义一个合并策略函数
app.config.optionMergeStrategies.msg = (parent, child) => {return (parent || '') + (child || '')
}app.mount('#app')
// 打印 'Hello Vue'

💕 不常用 app.config.errorHandler()

errorHandler:用于为应用内抛出的未捕获错误指定一个全局处理函数

interface AppConfig {errorHandler?: (err: unknown, // 错误对象instance: ComponentPublicInstance | null, // 触发该错误的组件实例info: string // 指出错误来源类型信息的字符串) => void
}

它可以从下面这些来源中捕获错误:

  • 组件渲染器
  • 事件处理器
  • 生命周期钩子
  • setup() 函数
  • 侦听器
  • 自定义指令钩子
  • 过渡 (Transition) 钩子
app.config.errorHandler = (err, instance, info) => {console.log(err, 'err')console.log(instance, 'instance')console.log(info, 'info')
}
<script setup>
const throwError = () => {throw new Error('错误信息')
}
</script>
<template><button @click="throwError">抛出错误</button>
</template>

在这里插入图片描述


💕 不常用 app.config.warnHandler()

warnHandler:用于为 Vue 的运行时警告指定一个自定义处理函数

interface AppConfig {warnHandler?: (msg: string, // 警告信息instance: ComponentPublicInstance | null, // 组件实例trace: string // 组件追踪字符串) => void
}

💕 不常用 app.config.performance

performance:设置此项为 true 可以在浏览器开发工具的“性能/时间线”页中启用对组件初始化、编译、渲染和修补的性能表现追踪。

在这里插入图片描述


💕 不常用 app.config.compilerOptions

✔ 官方解释

在这里插入图片描述

✔ 自己的理解:运行编译 vue 文件时,需要调用一些内部内部compilerOptions配置好的方法。我们可以通过修改 compilerOptions 提供的方法,来改写编译过程的一些方法。(不对的话,请多多指教)


💕 不常用 app.config.compilerOptions.isCustomElement()

isCustomElement:用于指定一个检查方法来识别原生自定义元素

// 将所有标签前缀为 `ion-` 的标签视为自定义元素
app.config.compilerOptions.isCustomElement = (tag) => {return tag.startsWith('ion-')
}

💕 不常用 app.config.compilerOptions.whitespace

whitespace:用于调整模板中空格的处理行为

  • 类型 'condense' | 'preserve'

  • 默认 'condense'

  • 详细信息

    Vue 移除/缩短了模板中的空格以求更高效的模板输出。默认的策略是“缩短”,表现行为如下:

    1. 元素中开头和结尾的空格字符将被缩短为一个空格。
    2. 包含换行的元素之间的空白字符会被删除。
    3. 文本节点中连续的空白字符被缩短成一个空格。

    设置该选项为 'preserve' 则会禁用 (2) 和 (3) 两项。


💕 不常用 app.config.compilerOptions.delimiters

delimiters:用于调整模板内文本插值的分隔符

  • 类型 [string, string]

  • 默认 ['{{', '}}']

  • 详细信息

    此项通常是为了避免与同样使用 mustache 语法的服务器端框架发生冲突。


💕 不常用 app.config.compilerOptions.comments

comments:用于调整是否移除模板中的 HTML 注释

  • 详细信息

    默认情况下,Vue 会在生产环境移除所有注释,设置该项为 true 会强制 Vue 在生产环境也保留注释。在开发过程中,注释是始终被保留的。这个选项通常在 Vue 与其他依赖 HTML 注释的库一起使用时使用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/233747.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【bug】【VSCode】远程终端TERMINAL打不开

【bug】【VSCode】远程终端TERMINAL打不开 可能的原因现象分析解决 可能的原因 昨天晚上vscode在打开多个TERMINAL的情况下&#xff0c;挂了一晚上&#xff0c;今早上来看的时候全都lost connections…。然后关闭再打开就出现了如上现象。 早上一来到实验室就要debug… 现象…

【UE Niagara学习笔记】03 - 火焰喷射效果

目录 效果 步骤 一、创建粒子系统 二、制作火焰动画 三、改为GPU粒子 四、循环播放粒子动画 五、火焰喷射效果雏形 六、火焰颜色 效果 步骤 一、创建粒子系统 1. 新建一个Niagara系统&#xff0c;选择模板 命名为“NS_Flame_Thrower”&#xff08;火焰喷射&#…

IntelliJ IDEA 如何编译 Maven 工程项目

在当今的Java开发领域&#xff0c;Maven已经成为项目构建和依赖管理的标准工具。IntelliJ IDEA作为一款集成度高的Java开发环境&#xff0c;提供了许多强大的功能来简化和优化Maven项目的构建流程。本文将深入介绍如何使用IntelliJ IDEA编译Maven工程的详细步骤以及一些高级技巧…

day6:进程间的通信

思维导图&#xff1a; 实现多个进程之间的收发信息操作 create.c&#xff1a; #include <head.h> int main(int argc, const char *argv[]) {if(mkfifo("a_send_b",0664)!0){perror("");return -1;}if(mkfifo("b_send_a",0664)!0){perro…

用Java编写图书网站信息采集程序教程

目录 一、准备工作 二、分析目标网站结构 三、选择信息采集方式 四、安装Jsoup库 五、编写信息采集程序 六、注意事项 总结&#xff1a; 编写图书网站信息采集程序需要掌握HTML、CSS、JavaScript、Java等前端和后端技术。下面是一个简单的教程&#xff0c;介绍如何使用…

Java后端开发——SSM整合实验

文章目录 Java后端开发——SSM整合实验一、常用方式整合SSM框架二、纯注解方式整合SSM框架 Java后端开发——SSM整合实验 一、常用方式整合SSM框架 1.搭建数据库环境&#xff1a;MySQL数据库中创建一个名称为ssm的数据库&#xff0c;在该数据库中创建一个名称为tb_book的表 …

Spring MVC(day1)

什么是MVC MVC是一种设计模式&#xff0c;将软件按照模型、视图、控制器来划分&#xff1a; M&#xff1a;Model&#xff0c;模型层&#xff0c;指工程中的JavaBean&#xff0c;作用是处理数据 JavaBean分为两类&#xff1a; 一类称为数据承载Bean&#xff1a;专门存储业务数据…

代码随想录算法训练营第三十天|总结、332.重新安排行程、51.N皇后、37.解数独

代码随想录 (programmercarl.com) 总结 332.重新安排行程 欧拉通路和欧拉回路&#xff1a; 欧拉通路&#xff1a;对于图G来说&#xff0c;如果存在一条通路包含G的所有边&#xff0c;则该通路称为欧拉通路&#xff0c;也称欧拉路径。欧拉回路&#xff1a;如果欧拉路径是一条…

06-微服务-SpringAMQP

SpringAMQP SpringAMQP是基于RabbitMQ封装的一套模板&#xff0c;并且还利用SpringBoot对其实现了自动装配&#xff0c;使用起来非常方便。 SpringAmqp的官方地址&#xff1a;https://spring.io/projects/spring-amqp SpringAMQP提供了三个功能&#xff1a; 自动声明队列、交…

Scrum的工件

我们采用了Scrum进行开发方面的管理&#xff0c;那么所有的计划和工作都应该是透明的&#xff0c;这给了我们检查这些东西的机会&#xff0c;以便能够即时做出调整来适应即将发生的变化。 那么Scrum为我们设计了一些工件帮助我们检查我们的工作和计划&#xff0c;每个工件都有…

QT qss文件设置样式

方式一 &#xff08;单个&#xff09; 方式二 &#xff08;全局&#xff09; 所有按钮都会采用这个样式。 方式三 &#xff08;qss文件&#xff09; 创建资源文件 创建qss文件&#xff08;Button.qss&#xff09; 引用qss文件 QApplication a(argc, argv);QString qss;QFile…

元数据管理平台对比预研 Atlas VS Datahub VS Openmetadata

大家好&#xff0c;我是独孤风。元数据管理平台层出不穷&#xff0c;但目前主流的还是Atlas、Datahub、Openmetadata三家&#xff0c;那么我们该如何选择呢&#xff1f; 本文就带大家对比一下,这三个平台优势劣势。要了解元数据管理平台&#xff0c;先要从架构说起。 正文共&am…

k8s的pod基础

pod概念 pod是k8s中最小的资源管理组件。 pod也是最小化运行容器化的应用的资源管理对象。 pod是一个抽象的概念&#xff0c;可以理解为一个或者多个容器化应用的集合。 在一个pod当中运行一个容器是最常用的方式。在一个pod当中同时运行多个容器&#xff0c;在一个pod当中…

阿里云服务器ECS入门与基础运维

一、云服务器简介 1、服务器&#xff1a; (1) 概念&#xff1a; 服务器本身就是一种电脑&#xff0c;同样具备CPU、内存、硬盘、网卡、电源等硬件。 互联网对外提供网站、游戏、在线会议、网盘等服务&#xff0c;都需要将这些互联网服务部署到服务器中。 (2) 特点&#xf…

通过盲对抗性扰动实时击败基于DNN的流量分析系统

文章信息 论文题目&#xff1a;Defeating DNN-Based Traffic Analysis Systems in Real-Time With Blind Adversarial Perturbations 期刊&#xff08;会议&#xff09;&#xff1a;30th USENIX Security Symposium 时间&#xff1a;2021 级别&#xff1a;CCF A 文章链接&…

校招社招,认知能力测验,③如何破解语言常识类测试题?

作为认知能力测评中的一个环节&#xff0c;语言常识类&#xff0c;是大概率的出现&#xff0c;不同的用人单位可能略有不同&#xff0c;语言是一切的基础&#xff0c;而常识则意味着我们的知识面的宽度。 语言常识类的测试&#xff0c;如果要说技巧&#xff1f;难说....更多的…

el-table 展开行表格,展开的内容高度可以变化时,导致的固定列错位的问题

问题描述 一个可展开的表格&#xff08;列设置了type“expand”&#xff09;&#xff0c;并且展开后的内容高度可以变化&#xff0c;会导致后面所有行的固定列错位&#xff0c;图如下&#xff0c;展示行中是一个树形表格&#xff0c;默认不展示子级&#xff0c;点击树形表格的…

面试算法102:加减的目标值

题目 给定一个非空的正整数数组和一个目标值S&#xff0c;如果为每个数字添加“”或“-”运算符&#xff0c;请计算有多少种方法可以使这些整数的计算结果为S。例如&#xff0c;如果输入数组[2&#xff0c;2&#xff0c;2]并且S等于2&#xff0c;有3种添加“”或“-”的方法使…

TS 36.211 V12.0.0-下行(8)-调制和上变频

本文的内容主要涉及TS 36.211&#xff0c;版本是C00&#xff0c;也就是V12.0.0。

[Kubernetes]5. k8s集群StatefulSet详解,以及数据持久化(SC PV PVC)

前面通过deployment结合service来部署无状态的应用,下面来讲解通过satefulSet结合service来部署有状态的应用 一.StatefulSet详解 1.有状态和无状态区别 无状态: 无状态(stateless)、牲畜(cattle)、无名(nameless)、可丢弃(disposable) 有状态: 有状态(stateful)、宠物(pet)…