插槽(Slot)
定义一个名child子组件,为该子组件添加内容应该在子组件的template中定义,直接在父组件的<child>标签中定义的内容不会被渲染。
在子组件中通过加入<slot>元素占位,便能够渲染父组件中子组件标签中的内容了。
插槽内容
插槽可以有默认内容,当在父组件中没有提供内容的时候,来进行显示。
<!-- submit-button --> <button type="submit"> <slot>Submit</slot> </button> 1. <submit-button></submit-button> ⬇️ <button type="submit"> Submit </button> 2. <submit-button> Save </submit-button> ⬇️ <button type="submit"> Save </button>
作用域
父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
具名插槽
试想,我们有一个带有如下模版的<base-layout>组件
<div class="container"> <header> <!-- 我们希望把页头放这里 --> </header> <main> <!-- 我们希望把主要内容放这里 --> </main> <footer> <!-- 我们希望把页脚放这里 --> </footer> </div>
可以看到,在组件中显示的内容是划分不同的部位的,这个时候就需要使用到<slot>元素的一个特有的属性:name来实现了。这个特性可以用来定义额外的插槽。
<div class="container"> <header> <slot name="header"></slot> </header> <main> <slot></slot> </main> <footer> <slot name="footer"></slot> </footer> </div>
一个不带 name 的 <slot> 出口会带有隐含的名字“default”。
在向具名插槽提供内容的时候,我们可以在一个 <template> 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称:
<base-layout> <template v-slot:header> <h1>Here might be a page title</h1> </template> <p>A paragraph for the main content.</p> <p>And another one.</p> <template v-slot:footer> <p>Here's some contact info</p> </template> </base-layout>
现在 <template> 元素中的所有内容都将会被传入相应的插槽。任何没有被包裹在带有 v-slot 的 <template> 中的内容都会被视为默认插槽的内容。
当然,也可以将默认插槽的内容通过v-slot:default包裹起来。
v-slot 只能添加在一个 <template> 上
作用域插槽
当我们希望能够让插槽内容能够访问子组件中才有的数据时,我们可以将数据作为一个<slot>元素的特性绑定上去
<span> <slot v-bind:user="user"> {{ user.name }} </slot> </span>
绑定在<slot>元素上的特性被称为插槽prop。此时我们在父组件中通过给v-slot带一个值来定义我们提供的插槽prop的名字。
<current-user> <template v-slot:default="slotProps"> {{ slotProps.user.age }} </template> </current-user>
独占默认插槽的缩写语法
当被提供的内容只有默认插槽时,上面的写法可以被简化来写
<!-- 简化版 --> <current-user v-slot:default="slotProps"> {{ slotProps.user.firstName }} </current-user> <!-- 终极简化版 --> <current-user v-slot="slotProps"> {{ slotProps.user.firstName }} </current-user>
需要注意两点:
解构插槽Prop
作用域插槽的内部工作原理是将你的插槽内容包括在一个传入单个参数的函数里:
function (slotProps) { // 插槽内容 }
这意味着 v-slot 的值实际上可以是任何能够作为函数定义中的参数的 JavaScript 表达式。所以在支持的环境下 (单文件组件或现代浏览器),你也可以使用 ES2015 解构来传入具体的插槽 prop,如下:
<current-user v-slot:default="slotProps"> {{ slotProps.user.firstName }} </current-user> ⬇️ <current-user v-slot="{ user }"> {{ user.firstName }} </current-user>
使用场景举例
插槽 prop 允许我们将插槽转换为可复用的模板,这些模板可以基于输入的 prop 渲染出不同的内容。
这在设计封装数据逻辑同时允许父级组件自定义部分布局的可复用组件时是最有用的。
动态插槽名
动态指令参数也可以用在 v-slot 上,来定义动态的插槽名
<base-layout> <template v-slot:[dynamicSlotName]> ... </template> </base-layout>
具名插槽缩写
v-slot可以缩写为#。
缩写方式只有在有参数的时候才可以使用
<!-- 这样会触发一个警告 --> <current-user #="{ user }"> {{ user.firstName }} </current-user> <!-- 这样是正确的 --> <current-user #default="{ user }"> {{ user.firstName }} </current-user>
动态组件&keep-alive
当在这些组件之间切换的时候,你有时会想保持这些组件的状态,以避免反复重渲染导致的性能问题。为了解决这个问题,我们可以用一个<keep-alive>元素将动态组件包裹起来
<!-- 失活的组件将会被缓存!--> <keep-alive> <component v-bind:is="currentTabComponent"></component> </keep-alive>
注意这个 <keep-alive> 要求被切换到的组件都有自己的名字,不论是通过组件的 name 选项还是局部/全局注册。
更加详细的说明在我们之后的实战过程中遇到的话,再进行专门解说。
异步组件
在实际的项目过程中,我们往往会将一系列的功能分割成一个个小的代码块,希望只有在需要的时候才去加载。为了达成这个目的,Vue允许我们以一个工厂函数的方式定义我们的组件,这个工厂函数会异步解析组件的定义。
Vue只有在这个组件需要渲染的时候才会触发这个工厂函数,而且会把结果缓存起来供之后使用。
Vue.component('async-example', function (resolve, reject) { setTimeout(function () { // 向 `resolve` 回调传递组件定义 resolve({ template: '<div>I am async!</div>' }) }, 1000) })
其实,这个过程有些类似于我们设计一个异步函数,这个工厂函数会收到一个resolve回调,这个回调在我们从服务器获取到组件定义的时候被调用,当加载失败的时候我们也可以调用reject(reason)。
一个推荐的做法是异步组件和webpack的code-splitting功能结合使用
Vue.component('async-webpack-example', function (resolve) { // 这个特殊的 `require` 语法将会告诉 webpack // 自动将你的构建代码切割成多个包,这些包 // 会通过 Ajax 请求加载 require(['./my-async-component'], resolve) })
同样,也可以在工厂函数中返回一个Promise
Vue.component( 'async-webpack-example', // 这个 `import` 函数会返回一个 `Promise` 对象。 () => import('./my-async-component') )
处理加载状态
上面的工厂函数可以返回一个下面格式的对象
const AsyncComponent = () => ({ // 需要加载的组件 (应该是一个 `Promise` 对象) component: import('./MyComponent.vue'), // 异步组件加载时使用的组件 loading: LoadingComponent, // 加载失败时使用的组件 error: ErrorComponent, // 展示加载时组件的延时时间。默认值是 200 (毫秒) delay: 200, // 如果提供了超时时间且组件加载也超时了, // 则使用加载失败时使用的组件。默认值是:`Infinity` timeout: 3000 })
小结
本篇我们主要围绕着Vue组件中的插槽和相关动态组件、异步组件的内容进行了梳理。通过这两篇的整理,我们对于Vue组件有了一个比较整体的了解。后续我们会在实战过程中针对具体的点再进行详细的说明。
以上所述是小编给大家介绍的Vue.js组件详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对小牛知识库网站的支持!
本文向大家介绍浅谈React组件之性能优化,包括了浅谈React组件之性能优化的使用技巧和注意事项,需要的朋友参考一下 高德纳: "我们应该忘记忽略很小的性能优化,可以说97%的情况下,过早的优化是万恶之源,而我们应该关心对性能影响最关键的另外3%的代码。" 不要将性能优化的精力浪费在对整体性能提高不大的代码上,而对性能有关键影响的部分,优化并不嫌早。因为,对性能影响最关键的部分,往往涉及解决方案
本文向大家介绍浅谈C++对象组合,包括了浅谈C++对象组合的使用技巧和注意事项,需要的朋友参考一下 以上所述就是本文的全部内容了,希望大家能够喜欢。
本文向大家介绍浅谈JavaScript的事件,包括了浅谈JavaScript的事件的使用技巧和注意事项,需要的朋友参考一下 1、事件流 事件流描述的是从页面中接收事件的顺序。但是IE提出的是冒泡流,而Netscape Communicator提出的是捕获流。 JavaScript事件流 2、事件冒泡(event bubbling) 事件开始由最具体的元素(嵌套层次最深的那个节点)接
本文向大家介绍浅谈vue.js导入css库(elementUi)的方法,包括了浅谈vue.js导入css库(elementUi)的方法的使用技巧和注意事项,需要的朋友参考一下 1.安装以下模块,让webpack可以解析css文件 2.安装elementUi模块 3.在webpack.base.conf.js中添加配置 4.然后在 main.js 引入并注册 以上这篇浅谈vue.js导入css库(e
本文向大家介绍浅谈Javascript 数组与字典,包括了浅谈Javascript 数组与字典的使用技巧和注意事项,需要的朋友参考一下 Javascript 的数组Array,既是一个数组,也是一个字典(Dictionary). 先举例看看数组的用法。 上面的代码创立了一个数组,每个元素都是一个字符串对象。 然后对数组进行遍历。注意 i 的结果为 0 和 1,a[i] 的结果才为字符串。 这个很象
大家都知道,在286以上的计算机中,一般都有一个CMOS RAM电路,它用于关机以后继续存放日期、时间、内存设置、软硬盘类型及其他许多有用的设置信息。CMOS即互补金属氧化物半导体,它的设置、应用和管理是保证系统正常工作的关键,下面就介绍一些有关CMOS的基本概念和应用。 ROM BIOS和CMOS RAM芯片 ROM BIOS是固化在ROM中的BIOS(Basic Input/Output Sy