Heim  >  Artikel  >  Web-Frontend  >  Kommunikation zwischen Komponenten, die Sie jeden Tag in Vue.js lernen müssen

Kommunikation zwischen Komponenten, die Sie jeden Tag in Vue.js lernen müssen

高洛峰
高洛峰Original
2017-01-03 17:26:191176Durchsuche

Was sind Komponenten?

Komponente ist eine der leistungsstärksten Funktionen von Vue.js. Komponenten können HTML-Elemente erweitern und wiederverwendbaren Code kapseln. Auf einer hohen Ebene ist eine Komponente ein benutzerdefiniertes Element, dem der Compiler von Vue.js spezielle Funktionen hinzufügt. Teilweise können Komponenten auch in Form nativer HTML-Elemente vorliegen, erweitert um das Attribut is.

Komponente verwenden

Registrieren

Wie bereits erwähnt, können wir Vue.extend() verwenden, um einen Komponentenkonstruktor zu erstellen:

var MyComponent = Vue.extend({
 // 选项...
})

Um diesen Konstruktor als Komponente zu verwenden, müssen Sie „Vue.component(tag, constructionor)“ verwenden. **Registrierung**:

// 全局注册组件,tag 为 my-component
Vue.component('my-component', MyComponent)

a619d07b01ad263fab71d64125f6401dFür benutzerdefinierte Tag-Namen erzwingt Vue.js keine W3C-Regeln (Kleinschreibung und Bindestrich), obwohl es besser ist, diese Regel zu befolgen.

Nachdem die Komponente registriert wurde, kann sie im Modul der übergeordneten Instanz als benutzerdefiniertes Element b98f2d1b8b5d79f8c1b053de334aa7b5 verwendet werden. Stellen Sie sicher, dass Sie die Komponente registrieren, bevor Sie die Root-Instanz initialisieren:

<div id="example">
 <my-component></my-component>
</div>
 
// 定义
var MyComponent = Vue.extend({
 template: &#39;<div>A custom component!</div>&#39;
})
 
// 注册
Vue.component(&#39;my-component&#39;, MyComponent)
 
// 创建根实例
new Vue({
 el: &#39;#example&#39;
})

wird wie folgt gerendert:

<div id="example">
 <div>A custom component!</div>
</div>

Beachten Sie, dass die Vorlage der Komponente das benutzerdefinierte Element ersetzt, das nur als Montagepunkt dient. Mithilfe der Instanzoption „replace“ können Sie entscheiden, ob eine Ersetzung durchgeführt werden soll.

Lokale Registrierung

Es ist nicht erforderlich, jede Komponente global zu registrieren. Sie können die Komponente nur in anderen Komponenten verwenden lassen, indem Sie sie mit der Instanzoption Komponenten registrieren:

var Child = Vue.extend({ /* ... */ })
 
var Parent = Vue.extend({
 template: &#39;...&#39;,
 components: {
 // <my-component> 只能用在父组件模板内
 &#39;my-component&#39;: Child
 }
})

Diese Kapselung eignet sich auch für andere Ressourcen, z B. Anweisungen, Filter und Übergänge.

Syntaktischer Registrierungszucker

Um Ereignisse zu vereinfachen, können Sie das Optionsobjekt anstelle des Konstruktors direkt an Vue.component() und Komponentenoptionen übergeben. Vue.js ruft hinter den Kulissen automatisch Vue.extend() auf:

// 在一个步骤中扩展与注册
Vue.component(&#39;my-component&#39;, {
 template: &#39;<div>A custom component!</div>&#39;
})
 
// 局部注册也可以这么做
var Parent = Vue.extend({
 components: {
 &#39;my-component&#39;: {
  template: &#39;<div>A custom component!</div>&#39;
 }
 }
})

Problem mit Komponentenoptionen

Die meisten Optionen des Vue-Konstruktors kann auch in Vue.extend() verwendet werden, es gibt jedoch zwei Sonderfälle: data und el. Stellen Sie sich vor, wir würden einfach ein Objekt als Datenoption an Vue.extend() übergeben: Instanzen teilen sich dasselbe „Daten“-Objekt! Das ist im Grunde nicht das, was wir wollen, also sollten wir eine Funktion als „Daten“-Option verwenden und diese Funktion ein neues Objekt zurückgeben lassen:

var data = { a: 1 }
var MyComponent = Vue.extend({
 data: data
})

Identisch mit Allerdings muss die Option „el“ auch eine Funktion sein, wenn sie in „Vue.extend()“ verwendet wird.

var MyComponent = Vue.extend({
 data: function () {
 return { a: 1 }
 }
})

Template-Parsing

Die Vorlage von Vue ist eine DOM-Vorlage. Verwenden Sie den nativen Parser des Browsers, anstatt selbst einen zu implementieren. DOM-Vorlagen haben einige Vorteile gegenüber String-Vorlagen, haben aber auch das Problem, dass es sich um ein gültiges HTML-Fragment handeln muss. Für einige HTML-Elemente gelten Einschränkungen hinsichtlich der Elemente, die darin platziert werden können. Allgemeine Einschränkungen:

•a darf keine anderen interaktiven Elemente (z. B. Schaltflächen, Links) enthalten.

•ul und ol können nur direkt li enthalten.
•select kann nur option und optgroup enthalten.

•table only Can direkt thead, tbody, tfoot, tr, caption, col, colgroup enthalten

•tr kann nur th und td direkt enthalten


In der Praxis führen diese Einschränkungen zu unerwarteten Ergebnissen. Obwohl es in einfachen Fällen funktionieren kann, können Sie sich nicht auf das Ergebnis der Erweiterung einer benutzerdefinierten Komponente verlassen, bevor der Browser sie validiert. Beispielsweise ist 750d7c37f87c44b67b1e945084b6bc455a07473c87748fb1bf73f23d45547ab8...4afa15d3069109ac30911f04c56f3338c3b6035d40e49dd3cf5dfe627a1d2a00 keine gültige Vorlage, selbst wenn die my-select-Komponente schließlich zu 221f08282418e2996498697df914ce4e erweitert wird. .7f311452790780533cf0d39616b917c7, d477f9ce7bf77f53fbcf36bec1b69b7a, ec872302d9f7ec49547f9998f4be2186) nicht innerhalb von UL-, Select-, Table- usw. Elementen verwendet werden können liegen innerhalb eingeschränkter Tags. Benutzerdefinierte Tags, die in diesen Elementen platziert werden, werden aus dem Element herausgehoben und falsch gerendert.

Für benutzerdefinierte Elemente sollte das is-Attribut verwendet werden:

„kann nicht innerhalb verwendet werden“, sollten Sie verwenden ``, `

` kann mehrere `` haben:
<table>
 <tr is="my-component"></tr>
</table>


Requisiten

<table>
 <tbody v-for="item in items">
 <tr>Even row</tr>
 <tr>Odd row</tr>
 </tbody>
</table>
Verwenden Sie Props, um Daten zu übergeben

Der Umfang der Komponenteninstanzen ist isoliert. Dies bedeutet, dass die Daten der übergeordneten Komponente nicht direkt in der Vorlage der untergeordneten Komponente referenziert werden können und sollten. Sie können Requisiten verwenden, um Daten an untergeordnete Komponenten zu übergeben.

„prop“ ist ein Feld mit Komponentendaten, die voraussichtlich von der übergeordneten Komponente weitergegeben werden. Untergeordnete Komponenten müssen props explizit mit der props-Option deklarieren:

und ihr dann eine normale Zeichenfolge übergeben:

758cb258350e09eaf2270541ea111f507d4dd9c7239aac360e401efe89cbb393

字面量语法 vs. 动态语法

初学者常犯的一个错误是使用字面量语法传递数值:

f0c719b41b2444c4dcad2b080dcdc8ea
4b3995833ef6b5c3dd766ff223ff2442f939a29b40f7380e5948c73965a66a8e
因为它是一个字面 prop,它的值以字符串 `”1”` 而不是以实际的数字传下去。如果想传递一个实际的 JavaScript 数字,需要使用动态语法,从而让它的值被当作 JavaScript 表达式计算:
 9f2d9e4b4b7c979b3472073d04508f03
4be8778d271aa63d943a0a34a5a1cce6f939a29b40f7380e5948c73965a66a8e

Prop 绑定类型

prop 默认是单向绑定:当父组件的属性变化时,将传导给子组件,但是反过来不会。这是为了防止子组件无意修改了父组件的状态——这会让应用的数据流难以理解。不过,也可以使用 .sync 或 .once 绑定修饰符显式地强制双向或单次绑定:

比较语法:

<!-- 默认为单向绑定 -->
<child :msg="parentMsg"></child>
 
<!-- 双向绑定 -->
<child :msg.sync="parentMsg"></child>
 
<!-- 单次绑定 -->
<child :msg.once="parentMsg"></child>

   

双向绑定会把子组件的 msg 属性同步回父组件的 parentMsg 属性。单次绑定在建立之后不会同步之后的变化。

注意如果 prop 是一个对象或数组,是按引用传递。在子组件内修改它会影响父组件的状态,不管是使用哪种绑定类型。

Prop 验证

组件可以为 props 指定验证要求。当组件给其他人使用时这很有用,因为这些验证要求构成了组件的 API,确保其他人正确地使用组件。此时 props 的值是一个对象,包含验证要求:

Vue.component(&#39;example&#39;, {
 props: {
 // 基础类型检测 (`null` 意思是任何类型都可以)
 propA: Number,
 // 多种类型 (1.0.21+)
 propM: [String, Number],
 // 必需且是字符串
 propB: {
  type: String,
  required: true
 },
 // 数字,有默认值
 propC: {
  type: Number,
  default: 100
 },
 // 对象/数组的默认值应当由一个函数返回
 propD: {
  type: Object,
  default: function () {
  return { msg: &#39;hello&#39; }
  }
 },
 // 指定这个 prop 为双向绑定
 // 如果绑定类型不对将抛出一条警告
 propE: {
  twoWay: true
 },
 // 自定义验证函数
 propF: {
  validator: function (value) {
  return value > 10
  }
 },
 // 转换函数(1.0.12 新增)
 // 在设置值之前转换值
 propG: {
  coerce: function (val) {
  return val + &#39;&#39; // 将值转换为字符串
  }
 },
 propH: {
  coerce: function (val) {
  return JSON.parse(val) // 将 JSON 字符串转换为对象
  }
 }
 }
})

   

type 可以是下面原生构造器:
 •String
 •Number
 •Boolean
 •Function
 •Object
 •Array 

type 也可以是一个自定义构造器,使用 instanceof 检测。

当 prop 验证失败了,Vue 将拒绝在子组件上设置此值,如果使用的是开发版本会抛出一条警告。

父子组件通信

父链

子组件可以用 this.$parent 访问它的父组件。根实例的后代可以用 this.$root 访问它。父组件有一个数组 this.$children,包含它所有的子元素。

尽管可以访问父链上任意的实例,不过子组件应当避免直接依赖父组件的数据,尽量显式地使用 props 传递数据。另外,在子组件中修改父组件的状态是非常糟糕的做法,因为:
 1.这让父组件与子组件紧密地耦合;

 2.只看父组件,很难理解父组件的状态。因为它可能被任意子组件修改!理想情况下,只有组件自己能修改它的状态。

自定义事件

Vue 实例实现了一个自定义事件接口,用于在组件树中通信。这个事件系统独立于原生 DOM 事件,用法也不同。

每个 Vue 实例都是一个事件触发器:
 •使用 $on() 监听事件;

 •使用 $emit() 在它上面触发事件;

 •使用 $dispatch() 派发事件,事件沿着父链冒泡;

 •使用 $broadcast() 广播事件,事件向下传导给所有的后代。

不同于 DOM 事件,Vue 事件在冒泡过程中第一次触发回调之后自动停止冒泡,除非回调明确返回 true。

简单例子:

<!-- 子组件模板 -->
<template id="child-template">
 <input v-model="msg">
 <button v-on:click="notify">Dispatch Event</button>
</template>
 
<!-- 父组件模板 -->
<div id="events-example">
 <p>Messages: {{ messages | json }}</p>
 <child></child>
</div>
 
// 注册子组件
// 将当前消息派发出去
Vue.component(&#39;child&#39;, {
 template: &#39;#child-template&#39;,
 data: function () {
 return { msg: &#39;hello&#39; }
 },
 methods: {
 notify: function () {
  if (this.msg.trim()) {
  this.$dispatch(&#39;child-msg&#39;, this.msg)
  this.msg = &#39;&#39;
  }
 }
 }
})
 
// 初始化父组件
// 将收到消息时将事件推入一个数组
var parent = new Vue({
 el: &#39;#events-example&#39;,
 data: {
 messages: []
 },
 // 在创建实例时 `events` 选项简单地调用 `$on`
 events: {
 &#39;child-msg&#39;: function (msg) {
  // 事件回调内的 `this` 自动绑定到注册它的实例上
  this.messages.push(msg)
 }
 }
})

   

使用 v-on 绑定自定义事件

上例非常好,不过从父组件的代码中不能直观的看到 "child-msg" 事件来自哪里。如果我们在模板中子组件用到的地方声明事件处理器会更好。为此子组件可以用 v-on 监听自定义事件:

4084e2349312ebcd04e4de37381def6c7d4dd9c7239aac360e401efe89cbb393
这样就很清楚了:当子组件触发了 `”child-msg”` 事件,父组件的 `handleIt` 方法将被调用。所有影响父组件状态的代码放到父组件的 `handleIt` 方法中;子组件只关注触发事件。
 子组件索引

尽管有 props 和 events,但是有时仍然需要在 JavaScript 中直接访问子组件。为此可以使用 v-ref 为子组件指定一个索引 ID。例如:

<div id="parent">
 <user-profile v-ref:profile></user-profile>
</div>
 
var parent = new Vue({ el: &#39;#parent&#39; })
// 访问子组件
var child = parent.$refs.profile

   

v-ref 和 v-for 一起用时,ref 是一个数组或对象,包含相应的子组件。

使用 Slot 分发内容

在使用组件时,常常要像这样组合它们:

<app>
 <app-header></app-header>
 <app-footer></app-footer>
</app>

   

注意两点:
 1.7ab1d477d2ef4cffc4b2f0ef9c222635 组件不知道它的挂载点会有什么内容,挂载点的内容是由 7ab1d477d2ef4cffc4b2f0ef9c222635 的父组件决定的。

 2.7ab1d477d2ef4cffc4b2f0ef9c222635 组件很可能有它自己的模板。

为了让组件可以组合,我们需要一种方式来混合父组件的内容与子组件自己的模板。这个处理称为内容分发(或 “transclusion”,如果你熟悉 Angular)。Vue.js 实现了一个内容分发 API,参照了当前 Web 组件规范草稿,使用特殊的 58cb293b8600657fad49ec2c8d37b472 元素作为原始内容的插槽。

编译作用域

在深入内容分发 API 之前,我们先明确内容的编译作用域。假定模板为:

6520631531c208a38051e59cee36c278
  {{ msg }}
53b801b01e70268453ed301cb998e90c

msg 应该绑定到父组件的数据,还是绑定到子组件的数据?答案是父组件。组件作用域简单地说是:

父组件模板的内容在父组件作用域内编译;子组件模板的内容在子组件作用域内编译
一个常见错误是试图在父组件模板内将一个指令绑定到子组件的属性/方法:

28f4e97653235e70fa02b96a2a29310c
68cc734b6c13c190f565c55929cd8b5e53b801b01e70268453ed301cb998e90c

假定 someChildProperty 是子组件的属性,上例不会如预期那样工作。父组件模板不应该知道子组件的状态。

如果要绑定子组件内的指令到一个组件的根节点,应当在它的模板内这么做:

Vue.component(&#39;child-component&#39;, {
 // 有效,因为是在正确的作用域内
 template: &#39;<div v-show="someChildProperty">Child</div>&#39;,
 data: function () {
 return {
  someChildProperty: true
 }
 }
})

   

类似地,分发内容是在父组件作用域内编译。 

单个 Slot

父组件的内容将被抛弃,除非子组件模板包含 58cb293b8600657fad49ec2c8d37b472。如果子组件模板只有一个没有特性的 slot,父组件的整个内容将插到 slot 所在的地方并替换它。

58cb293b8600657fad49ec2c8d37b472 标签的内容视为回退内容。回退内容在子组件的作用域内编译,当宿主元素为空并且没有内容供插入时显示这个回退内容。

假定 my-component 组件有下面模板:

<div>
 <h1>This is my component!</h1>
 <slot>
 如果没有分发内容则显示我。
 </slot>
</div>

   

父组件模板: 
b98f2d1b8b5d79f8c1b053de334aa7b5
  e388a4556c0f65e1904146cc1a846beeThis is some original content94b3e26ee717c64999d7867364b1b4a3
  e388a4556c0f65e1904146cc1a846beeThis is some more original content94b3e26ee717c64999d7867364b1b4a3
83153a5025b2246e72401680bb5dd683
渲染结果: 

<div>
 <h1>This is my component!</h1>
 <p>This is some original content</p>
 <p>This is some more original content</p>
</div>

   

具名 Slot

58cb293b8600657fad49ec2c8d37b472 元素可以用一个特殊特性 name 配置如何分发内容。多个 slot 可以有不同的名字。具名 slot 将匹配内容片段中有对应 slot 特性的元素。

仍然可以有一个匿名 slot,它是默认 slot,作为找不到匹配的内容片段的回退插槽。如果没有默认的 slot,这些找不到匹配的内容片段将被抛弃。

例如,假定我们有一个 multi-insertion 组件,它的模板为:

<div>
 <slot name="one"></slot>
 <slot></slot>
 <slot name="two"></slot>
</div>

   

父组件模板: 

<multi-insertion>
 <p slot="one">One</p>
 <p slot="two">Two</p>
 <p>Default A</p>
</multi-insertion>

   

渲染结果为: 

<div>
 <p slot="one">One</p>
 <p>Default A</p>
 <p slot="two">Two</p>
</div>

   

在组合组件时,内容分发 API 是非常有用的机制。 

动态组件

多个组件可以使用同一个挂载点,然后动态地在它们之间切换。使用保留的 8c05085041e56efcb85463966dd1cb7e 元素,动态地绑定到它的 is 特性:

new Vue({
 el: &#39;body&#39;,
 data: {
 currentView: &#39;home&#39;
 },
 components: {
 home: { /* ... */ },
 posts: { /* ... */ },
 archive: { /* ... */ }
 }
})
 
<component :is="currentView">
 <!-- 组件在 vm.currentview 变化时改变 -->
</component>

   

keep-alive

如果把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染。为此可以添加一个 keep-alive 指令参数:

39a981128a40da37853cce84bffb2ba2
  b2b0822175891cddec63f9cdd3f18ba9
2724ec0ed5bf474563ac7616c8d7a3cd

activate 钩子

在切换组件时,切入组件在切入前可能需要进行一些异步操作。为了控制组件切换时长,给切入组件添加 activate 钩子:

Vue.component(&#39;activate-example&#39;, {
 activate: function (done) {
 var self = this
 loadDataAsync(function (data) {
  self.someData = data
  done()
 })
 }
})

   

注意 `activate` 钩子只作用于动态组件切换或静态组件初始化渲染的过程中,不作用于使用实例方法手工插入的过程中。 
transition-mode

transition-mode 特性用于指定两个动态组件之间如何过渡。

在默认情况下,进入与离开平滑地过渡。这个特性可以指定另外两种模式:
 •in-out:新组件先过渡进入,等它的过渡完成之后当前组件过渡出去。

 •out-in:当前组件先过渡出去,等它的过渡完成之后新组件过渡进入。

 示例:

<!-- 先淡出再淡入 -->
<component
 :is="view"
 transition="fade"
 transition-mode="out-in">
</component>
 
.fade-transition {
 transition: opacity .3s ease;
}
.fade-enter, .fade-leave {
 opacity: 0;
}

   

杂项

组件和 v-for

自定义组件可以像普通元素一样直接使用 v-for:

a9a1e7d04477c0e832f43883fce1bc2c83153a5025b2246e72401680bb5dd683

但是,不能传递数据给组件,因为组件的作用域是孤立的。为了传递数据给组件,应当使用 props:

35c87bd607c1909a6b5ef52c795f1ed7
83153a5025b2246e72401680bb5dd683

不自动把 item 注入组件的原因是这会导致组件跟当前 v-for 紧密耦合。显式声明数据来自哪里可以让组件复用在其它地方。

编写可复用组件

在编写组件时,记住是否要复用组件有好处。一次性组件跟其它组件紧密耦合没关系,但是可复用组件应当定义一个清晰的公开接口。

Vue.js 组件 API 来自三部分——prop,事件和 slot:
 •prop 允许外部环境传递数据给组件;

 •事件 允许组件触发外部环境的 action;

 •slot 允许外部环境插入内容到组件的视图结构内。

 使用 v-bind 和 v-on 的简写语法,模板的缩进清楚且简洁:

9f5a0aa3d537eedfa843e3c0a63d4317
  cb4e25d677c71b611af30b24ac580ce8
  2660389d9a6836ad2cf20a139757c02e
  17b047d0462086858c7d0a0ba5a2ece2Hello!94b3e26ee717c64999d7867364b1b4a3
83153a5025b2246e72401680bb5dd683

异步组件

在大型应用中,我们可能需要将应用拆分为小块,只在需要时才从服务器下载。为了让事情更简单,Vue.js 允许将组件定义为一个工厂函数,动态地解析组件的定义。Vue.js 只在组件需要渲染时触发工厂函数,并且把结果缓存起来,用于后面的再次渲染。例如:

Vue.component(&#39;async-example&#39;, function (resolve, reject) {
 setTimeout(function () {
 resolve({
  template: &#39;<div>I am async!</div>&#39;
 })
 }, 1000)
})

   

工厂函数接收一个 resolve 回调,在收到从服务器下载的组件定义时调用。也可以调用 reject(reason) 指示加载失败。这里 setTimeout 只是为了演示。怎么获取组件完全由你决定。推荐配合使用 Webpack 的代码分割功能:

Vue.component(&#39;async-webpack-example&#39;, function (resolve) {
 // 这个特殊的 require 语法告诉 webpack
 // 自动将编译后的代码分割成不同的块,
 // 这些块将通过 ajax 请求自动下载。
 require([&#39;./my-async-component&#39;], resolve)
})

   

资源命名约定

一些资源,如组件和指令,是以 HTML 特性或 HTML 自定义元素的形式出现在模板中。因为 HTML 特性的名字和标签的名字不区分大小写,所以资源的名字通常需使用 kebab-case 而不是 camelCase 的形式,这不大方便。

Vue.js 支持资源的名字使用 camelCase 或 PascalCase 的形式,并且在模板中自动将它们转为 kebab-case(类似于 prop 的命名约定):

// 在组件定义中
components: {
 // 使用 camelCase 形式注册
 myComponent: { /*... */ }
}
 
<!-- 在模板中使用 kebab-case 形式 -->
<my-component></my-component>
 
ES6 对象字面量缩写 也没问题:
 
// PascalCase
import TextBox from &#39;./components/text-box&#39;;
import DropdownMenu from &#39;./components/dropdown-menu&#39;;
 
export default {
 components: {
 // 在模板中写作 <text-box> 和 <dropdown-menu>
 TextBox,
 DropdownMenu
 }
}

   

递归组件

组件在它的模板内可以递归地调用自己,不过,只有当它有 name 选项时才可以:

var StackOverflow = Vue.extend({
 name: &#39;stack-overflow&#39;,
 template:
 &#39;<div>&#39; +
  // 递归地调用它自己
  &#39;<stack-overflow></stack-overflow>&#39; +
 &#39;</div>&#39;
})

   

上面组件会导致一个错误 “max stack size exceeded”,所以要确保递归调用有终止条件。当使用 Vue.component() 全局注册一个组件时,组件 ID 自动设置为组件的 name 选项。

片断实例

在使用 template 选项时,模板的内容将替换实例的挂载元素。因而推荐模板的顶级元素始终是单个元素。

不这么写模板:

dc6dce4a544fdca2df29d5ac0ea9906broot node 116b28748ea4df4d9c2150843fecfba68
dc6dce4a544fdca2df29d5ac0ea9906broot node 216b28748ea4df4d9c2150843fecfba68

推荐这么写:

dc6dce4a544fdca2df29d5ac0ea9906b
  I have a single root node!
  dc6dce4a544fdca2df29d5ac0ea9906bnode 116b28748ea4df4d9c2150843fecfba68
  dc6dce4a544fdca2df29d5ac0ea9906bnode 216b28748ea4df4d9c2150843fecfba68
16b28748ea4df4d9c2150843fecfba68

Die folgenden Situationen verwandeln die Instanz in eine Fragmentinstanz:
1. Die Vorlage enthält mehrere Elemente der obersten Ebene.
2. Die Vorlage enthält nur normalen Text.
3. Die Vorlage enthält nur andere Komponenten (andere Komponenten können eine Fragmentinstanz sein).
4. Die Vorlage enthält nur eine Elementanweisung, z. B. ec872302d9f7ec49547f9998f4be2186 oder vue-routers 975b587bf85a482ea10b0a28848e78a4.
5. Der Stammknoten der Vorlage verfügt über eine Flusskontrollanweisung, z. B. v-if oder v-for.

In diesen Fällen, in denen Instanzen eine unbekannte Anzahl von Elementen der obersten Ebene haben, werden ihre DOM-Inhalte als Fragmente behandelt. Fragmentinstanzen rendern Inhalte weiterhin korrekt. Es verfügt jedoch nicht über einen Wurzelknoten und sein $el zeigt auf einen Ankerknoten, bei dem es sich um einen leeren Textknoten handelt (ein Kommentarknoten im Entwicklungsmodus).

Aber was noch wichtiger ist: Nicht-Flusskontrollanweisungen, Nicht-Prop-Attribute und Übergänge auf Komponentenelementen werden ignoriert, da kein Stammelement zum Binden vorhanden ist:

2a10098375e4881cf8e1e4f399c63c43
f80d695f4e6937093b39b7ae3e2bbf584cddb7d8848582d36dd9716ae6c29b0b

f9b899e80630412605ae6ba40494c4b44cddb7d8848582d36dd9716ae6c29b0b

Natürlich haben Fragmentinstanzen ihre Verwendung, aber normalerweise ist es besser, der Komponente einen Wurzelknoten zu geben. Dadurch wird sichergestellt, dass Anweisungen und Eigenschaften von Komponentenelementen korrekt übersetzt werden und die Leistung etwas besser ist.


Inline-Vorlage

Wenn eine untergeordnete Komponente das Attribut „inline-template“ hat, behandelt die Komponente ihren Inhalt als ihre Vorlage und nicht als verteilten Inhalt. Dadurch werden Vorlagen flexibler.

8283dd6e937edd85c001c6ec3509d95d

e388a4556c0f65e1904146cc1a846beeDiese werden als eigene Vorlage der Komponente kompiliert94b3e26ee717c64999d7867364b1b4a3

e388a4556c0f65e1904146cc1a846beeNicht der Transklusionsinhalt der übergeordneten Komponente.83153a5025b2246e72401680bb5dd683


Aber Inline-Template macht den Umfang der Vorlage schwer zu verstehen und die Ergebnisse der Vorlagenkompilierung können nicht zwischengespeichert werden. Die beste Vorgehensweise besteht darin, die Vorlage innerhalb der Komponente mithilfe der Vorlagenoption zu definieren.

Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass er zum Lernen aller beiträgt. Ich hoffe auch, dass jeder die PHP-Chinesisch-Website abonniert.

Weitere Artikel zur Kommunikation zwischen Komponenten, die jeden Tag in Vue.js gelernt werden müssen, finden Sie auf der chinesischen PHP-Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn