0


第一节: 全面细致的理解创建vue3应用的 createApp函数

1. createApp 创建应用

1.1. createApp 函数理解

每个 Vue 应用实例都是通过

createApp

函数创建;每次调用函数都会返回一个新的应用对象;

使用方式

import{createApp}from'vue'const app =createApp({// ...options})

通过源码或

vue

官网, 可以知道

createApp

函数的类型如下

functioncreateApp(rootComponent: Component, rootProps?: object): App

通过类型可以看出

createApp

接收两个参数:

  1. 第一个参数为根组件对象(可以是.vue单文件组件, 可以是组件对象), 是必传参数,
  2. 第二个参数为传递给根组件的props, 第二个参数时可选参数
createApp

返回一个

App

类型的应用对象.如果要详细了解

App

类型, 可以查看源码. 我们可以通过在控制台输出的方式, 查看返回的应用对象都具有哪些属性.

1.2. 应用对象

createApp

函数调用完后返回一个应用对象.

示例:

import{createApp}from'vue'const vm =createApp({})
console.log('vm', vm)

控制台输出结果:

img

通过控制台输出可以看到很多熟悉的单词, 比如

component

表示组件,

directive

表示指令, 具体如何使用, 我们娓娓道来

分析完

createApp

函数的返回值, 接下来我们详细研究一下参数

2. createApp API 参数

createApp

函数接受两个参数, 第二个参数是可选地,

第一个参数有两种形式

  1. 直接传入单文件组件, 作为根组件
  2. 使用vue选项对象

2.1. createApp 参数单文件组件

通过

createApp

函数的类型可知,

createApp

至少传一个参数, 参数可以为单文件组件

示例:

根组件代码:

<template><div>这是一个新的根组件</div></template><scriptlang="ts">import{ defineComponent }from"vue";exportdefaultdefineComponent({});</script>

入口函数

main.ts
import{ createApp }from'vue'// 导入单文件组件import App from'./App.vue'// 将单文件组件App作为参数传递给createAPPconst app =createApp(App)

运行结果:

img

2.2. createApp 参数组件选项对象

createApp

的第一个参数除了可以是单文件组件, 也可以是选项对象

vue2

中我们通过

template

选项添加模板渲染内容

vue3

中, 我们也可以使用使用

tempate

选项定义渲染模板

示例:

// 引入完整vue代码, 包括运行时 + 编译器import{ createApp}from'vue/dist/vue.esm-bundler.js'const app =createApp({name:'App',// 使用template 模板template:`
    <h2>你好,中国</h2>
  `,})

运行结果:

img

这里有个需要注意的点, 就是导入

createApp

的模块不是

vue

, 而是

vue/dist/vue.esm-bundler.js

原因在于从

vue

中导入的模块,是运行时

(runtime)

代码, 运行时代码不包括编译器

(compile)

, 没有编译器,就不能将模板编译成渲染函数

所以, 如果你需要在组件对象中使用

template

模板, 一定注意使用完整版

vue

因为

template

模板是需要编译成渲染函数, 通过调用渲染函数, 获取返回的

vnode

进行页面渲染.

所以我们也可以不使用

template

选项, 直接编写渲染函数, 渲染函数需要返回

vnode

.,

vue3

提供了一个

h

函数用于创建

vnode

, 需要配合

setup

选项一起使用

示例: 在

setup

函数中直接返回render渲染函数

import{ createApp,h }from'vue'// createApp, 组件对象中直接返回渲染函数const app =createApp({name:'App',setup(){// 返回render渲染函数return()=>{// 渲染中返回vnode, 通过vue3 提供h api 创建vnodereturnh('h1',null,'hello world')}}})

运行结果:

img

这里使用的

setup

选项, 以及

h

函数都是

vue3

开始提供API, 之后我们会详细分析

这里主要记住两点:

  1. setup选项, 可以理解时一个钩子函数, 跟created相似, 会自动执行, 可以直接返回一个渲染函数
  2. h函数用于创建vnode, 渲染函数需要返回vnode

至此, 我们已经分析完

createApp

函数的第一个参数, 接下来我们分析第二个参数

2.3. createApp 第二个参数为props

createApp

函数第二个参数的作用是给根组件传入

props

数据

props

相信大家已经比较熟了, 就是父组件给子组件传参的方式. 问题在于根组件已经是顶级组件了, 没有父组件传入

props

参数.

此时我们就可以使用

createApp

第二个参数实现向根组件传参

示例:

import{ createApp, h }from'vue'const app =createApp(// 第一个参数: 根组件对象{name:'App',// 获取第二个参数传入的props数据props:{msg:{type: String,default:''}},setup(props){
      console.log('props', props)return()=>h('h1',null, props.msg)}},// 第二个参数: props 对象{msg:'hello world'})

控制台输出的

props

值:

img

一般情况下使用不到第二个参数, 因为正常使用

createApp

时,会使用.

vue

单文件组件作为参数

而根组件通常是页面的布局结构, 不太能使用到数据

到此为止,

createApp

API 的入参就分析完了, 我们前面讲到过,

createApp

会返回应用对象.

接下来我们详细分析一下,

createApp

返回的应用对象

3. 应用对象的属性与方法

前面我们也在控制台输出了

createApp

函数返回的应用对象.应用对象中具有很多属性和方法.

我们看几个常用的方法

示例: 查看app应用属性与方法

import{ createApp }from'vue'import App from'./App.vue'// 根组件// createApp创建app应用实例对象const app =createApp(App)

console.log(app)/*

{
    // 1. 注册全局组件
    component:  ƒ component(name, component)
  config: {...}
  directive: ƒ directive(name, directive)
  mixin: ƒ mixin(mixin)

  // 2. 挂载方法(参数时dom对象或选择器)
  mount: (containerOrSelector) => {…}
  provide: ƒ provide(key, value)
  runWithContext: ƒ runWithContext(fn)

  // 3. 卸载应用
  unmount: ƒ ()  
  use: ƒ use(plugin, ...options)
  version: "3.3.4"
  _component: {name: 'JX-APP', __hmrId: 'e16649ff', __scopeId: 'data-v-e16649ff', __file: 'D:/studey/vue-上课/vue3/vue代码/vue3/vue3-studey/src/App2.vue', setup: ƒ, …}
  _container: div#app
  _context: {app: {…}, config: {…}, mixins: Array(0), components: {…}, directives: {…}, …}
  _instance: {uid: 0, vnode: {…}, type: {…}, parent: null, appContext: {…}, …}
  _props: null
  _uid: 0
}

*/

3.1. app.mount 挂载方法

vue3通过调用应用对象的

mount()

方法挂载应用, 该方法接受一个

"容器"

参数, 可以是一个真实DOM元素, 也可以是一个选择器字符串

参数为真实dom元素

示例:

import{ createApp }from'vue'import App from'./App.vue'// 根组件// createApp创建app应用实例对象const app =createApp(App)// 获取真实的dom节点const dom = document.getElementById('app')// 通过真实dom节点进行挂载
app.mount(dom)

参数为选择器字符串

示例:

// 导入createAppimport{ createApp }from"vue";import App from"./App.vue";// 初始化vue应用const app =createApp(App);// 调用mount方法挂着vue
app.mount("#app");

这个时候不知道大家是否会有一问, 选择器只能用

id

吗? 如

#app

答案是否定的, 也可以使用其他选择器, 比如class 选择

.app

, 只不过

id

具有唯一性

示例:

<divclass="app"></div><scripttype="module"src="/src/main.ts"></script>s
// 导入createAppimport{ createApp }from"vue";import App from"./App.vue";// 初始化vue应用const app =createApp(App);// 调用mount方法挂着vue
app.mount(".app");

我们会发现也是可以运行的, 原因在于

mount

参数如果是选择器,

vue3

会自己获取dom节点

我们不用担心

class

类名,或者标签名有多个的问题, 因为

vue

使用

querySelector

方法通过选择器获取第一个

dom

节点

我们简单看一下

vue3

源码中

mount

方法的实现

源码:

 app.mount =(containerOrSelector: Element | ShadowRoot | string):any=>{// 获取挂载点的真实domconst container =normalizeContainer(containerOrSelector)// ....}functionnormalizeContainer(container: Element | ShadowRoot | string): Element |null{// 判断mount 挂载方法参数是不是字符串if(isString(container)){// 获取dom, 因为使用querySelector 方法获取, 因此返回第一个dom对象const res = document.querySelector(container)// 如果通过mount参数字符串没有获取到挂载点dom对象, 则报错if(__DEV__ &&!res){warn(`Failed to mount app: mount target selector "${container}" returned null.`)}return res
  }// 如果参数时真实dom节点直接返回return container as any
}

3.2. app.unmount 卸载应用

应用对象通过

mount

方法挂载元素, 相对应的,是通过

unmount

方法卸载应用

示例

// 导入createAppimport{ createApp }from"vue";import App from"./App.vue";// 初始化vue应用const app =createApp(App);// 调用mount方法挂着vue
app.mount("#app");// 卸载应用
app.unmount()

3.3. app.component 注册全局组件

app.component

方法是

vue3

提供的用于注册全局组件

  1. 如果component方法传入两个参数, 第一个参数为字符串,用于声明组件名称, 第二个参数为组件对象,
  2. 如果component接受一个参数, 参数为一个名字,则会返回用该名字对应的注册组件 (如果存在的话)。

示例:

注册全局组件

// 导入createAppimport{ createApp }from"vue";import App from"./App.vue";// 初始化vue应用const app =createApp(App);// 注册全局组件
app.component(// 第一个参数为组件名称'jx-hello',// 第二参数为组件对象{name:'JxHello',setup(){return()=>{returnh('div',null,'这是一个全局组件')}}})// 调用mount方法挂着vue
app.mount("#app");

使用全局组件

<template><div><!--   使用全局组件     --><jx-hello></jx-hello></div></template><script  lang="ts">import{ defineComponent,}from'vue';exportdefaultdefineComponent({name:"JX-APP",setup(){return{}}})</script>

到这里,

createApp

API的使用就已经分析完了


本文转载自: https://blog.csdn.net/fjiex/article/details/138659957
版权归原作者 前端付杰 所有, 如有侵权,请联系我们删除。

“第一节: 全面细致的理解创建vue3应用的 createApp函数”的评论:

还没有评论