1、插槽

(1)插槽内容

像 HTML 元素一样,我们常常需要给组件传递内容

比如在下面的例子中,我们给自定义组件 prompt-info 传入 出错啦 的文本

<!DOCTYPE html>
<html><head><title>Demo</title></head><body><div id="app"><prompt-info>出错啦</prompt-info></div></body></html>

但是,结果并不像我们所想的,出错啦 的提示信息没有显示出来,这时候我们就可以使用 <slot> 解决这个问题

<slot> 就是插槽,也就是说我们需要先在组件中留下一个位置,然后才能在使用的时候把传入的内容放进去

Vue.component('prompt-info', {template: `<div><h3>提示信息</h3><slot></slot></div>`
})

我们还可以为插槽提供默认内容,但是它仅仅会在没有提供内容的时候显示出来

Vue.component('prompt-info', {template: `<div><h3>提示信息</h3><slot>不好意思</slot></div>`
})

在定义好插槽后就可以正常显示传入的内容啦,事实上我们不仅可以传入简单的文本,还可以传入任何模板代码

<div id="app"><prompt-info><span>出错啦</span><p>请稍后再试</p></prompt-info>
</div>

(2)插槽数据

考虑一个问题,上面我们传入的模板代码中是没有包含数据的,假如现在我们使用数据会发生什么呢?

这里面还有一定的讲究

  • 数据在父级模板中定义,在父级模板中使用:例如下面的 msg
<!DOCTYPE html>
<html><head><title>Demo</title></head><body><div id="app"><prompt-info>{{ msg }}</prompt-info></div></body></html>
  • 数据在子模板中定义,在子模板中使用:例如下面的 info
<!DOCTYPE html>
<html><head><title>Demo</title></head><body><div id="app"><prompt-info></prompt-info></div></body></html>
  • 数据在子模板中定义,在父级模板中使用

这次没有这么简单,我们先来看一份简单的代码:

<!DOCTYPE html>
<html><head><title>Demo</title></head><body><div id="app"><prompt-info>{{ info }}</prompt-info></div></body></html>

实际上,这份代码不会被正确编译,控制台会输出错误信息:info is not defined

这是因为 父级模板里的所有内容都是在父级作用域中编译的,子模板里的所有内容都是在子作用域中编译的

如果我们希望让插槽内容访问子组件数据,可以怎么做呢?

首先,我们需要在 <slot> 元素上使用 v-bind 指令绑定数据(绑定在 <slot> 元素上的特性称为 插槽 prop

然后,我们就可以在组件上使用 v-slot 指令获取并使用 插槽 prop

(注意,在这里使用 v-slot 的语法为 v-slot='slotProps'

<!DOCTYPE html>
<html><head><title>Demo</title></head><body><div id="app"><prompt-info v-slot='slotProps'>{{ slotProps.info }}</prompt-info></div></body></html>

(3)具名插槽

好,下面我们再来考虑另一个问题,当我们需要使用多个插槽时,应该怎么对它们进行区分呢?

答案是在定义的时候使用 name 特性为插槽命名,然后在使用的时候还是使用 v-slot 指令指定插槽

(注意,在这里使用 v-slot 的语法为 v-slot:slotName,与上面的语法并不冲突)

<!DOCTYPE html>
<html><head><title>Demo</title></head><body><div id="app"><prompt-info><template v-slot:header><p>服务离家出走啦</p></template><!-- 没有使用 v-slot 指令指定的元素默认放在 default 插槽 --><template><p>请稍后再试</p></template><template v-slot:footer><p>不好意思</p></template></prompt-info></div></body></html>
  • 具名插槽的缩写:

v-onv-bind 指令一样,Vue 也为 v-slot 指令提供了缩写

<!-- 完整语法 -->
<template v-slot:header>...</template><!-- 缩写 -->
<template #header>...</template>
  • 独占默认插槽的缩写:

当只有一个默认插槽时,我们可以直接把 v-slot 用在组件上:

Vue.component('prompt-info', {template: `<div><h3>提示信息</h3><slot></slot> </div>`
})
<prompt-info v-slot:default="slotProps"></prompt-info>

但是只要出现多个插槽,请始终为所有的插槽使用完整的基于 <template> 的语法:

Vue.component('prompt-info', {template: `<div><h3>提示信息</h3><slot name="header"></slot><slot></slot> <slot name="footer"></slot></div>`
})
<prompt-info v-slot:default="slotProps"><template v-slot:header="slotProps"><!-- 内容 --></template><template v-slot:default="slotProps"><!-- 内容 --></template><template v-slot:footer="slotProps"><!-- 内容 --></template>
</prompt-info>

2、动态组件 & 异步组件

(1)动态组件

动态组件其实就是动态切换组件,我们可以通过 <component> 元素配合 is 特性实现,来看一个简单的例子

<!DOCTYPE html>
<html><head><title>Demo</title></head><body><div id="app"><button v-for="tab in tabs" v-on:click="currentTab = tab">{{ tab }}</button><component v-bind:is="currentTabComponent"></component></div></body></html>

当每次切换组件时,Vue 都会创建一个 currentTabComponent 实例

但是,有的时候我们却希望能够保持组件的状态,以避免反复重渲染导致的性能问题

这时候我们可以通过 <keep-alive> 元素实现,包裹在该元素内的组件在第一次创建时会被缓存起来

<keep-alive><component v-bind:is="currentTabComponent"></component>
</keep-alive>

(2)异步组件

异步组件其实就是异步加载组件,我们可以通过工厂函数定义组件,一个简单的例子如下

<!DOCTYPE html>
<html><head><title>Demo</title></head><body><div id="app"><p>Hello</p><my-component></my-component></div></body></html>

我们还可以在工厂函数中返回 Promise 对象,把 webpack 和 ES2015 语法结合在一起使用

Vue.component('my-component', () => import('./async-component'))

3、边界情况

(1)访问元素

绝大多数情况下,我们不应该触及另一个组件实例内部或手动操作 DOM 元素,但是也的确存在这样的情况

  • 访问父级组件实例
<!DOCTYPE html>
<html><head><title>Demo</title></head><body><div id="app"><my-component></my-component></div></body></html>
  • 访问子组件实例
<!DOCTYPE html>
<html><head><title>Demo</title></head><body><div id="app"><button v-on:click="showMsg()">打印信息</button><my-component ref="page"></my-component></div></body></html>
  • 访问子元素
<!DOCTYPE html>
<html><head><title>Demo</title></head><body><div id="app"><button v-on:click="changeText()">改变文本</button><p ref="page">Hello World</p></div></body></html>
  • 依赖注入

使用 provide 选项指定提供什么数据给后代,然后在任何后代组件中都可以使用 inject 选项接收数据

<!DOCTYPE html>
<html><head><title>Demo</title></head><body><div id="app"><my-component></my-component></div></body></html>

转载于:https://www.cnblogs.com/wsmrzx/p/11219825.html

Vue学习笔记(八) 组件进阶相关推荐

  1. Vue学习笔记05 组件的自定义事件-组件通信-$nextTick-脚手架解决ajax跨域-插槽-过渡动画

    文章目录 Vue学习笔记05 父组件给子组件传值 注意点 子组件给父组件传值 父组件接受子组件的传值 通过函数 组件的自定义事件 事件绑定的第一种写法 @或v-on 事件绑定的第二种写法:使用ref ...

  2. Vue学习笔记02 = 组件化

    目录 一.组件化基本概念 什么是组件化?组件化有什么作用? 人面对复杂问题的处理方式: 组件化也是类似的思想: Vue组件化思想: 组件化思想的应用: 二.组件的基本使用: 2.1.创建组件的构造器. ...

  3. 【Vue】Vue学习笔记——UI组件库和常用插件

    文章目录 6. UI组件库和常用插件 6.1 Element-ui 6.2 Vue-router 6.2.1 基本用法 6.2.2 跳转 6.2.3 路由嵌套 6.2.4 路由参数传递 6.3 Axi ...

  4. 少侠请重新来过 - Vue学习笔记(八) - Vuex

    Vuex 是什么? Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. State Vuex ...

  5. vue学习笔记(1)-组件通信

    vue.js官方教程上讲的也挺清楚的了,自己整理一遍以加深印象,同时也完成自己的项目中需要的动态创建表单提交编辑修改功能. 表单主要是v-model双向绑定实现父组件与子组件的双向数据传递,所以首先说 ...

  6. Vue学习笔记_组件化

    文章目录

  7. Vue学习笔记进阶篇——多元素及多组件过渡

    本文为转载,原文:Vue学习笔记进阶篇--多元素及多组件过渡 多元素的过渡 对于原生标签可以使用 v-if/v-else.但是有一点需要注意: 当有相同标签名的元素切换时,需要通过 key 特性设置唯 ...

  8. Vue学习笔记进阶篇——Render函数

    本文为转载,原文:Vue学习笔记进阶篇--Render函数 基础 Vue 推荐在绝大多数情况下使用 template 来创建你的 HTML.然而在一些场景中,你真的需要 JavaScript 的完全编 ...

  9. day4 vue 学习笔记 组件 生命周期 数据共享 数组常用方法

    系列文章目录 day1学习vue2笔记 vue指令 day2 学习vue2 笔记 过滤器 侦听器 计算属性 axios day3 vue2 学习笔记 vue组件 day4 vue 学习笔记 组件 生命 ...

最新文章

  1. Android 布局跟着NAVIGATION_BAR 重新布局
  2. JavaScript cookie
  3. 使用Spyder生成动态二维码遇到的问题 ImportError 、ValueError 、OSError
  4. 云技术与云计算的区别
  5. Python常见错误及解决方案(持续更新)
  6. 关于SOA的四个基本观点 from MS
  7. tensorflow处理简单线性回归
  8. html5判断设备的动作
  9. JAVA复习5(总结+循环链表)
  10. mysql运用索引写出高效sql_从SQL Server到MySql(5) : 高性能的MySql 索引策略
  11. SQLserver通过链接服务器连接oracle
  12. python结构体字节对齐_Python及字节对齐的问题
  13. 键盘测试软件能自动,键盘测试软件哪个好用?2020键盘测试软件推荐
  14. .net xml转json
  15. 如何引导机器?如何面临人机结合?《​人工智能与人类未来》
  16. 数据挖掘(一)-探索性数据分析
  17. Buffer(缓冲区)
  18. 数位DP入门笔记(1)HUD-2089
  19. 网络学习(一)--基本模型学习
  20. 查看mysql 表 被人删除_MySQL 删除数据表

热门文章

  1. jQuery相当于对 javascript二次开发,所以基于 jQuery实现的各种插件直接调用即可...
  2. ios7开发学习笔记-包括c oc 和ios介绍
  3. windows phone7资料整理
  4. 如何在 Windows Server 2003、Windows 2000 和 Windows XP 中备份恢复代理的加密文件系统 (EFS) 私钥...
  5. 六种方法,做一名更好的开发者
  6. libcurl库进行http通讯网络编程
  7. [pytorch、学习] - 5.4 池化层
  8. (水一下)Linux启动步骤(面试题)
  9. 淘宝top平台调用接口响应时间优化
  10. PLSQL DBMS_DDL.ANALYZE_OBJECT