重新认识一下 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.hqwc.cn/news/318875.html

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

相关文章

【Java期末】学生成绩管理系统

诚接计算机专业编程任务(C语言、C、Python、Java、HTML、JavaScript、Vue等)10/15R&#xff0c;如有需要请私信我&#xff0c;或者加我的企鹅号&#xff1a;1404293476 本文资源下载地址&#xff1a;https://download.csdn.net/download/weixin_47040861/88697244 —————…

Plantuml之nwdiag网络图语法介绍(二十九)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

GPU的硬件架构

SM: streaming Multiprocessor 流多处理器 sm里面有多个(sp)cuda core 32个线程称为一个warp&#xff0c;一个warp是一个基本执行单元 抽象概念&#xff1a;grid 网格 block 块 thread 线程 块中的线程大小是有讲究的&#xff0c;关乎到资源的调度&#xff0c;一般是128&#x…

[Ray Tracing: The Rest of Your Life] 笔记

前言 开年第一篇博客~ 整理了三四个小时才整理完orz。 这一部分是光线追踪三部曲的最后一部&#xff0c;主要介绍了蒙特卡洛积分、重要性采样等内容。场景上没有什么大的改变&#xff0c;基本上就是在Cornell Box中渲染的&#xff0c;本篇主要在加速收敛&#xff0c;提升渲染效…

60.Go反射库reflect

文章目录 一、简介二、前置总结三、接口四、反射基础五、反射用法1、透视数据组成2、调用函数或方法3、设置值4、StructTag 六、实战案例 一、简介 反射是一种机制&#xff0c;在编译时不知道具体类型的情况下&#xff0c;可以透视结构的组成、更新值。使用反射&#xff0c;可…

目标检测-One Stage-RetinaNet

文章目录 前言一、RetinaNet的网络结构和流程二、RetinaNet的创新点Balanced Cross EntropyFocal Loss 总结 前言 根据前文目标检测-One Stage-YOLOv2可以看出YOLOv2的速度和精度都有相当程度的提升&#xff0c;但是One Stage目标检测模型仍存在一个很大的问题&#xff1a; 前…

【REST2SQL】03 GO读取JSON文件

REST2SQL需要一些配置信息&#xff0c;用JSON文件保存&#xff0c;比如config.json 1 创建config.json配置文件 {"hostPort":"localhost:5217","connString":"oracle://blma:5217127.0.0.1:1521/CQYH","_oracle":"ora…

【JUC】Synchronized及JVM底层原理

Synchronized使用方式 Synchronized有三种应用方式 作用于实例方法&#xff0c;当前示实例加锁进入同步代码前要获得当前实例的锁&#xff0c;即synchronized普通同步方法&#xff0c;调用指令将会检查方法的ACC_SYNCHRONIZED访问标志是否被设置。 如果设置了&#xff0c;执行…

pytest-yaml 测试平台-4.生成allure报告,报告反馈企业微信、钉钉、飞书通知

前言 定时任务执行完成后生成可视化allure报告&#xff0c;并把结果发到企业微信&#xff0c;钉钉&#xff0c;飞书通知群里。 生成allure报告 添加定时任务 执行完成后生成allure报告 查看报告详情 报告会显示详细的request 和 response 详细信息 也可以查看log日志 …

Navicat for Mysql怎么执行创建表的脚本

Navicat for Mysql怎么执行创建表的脚本 Navicat 怎么执行sql文件 Navicat 执行创建表语句 Navicat 执行sql语句 Navicat 怎么创建表语句 1、打开Navicat数据库管理工具&#xff1b; 2、点击菜单栏上的“工具”&#xff0c;选择“命令列界面”&#xff1b; 打开了命令列界面…

智能分析网关V4智慧港口码头可视化视频智能监管方案

一、需求背景 近年来&#xff0c;水利港口码头正在进行智能化建设&#xff0c;现场管理已经是重中之重。港口作为货物、集装箱堆放及中转机构&#xff0c;具有昼夜不歇、天气多变、环境恶劣等特性&#xff0c;安全保卫工作显得更加重要。港口码头的巡检现场如何高效、快捷地对…

学习Vue 01 欢迎来到Vue的世界

学习Vue 01 欢迎来到Vue的世界 概述 Initially released in 2014, Vue.js has experienced rapid adoption, especially in 2018. Vue is a popular framework within the developer community, thanks to its ease of use and flexibility. If you are looking for a great …