這篇文章跟大家分享Vue進階技巧,深入理解下Vue中的插槽、內容分發、具名插槽,希望對大家有幫助。
#Vue中元件的資料可以透過props傳遞,或透過事件的方式進行獲取傳遞,但當需要接收模板內容(任意合法的模板內容,程式碼片段、Vue元件)時,就需要使用插槽來實現了。當然也可以透過函數式程式設計間接實現;【相關推薦:vuejs影片教學】
// 父元素传入插槽内容 FancyButton('Click me!') // FancyButton 在自己的模板中渲染插槽内容 function FancyButton(slotContent) { return `<button> ${slotContent} </button>` }
常規的slot可以用於自訂元件的模板,但只是限制於固定的模板,無法自訂內部的具體的某一項,即常規的slot無法實現對組件循環體的每一項進行不同的內容分發,此時可以透過slot-scope進行實現,本質上和slot一樣,不同點在於可以進行參數傳遞
//普通的组件定义
使用slot-scope時,當父元件使用該API,對應的插槽會取代模板中的slot進行展示
在元件中定義多個插槽出口可以相容多個不同需求的相容性,使得多個插槽內容傳入到各自的插槽出口中;當插槽中配置了
name
屬性時,此插槽就稱為具名插槽(named slots),沒有提供name的插槽會隱含命名為「default」
v-slot
可以簡寫為
##,其值對應於插槽中的 name
對應的值;template
節點都被隱式的視為預設插槽的內容,因此可以省略預設插槽的template
節點標籤;<com> <!-- 隐式的默认插槽 --> <!-- <p>A paragraph for the main content.</p> <p>And another one.</p> --> <template> <p>A paragraph for the main content.</p> <p>And another one.</p> </template> <template> <p>Here's some contact info</p> </template> </com>
普通的插槽,是無法取得其他作用域下的資料的,即父元件範本中的表達式只能存取父元件的作用域;子元件範本中的表達式只能存取子元件元件的作用域
但在某些情況下,插槽中的內容想要同時使用父元件和子元件內的數據,可以透過像元件傳遞資料
props那樣,讓子元件在渲染時將一部分資料提供給插槽,這樣在元件外部(父元件)中就可以使用子元件中的資料了-透過
slot的方式
#子元件傳入插槽的props 作為了 v-slot 指令的值,可以在插槽內的表達式中訪問,其中name是Vue刻意保留的attribute,不會作為props進行傳遞
//子组件 <template> <slot></slot> </template>
//父组件 - 使用方 <mycom> {{ shopInfo }} {{ userInfo }} </mycom>
<mycom> <template> {{ shopInfo }} </template> <template> {{ introduction }} </template> <template> {{ userInfo }} </template> </mycom>
<cpm> <!-- 不显示 --> <div>555</div> <!-- 不显示 --> <div> <div>{{scope.name}}</div> </div> <!-- 显示 --> <div> <div>{{scope}}</div> <div>{{scope.name}}</div> <div>{{scope.age}}</div> </div> </cpm>
;但有時會省略這個key值,直接進行傳遞數據,如
v-bind = 'item',這種用法會將整個物件的所有屬性都綁定到當前元素上,適用於需要綁定的屬性過多的場景
// data: { // shapes: [ // { name: 'Square', sides: 4 }, // { name: 'Hexagon', sides: 6 }, // { name: 'Triangle', sides: 3 } // ], // colors: [ // { name: 'Yellow', hex: '#F4D03F', }, // { name: 'Green', hex: '#229954' }, // { name: 'Purple', hex: '#9B59B6' } // ] // } <my-list> <template> <div>{{ shape.name }} <small>({{ shape.sides }} sides)</small> </div> </template> </my-list> <my-list> <template> <div> <div></div> {{ color.name }} </div> </template> </my-list> <div> <div>{{ title }}</div> <div> <div> <slot></slot> </div> </div> </div> Vue.component('my-list', { template: '#my-list', props: [ 'title', 'items' ] });
遞歸元件就是指元件在模板中呼叫自己,由於是組件自身調用,就不能像常規組件定義一樣,可以省略組件的name配置,組件的遞歸需要依賴於自身的name配置(name還用於遍歷組件的name選項來查找組件的實例);
<template> <div> <my-component></my-component> </div> </template> <script> export default { name:'my-component', props: { count: { type: Number, default: 1 } } } </script>
有时候我们需要根据一些条件,动态的切换/选择某个组件,在函数式组件中,没有上下文的概念,常用于程序化的在多个组件中选择一个,可以间接的解决动态切换组件的需求,缺点是基于js对象进行开发,不方便开发;
Vue官方提供了一个内置组件<component></component>
和is的属性,用来解决上述的问题
<component></component> //component 就是js import进的组件实例,其值可以是标签名、组件名、直接绑定一个对象等
常规的组件components是直接通过引用定义好的组件进行展示的,也可以直接在当前组件内定义,然后通过配置components进行渲染
<div> <cpn></cpn> </div> <template> <div> <h2>Lbxin</h2> <p>class - 11</p> </div> </template> <script> var app = new Vue({ el: '#app', data: { isShow: true }, components: { cpn: { template: '#com', data() { isShow: false } } } }) </script>
<slot></slot>
简介HTML的slot元素,是Web Components技术套件的一部分,是Web组件内的一个占位符,该占位符可以在后期使用自己的标记语言进行填充,这样可以创建单独的DOM树,并将其与其他的组件组合在一起 -- MDN
常见的填充Web组件的shadow DOM的模板有template和slot
模板 - Templates
<template> <p>My paragraph</p> </template>
let template = document.getElementById('my-paragraph'); let templateContent = template.content; document.body.appendChild(templateContent);
customElements.define('my-paragraph', class extends HTMLElement { constructor() { super(); let template = document.getElementById('my-paragraph'); let templateContent = template.content; const shadowRoot = this.attachShadow({mode: 'open'}) .appendChild(templateContent.cloneNode(true)); } }) // 自定义标签使用 <my-paragraph></my-paragraph>
template.content
获取到然后打入到指定的容器中)Web Component简介
Web Component的一个很重要的属性就是封装 - 可以将标记结构、样式和行为影藏起来,并于界面上的其他代码隔离开来,保证代码的独立性
Web Component标准非常重要的一个特性是,使得开发者可以将HTML页面的功能封住成custom elements(自定义标签)
customElements 接口用来实现一个对象,允许开发者注册一个custom elements的信息,返回已注册的自定义标签的信息;
customElements.define方法用来注册一个custom element,接收三个参数
参数一:表明创建元素的名称,其注册的名称不能简单的单词,需要由短划线进行拼接
参数二:用于定义元素行为的类
参数三:一个包含extends属性配置的配置对象,可选,指定了所创建的自定义元素是继承于哪个内置的元素,可以继承任何内置的元素;
customElements.define( 'word-count', WordCount, { extends: 'p' } );
可以使用ES2015的类实现
class WordCount extends HTMLParagraphElement { constructor() { // 必须首先调用 super 方法 super(); // 元素的功能代码写在这里 ... } }
自定义标签的类型
Autonomous custom elements
是独立的元素,它不继承其他内建的 HTML 元素,可以直接通过标签的方式进行HTML使用<popup-info></popup-info>
,也可以通过js的方式进行使用document.createElement("popup-info")
Customized built-in elements
继承自基本的 HTML 元素。在创建时,你必须指定所需扩展的元素,使用时,需要先写出基本的元素标签,并通过 is
属性指定 custom element 的名称;<p is="word-count"></p>
或document.createElement("p", { is: "word-count" })
shadow DOM简介
图解Shandow DOM
Shadow host:一个常规 DOM 节点,Shadow DOM 会被附加到这个节点上。
Shadow tree:Shadow DOM 内部的 DOM 树。
Shadow boundary:Shadow DOM 结束的地方,也是常规 DOM 开始的地方。
Shadow root: Shadow tree 的根节点。
shadow DOM主要是将一个隐藏的、独立的DOM树附加到常规的DOM树上,是以shadow DOM节点为起始根节点,在这个根节点的下方,可以是任意的元素,和普通的DOM元素一致
如常见的video标签,其内部的一些控制器和按钮等都是通过Shandow DOM进行维护的,开发者可以通过这个API进行自己独立的逻辑控制
基本用法
mode
的属性,值可以是open - 可以通过外部js获取 Shadow DOM和closed - 外部不可以通过js进行获取 Shadow DOMlet shadow1 = elementRef.attachShadow({mode: 'open'}); let shadow2 = elementRef.attachShadow({mode: 'closed'}); let myShadowDom = shadow1.shadowRoot; // 具体内容 let myShadowDom = shadow2.shadowRoot; //null
let shadow = this.attachShadow({mode: 'open'}); // 将一个shadow DOM添加到一个元素上之后就可以使用DOM API进行操作访问了
以上是深入理解Vue中的插槽、內容分發、具名插槽的詳細內容。更多資訊請關注PHP中文網其他相關文章!