重新认识一下 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-line
    throw 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 注释的库一起使用时使用

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Postman 安装及使用

文章目录 1. 安装 Postman1&#xff09;下载2&#xff09;安装3&#xff09;注册用户4&#xff09;登陆完成 2. 创建和发送请求1&#xff09;发送一个 GET 请求2&#xff09;发送一个 POST 请求 3. 查看响应4. 使用环境变量和变量5. 高级功能和测试6. 导出和分享请求总结 Postm…

VirtualBox + Redhat7.6 +Oracle19C 数据库安装

软件工具&#xff1a; 虚拟化工具&#xff1a;VirtualBox-6.1.26-145957-Win.exe操作系统镜像&#xff1a;rhel-server-7.6-x86_64-dvd.iso远程连接工具&#xff1a;XmanagerPowerSuite-7.0.0004r.exe、SecureCRT 8.5.3数据库版本镜像&#xff1a;LINUX.X64_193000_grid_home.…

网络安全B模块(笔记详解)- 弱口令渗透测试

nmap扫描渗透测试 1.通过BT5对服务器场景Linux进行TCP同步扫描 (使用工具Nmap,使用参数n,使用必须要使用的参数),并将该操作使用命令中必须要使用的参数作为Flag提交; Flag:sS 2.通过BT5对服务器场景Linux进行TCP同步扫描 (使用工具Nmap,使用参数n,使用必须要使用的参数…

【小沐学NLP】Python实现TF-IDF算法(nltk、sklearn、jieba)

文章目录 1、简介1.1 TF1.2 IDF1.3 TF-IDF2.1 TF-IDF(sklearn)2.2 TF-IDF(nltk)2.3 TF-IDF(Jieba)2.4 TF-IDF(python) 结语 1、简介 TF-IDF&#xff08;term frequency–inverse document frequency&#xff09;是一种用于信息检索与数据挖掘的常用加权技术。TF是词频(Term Fr…

从vue小白到高手,从一个内容管理网站开始实战开发第三天,使用Element UI构建页面-登录(一)

上次我们介绍了如何安装Element UI库,这次我们使用Element UI中的组件开始开发我们的页面。 开发之前要先在项目中建立好几个目录,方便我们下面的开发。 一、在项目中创建页面管理目录 1、pages目录(文件夹) 首先在src文件夹下创建一个名为pages的文件夹,该文件夹用来统…

Unity3D UGUI图集打包与动态使用(TexturePacker)

制作图集的好处&#xff1a; 众所周知CPU是用来处理游戏的逻辑运算的&#xff0c;而GPU是用来处理游戏中图像的。在GPU中&#xff0c;我们要绘制一个图像需要提交图片&#xff08;纹理&#xff09;到显存&#xff0c;然后再进行绘制&#xff08;在这个过程中会产生一次DrawCall…

【Emgu.CV教程】第22篇 、色彩处理之ApplyColorMap()伪色彩应用

这篇文章讲的内容比较轻松&#xff0c;技术含量比较低。从我个人的角度讲&#xff0c;ApplyColorMap()函数实现了类似PhotoShop的一些酷炫效果&#xff0c;既把原始彩色图转换为21种风格各异的彩色图像&#xff0c;比如秋天风格、热力图风格等等&#xff0c;但是&#xff0c;在…

修改多选框el-checkbox样式, 大小,背景色

修改多选框el-checkbox样式, 大小,背景色 /* 背景透明 */ .el-checkbox__inner {background: transparent;border: 1px solid #00ffe5; } /* 选中样式 */ .el-checkbox__input.is-checked .el-checkbox__inner, .el-checkbox__input.is-indeterminate .el-checkbox__inner {b…

redis的搭建及应用(七)-redis的限流插件redis-cell

Redis限流插件-redis-cell redis-cell 是一个用rust语言编写的基于令牌桶算法的的限流模块&#xff0c;提供原子性的限流功能&#xff0c;并允许突发流量&#xff0c;可以很方便的应用于分布式环境中。 下载redis-cell插件 访问Releases brandur/redis-cell (github.com) 上传…

leetcode:1464. 数组中两元素的最大乘积(python3解法)

难度&#xff1a;简单 给你一个整数数组 nums&#xff0c;请你选择数组的两个不同下标 i 和 j&#xff0c;使 (nums[i]-1)*(nums[j]-1) 取得最大值。 请你计算并返回该式的最大值。 示例 1&#xff1a; 输入&#xff1a;nums [3,4,5,2] 输出&#xff1a;12 解释&#xff1a;如…

CGAL的无限制的Delaunay图

本章描述了构建L∞距离下线段Delaunay图的算法和几何特征。这些特征还包括绘制L∞距离下线段Delaunay图对偶&#xff08;即L∞距离下线段Voronoi图&#xff09;边缘的方法。L∞算法和特征依赖于欧几里得&#xff08;或L2&#xff09;距离下的线段Delaunay图算法和特征。L∞度量…

LeetCode刷题:876. 链表的中间结点

题目&#xff1a; 是否参考题解&#xff1a;否 做题思路&#xff1a;看到题目关于奇偶数的题&#xff0c;首先想到了用计数器把链表遍历一遍&#xff0c;然后将计算出的数据个数count/2的下标作为头结点便可以遍历出来结果 题解思路&#xff1a;在评论区学习到还有两种解题思…

书生-浦路大模型全链路开源体系

2023年&#xff0c;大模型成为热门关键词 论文链接 大模型已经成为发展通用人工智能的重要途经 模型评测过程&#xff1a;从模型到应用 全链条开源开发体系 | 数据&#xff1a; 多模态融合 万卷包含文本、图像和视频等多模态数据&#xff0c;涵盖科技、文学、媒体、教育和法…

【React】class组件生命周期函数的梳理和总结(第一篇)

1. 前言 本篇梳理和总结一下React的生命周期函数&#xff0c;方便使用class组件的同学查阅&#xff0c;先上生命周期图谱。 2. 生命周期函数 生命周期函数说明constructor(props) 功能&#xff1a;如果不需要初始化state或不进行方法绑定&#xff0c;class组件可以不用实现构造…

工业物联网上篇——什么是IIOT?

工业物联网背后的理念是使用工业设施中“哑巴设备”多年来产生的数据。装配线上的智能机器不仅可以更快地捕获和分析数据&#xff0c;且在交流重要信息方面也更快&#xff0c;这有助于更快、更准确地做出业务决策。 信息技术&#xff08;IT&#xff09;和运营技术&#xff08;O…

1.3 力扣二叉树中等题

题目一&#xff1a; 669. 修剪二叉搜索树 给你二叉搜索树的根节点 root &#xff0c;同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树&#xff0c;使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即&#xff0c;如果没有被移除&…

图像清晰度评估指标

图像清晰度评估涉及多个指标&#xff0c;这些指标可用于定量测量图像的清晰度和质量。 以下是一些常见的图像清晰度评估指标&#xff1a; 均方根误差&#xff08;Root Mean Square Error&#xff0c;RMSE&#xff09;&#xff1a; 通过计算原始图像和处理后图像之间的像素差异的…

【计算机视觉】常用图像数据集

图像数据集 模型需要好的数据才能训练出结果&#xff0c;本文总结了机器学习图像方面常用数据集。 MNIST 机器学习入门的标准数据集&#xff08;Hello World!&#xff09;&#xff0c;10个类别&#xff0c;0-9 手写数字。包含了60,000 张 28x28 的二值训练图像&#xff0c;10…

滑动窗口最大值(力扣239题)

单调递减队列&#xff1a; 在解决题目之前&#xff0c;我们先来了解一下单调递减队列&#xff0c;它其实就是在队列的基础上多加了一些限制&#xff0c;如下图&#xff1a; 要求队列中的元素必须按从大到小的顺序排列。 如果向单调递减队列中加入数字 1&#xff0c;可以直接加入…

【Vue2+3入门到实战】(22)VUE3之组合式API - setup、reactive和ref函数、computed、watch、生命周期函数详细讲解

目录 一、组合式API - setup选项1. setup选项的写法和执行时机2. setup中写代码的特点3. <script setup>语法糖 二、组合式API - reactive和ref函数1. reactive2. ref3. reactive 对比 ref 三、组合式API - computed四、组合式API - watch1. 侦听单个数据2. 侦听多个数据…