动态组件

除了允许用户自定义组件之外,Vue还内置了一些组件,以帮助用户高效地开发一些功能。本章将带领大家一起来了解这些内置组件。
某些时候需要动态切换页面部分区域的视图,这个时候内置组件component就显得尤为重要。 component接收一个名为is的属性,is的值应为在父组件中注册过的组件的名称,用法如下:
< !-- view为变量 -->

下面来看一个示例,代码如下:

 <style>.tabs {margin: 0;padding: 0;list-style: none;}.per-tab {display: inline-block;width: 120px;line-height: 32px;border-left: 1px solid #ccc;border-top: 1px solid #ccc;}.per-tab:last-child {border-right: 1px solid #ccc;}.tab-content {height: 240px;border: 1px solid #ccc;}</style><div id="app"><ul class="tabs"><li class="per-tab" @click="toggleView('Home')">Home</li><!----><li class="per-tab" @click="toggleView('About')">About</li></ul><div class="tab-content"><component :is="view"></component> <!-- view为变量 --></div></div><script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.min.js"></script><script type="text/javascript">let Home = {  // Home组件template: '<p style="color: #787878;">Hello Home!</p>'}let About = {  // About组件template: '<p>Hello About!</p>'}let vm = new Vue({  // Vue实例el: '#app',components: { Home, About },data () {return {view: 'Home'}},methods: {toggleView (view) {this.view = view}}})</script>

效果:

点击两个组件会呈现不同的字
定义了Home和Aboat两个组件,并使用components选项将其注册到实例vm中,初始时设置is的值为Home:

data () {
return {
view: ‘Home’
}
},

使用插槽分发内容

通过props选项,组件可以接收多态的数据,如何接收多态的DOM结构呢? 实现方法有很多,比如使用props配合v-html等。这里,Vue提供了一种更简单的选择,使用内置组件slot(插槽)分发内容。 在定义多个插槽时,我们可以使用name属性对其进行区分,如果没有指定name属性,则Vue会将所有的插槽内容置于默认插槽default中。 下面来看一段示例代码:

  <div id="app"><slot-test><p>使用插槽分发内容</p><h1 slot="header">插槽测试!</h1><p>在组件中,没有指定插槽名称的元素将被置于默认插槽中</p><p slot="none">指定到不存在的插槽中的内容将不会被显示</p></slot-test></div><script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.min.     js"></script><script type="text/javascript">let SlotTest = {template: '<div>' +'<slot name="header">相当于占位元素,因此这些文字也不会被渲染</slot>' +  //具名插槽'<slot></slot>' +  // 默认插槽'</div>'}let vm = new Vue({  // Vue实例el: '#app',components: { SlotTest }})</script>


是通过 < slot name=“header”>相当于占位元素,因此这些文字也不会被渲染’ 和 < h1 slot=“header”>插槽测试!
来进行渲染的,可以看到 < p slot=“none”>指定到不存在的插槽中的内容将不会被显示< /p> 这句话并没有显示出来。说明父组件的元素被成功分发导对应插槽中。
VUE还提供了作用域插槽slot-scope(在VUE2.5以下版本为scope,只可用于template元素)我们可以用slot-scope获取子组件回传的数据,用来在父组件中执行多态的渲染或响应

一个实例:

<body>
<style>#app {color: #206fbf;font-family: Roboto, sans-serif;}.label {display: inline-block;min-width: 160px;}
</style>
<style>.tabs {margin: 0;padding: 0;list-style: none;}.per-tab {display: inline-block;width: 120px;line-height: 32px;border-left: 1px solid #583b3b;border-top: 1px solid #e21a1a;}.per-tab:last-child {border-right: 1px solid #7f0303;}.tab-content {height: 240px;border: 1px solid #0f7f8d;}
</style>
<style>.btn {outline: none;border: none;cursor: pointer;padding: 5px 12px;}.btn-text {color: #409eff;background-color:#42b983;}/*这个backgroundcolor是改变切换标记的背景颜色*/.btn-text:hover {color: #ff66b5;}/*}这个是改变点击切换标记之后水果显示的颜色*/. fly-table {width: 400px;text-align: left;line-height: 42px;border: 1px solid #b37f3f;user-select: none;}
</style>
<div id="app"><h2>Fly Table Component</h2><buttonclass="btn btn-text"title="点击使数组倒序"@click="handleReverse">
<!--        /* 用来倒序的函数*/-->倒序</button><fly-table:fields=" fields":goods="goods"><!-- 组件标签包裹着的内容将被分发 --><!-- 思考下:是否可以在 fly-table组件中直接书写这段代码? --><template slot-scope="{ row, col }"><span v-if="col.prop !== 'operate'">{{ row[col.prop] }}</span><buttonclass="btn btn-text"v-else@click="handleMarked(row)">切换标记</button></template>
</fly-table>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.min.js"></script>
<script type="text/javascript">let FlyTable = {props: {  // 组件接收从父组件传入的数据fields: {type: Array,default () {return []}},goods: {type: Array,default () {return []}}},template: function () {return '<table class=" fly-table">\n' +'    <tr>\n' +'      <th\n' +'        v-for="(col, cIndex) in fields"\n' +'        :key="cIndex">\n' +'        {{ col.label }}\n' +'      </th>\n' +'    </tr>\n' +'    <tr\n' +'      v-for="(row, rIndex) in goods"\n' +'      :key="rIndex"\n' +'      :style="{color: row.isMarked ? \'#ea4335\' : \'\'}">\n' +'      <td\n' +'        style="border-top: 1px solid #eee"\n' +'        v-for="(col, cIndex) in fields"\n' +'        :key="cIndex">\n' +// slot应写在子组件中,用于接收父组件分发的内容'        <slot :row="row" :col="col"></slot>\n' +'      </td>\n' +'    </tr>\n' +'  </table>'}()}// 声明 Vue 实例let vm = new Vue({el: '#app',components: { FlyTable },data () {return {fields: [{label: '名称',prop: 'name'},{label: '数量',prop: 'quantity'},{label: '价格',prop: 'price'},{label: '',prop: 'operate'}],goods: [{name: '苹果',quantity: 200,price: 6.8,isMarked: false},{name: '西瓜',quantity: 50,price: 4.8,isMarked: false},{name: '榴莲',quantity: 0,price: 22.8,isMarked: false}]}},methods: {handleReverse () {this.goods.reverse()},handleMarked (row) {row.isMarked = !row.isMarked}}})
</script></body>



这段代码中定义了fly-table组件,它接收fields和goods属性,用以动态显示表格数据。在调用fly-table时,还提供了倒序数组的功能,并使用slot-scope根据数据的不同进行多态的视图渲染。显然,在之前的代码改造之后,fly-table组件的复用性更好

组件的缓存

keep-alive是一个抽象组件,即它既不渲染任何DOM元素,也不会出现在组件结构树中。我们可以使用它缓存一些非动态的组件实例(没有或不需要数据变化),以保留组件状态或减少重新渲染的开销。keep-alive应出现在组件被移除之后需要再次挂载的地方,比如使用动态组件时:
 
 

或者使用v-if时:

它还可以接收include和exclude两个props属性:
●include字符串或正则表达式。只有匹配的组件会被缓存。 ●exlude字符串或正则表达式。任何被匹配的组件将不会被缓存。
当组件在keep-alive内被切换时,它的activated和deactivated这两个生命周期钩子函数将会被执行。

过渡效果

单节点的过渡

Vue提供了标签为transition的内置组件,在下列情形中,我们可以给任何元素和组件添加进入/离开时的过渡动画:
  ●元素或组件初始渲染时
  ●元素或组件显示/隐藏时(使用v-if或v-show进行条件渲染时)
  ●元素或组件切换时 Vue允许用户使用CSS和JS两种方式来定义过渡效果。 在使用CSS过渡时,我们需要预置符合Vue规则的带样式的类名,这些类名用于定义过渡不同阶段时的样式:
  ●v-enter:定义进入过渡的开始状态。在元素被插入前生效,被插入后的下一帧移除。
  ●v-enter-active:定义进入过渡生效时的状态。在整个进入过渡阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以用来定义进入过渡的过程时间、延迟和曲线函数等。
  ●v-enter-to:(Vue 2.1.8及以上版本)定义进入过渡结束时的状态。在元素被插入后的下一帧生效(此时v-enter被移除),在过渡/动画完成之后移除。
  ●v-leave:定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。
  ●v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。 这个类可以被用来定义离开过渡的过程时间、延迟和曲线函数。
  ●v-leave-to:(Vue 2.1.8版及以上版本)定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效(此时v-leave被移除),在过渡/动画完成之后移除。 当实例中存在多个不同的动画效果时,我们可以使用自定义前缀替换v-,比如使用slide-enter替换v-enter,不过这需要赋予transition元素name属性。 下面来看一个示例,代码如下:

<body>
<style>/* 在此处声明过渡样式类,从一个状态过渡到另一个状态 */.v-enter,.v-leave-to {opacity: 0;}.v-enter-active,.v-leave-active {transition-property: opacity; /* 过渡属性 */transition-delay: 100ms;  /* 延迟 */transition-duration: 900ms; /* 过渡时长 */transition-timing-function: linear; /* 贝塞尔曲线(动画速度曲线) */}.rotate-enter,.rotate-leave-to {transform: rotateY(90deg);}.rotate-enter-active,.rotate-leave-active {transform-origin: left;transition: transform 1s linear;}</style><div id="app"><button @click="isHidden = !isHidden"> {{ isHidden?'显示':'隐藏' }}</button><!-- 默认前缀的过渡 --><transition><p v-if="!isHidden">使用默认前缀的过渡</p></transition><!-- 自定义前缀的过渡,transitionName为变量 --><transition :name="transtionName"><p v-if="!isHidden">使用rotate前缀的过渡</p></transition></div><script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.min.js"></script><script type="text/javascript">// 声明 Vue 实例let vm = new Vue({el: '#app',data () {return {isHidden: true,transtionName: 'rotate' /*// 如果在运行时,将transitionName改为v会怎样?*/}}})</script></body>

效果:

点击显示之后,字体慢慢浮现

除了transition之外,我们还可以使用CSS中的animation,或者直接使用第三方动画库(如Animate.css)来实现过渡动画。借助于Animate.css,我们可以用十分简短的代码来实现一个酷炫的动画效果,
由于这些动画库有着不同的类名规则,无法与Vue默认的类名规则配合使用,因此Vue为其提供了兼容方案,允许用户自定义过渡的类名,这些类名的优先级将高于默认的类名。 我们可以使用以下特性来自定义过渡类名:
●enter-class
●enter-active-class
●enter-to-class
●leave-class
●leave-active-class
●leave-to-class
下面来看一段示例代码:

<body><!-- 引入Animate.css动画库 -->
<linkrel="stylesheet"href="https://cdnjs.cloud flare.com/ajax/libs/animate.css/3.5.2/animate.min.css"><!-- 引入Vue --><script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.min.js"></script><style>.inline-block {display: inline-block;}.rotate-enter-active {animation: selfRotateIn 1s;}.rotate-leave-active {animation: selfRotateOut 1s;}/* 命名避免与Animate.css冲突 */@keyframes selfRotateIn {0% {opacity: 0;transform: rotateZ(-180deg);}100% {opacity: 1;transform: rotateZ(0deg);}}@keyframes selfRotateOut {0% {opacity: 1;transform: rotateZ(0deg);}100% {opacity: 0;transform: rotateZ(180deg);}}</style><div id="app"><button @click="isHidden = !isHidden">{{ isHidden ? '显示' : '隐藏' }}</button><!-- 自定义的动画 --><transition name="rotate">
<span class="inline-block" v-if="!isHidden">自定义的动画</span></transition><!-- animate.css的动画 --><transitionname="custom"enter-active-class="animated rotateIn"leave-active-class="animated rotateOut"><span class="inline-block" v-if="!isHidden">animate.css动画</span><script type="text/javascript">// 声明 Vue 实例let vm = new Vue({el: '#app',data () {return {isHidden: true}}})</script></body>

效果:

点击显示时字体旋转浮现

节选自–《vue.js从入门到实战》

VUE内置组件 vue使用插槽分发内容 组件缓存 实现动画的过渡效果相关推荐

  1. 浅谈Vue内置component组件的应用场景

    官方的说明 渲染一个"元组件"为动态组件.依 is 的值,来决定哪个组件被渲染. <!-- 动态组件由 vm 实例的属性值 `componentId` 控制 --> & ...

  2. vue内置动态组件component使用详解

    1 动态组件介绍 component是vue内置组件,主要作用为动态渲染组件,基本用法如下: <!-- 动态组件由 vm 实例的 `componentName` property 控制 --&g ...

  3. vue组件-使用插槽分发内容(slot)

    slot--使用插槽分发内容(位置.槽口:作用: 占个位置) 官网API: https://cn.vuejs.org/v2/guide/components.html#使用插槽分发内容 使用组件时,有 ...

  4. vue.js 数据替换_Vue.js实战笔记之Vue内置指令

    指令是Vue模板中最常用的一项功能,它带有前缀v-,主要职责是当其表达式的值改变时,相应的将某些行为应用在 DOM 上. 基本指令 v-clock v-clock 不需要表达式,它会在 Vue 实例结 ...

  5. 2.0 vue内置指令与自定义指令

    一.概述 模板在解析之前指令是存在的,但是解析完成以后就不存在了. 1.1 常用内置指令 1) v:text : 更新元素的 textContent 2) v-html : 更新元素的 innerHT ...

  6. Vue 内置指令、自定义指令、过滤器

    文章目录 内置指令 v-text指令 v-html指令 v-cloak指令 v-once指令 v-pre指令 自定义指令 过滤器 内置指令 复习之前所学指令: v-bind:单向绑定解析表达式, 可简 ...

  7. 为什么vs2005内置Web application server中调用COM组件时正常,在IIS中运行时组件创建失败?...

    如题. 在vs2005内置服务器中运行正常,发布到IIS中运行时出现组件创建失败的错误.错误页面如 下: 不知道有没有遇到过这种情况的兄弟?麻烦指点一二.谢谢!

  8. Vue - 实现图片裁剪功能,并上传到服务器(内置第三方最优秀的裁剪图片组件,上传到服务器功能)干净整洁无 BUG 的示例源码与超详细的注释,兼容任意浏览器

    前言 您可以滑动到文章最底部,直接克隆完整示例 Gitee 仓库,与本文教程最终效果一致. 在项目开发中,您难免会遇到图片上传到服务器之前,用户可进行裁剪的需求, 在看了网上大部分教程后,代码都非常乱 ...

  9. 过滤器、vue内置指令

    一.过滤器 定义:对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理) 语法: 1.注册过滤器:Vue.filter(name ,function(){})(全局过滤器)或new vue{ ...

最新文章

  1. 关于Laravel中使用response()方法调用json()返回数据unicode编码转换的问题解决
  2. Java中设计模式之工厂模式-4
  3. java集合详解_Map、Set、List及其子类和接口你都明白吗?看这篇Java集合超详解
  4. 一道关于比赛胜负的Sql查询题目
  5. Navicat Premium试用期破解方法(转)
  6. UserInfoActivity用户图像修改和退出登录
  7. 数组——寄包柜(洛谷 P3613)
  8. 大屏数据可视化综合设计
  9. 拼多多回应“轩尼诗假酒”案:实际售出3单 9月已关闭店铺
  10. MySQL 的主从原理和复制过程简述
  11. linux Enterprise5 添加删除程序无法正常使用 解决
  12. html中的坐标从哪里开始,HTML+CSS入门 页面内跳转到相应位置的3种方法
  13. 协议栈处理中的conntrack HASH查找/Bloom过滤/CACHE查找/大包与小包/分层处理风格
  14. eclipse没有server选项怎么解决
  15. mysql怎么导入sql文件_如何将sql文件导入mysql
  16. 计算机音乐狂浪乐谱,当代歌曲 - 听海(流行歌曲 简谱)
  17. 光敏二极管的工作原理
  18. 刻录DVD9光盘内容至DVD5 DVD-R盘指南
  19. VS2017 C++控制台程序不用加pch.h
  20. 简单飞机模型静态/模态分析

热门文章

  1. 腾讯html5平台,腾讯浏览服务
  2. buck电路matlab,buck变换器介绍_buck变换器matlab仿真
  3. Java八大基本数据类型和对应的封装类型
  4. java程序中可以有几个构造方法_java中多个构造方法可以相互引用么?
  5. linux界面添加地址,Linux系统下图形界面更改IP地址
  6. android开发标签栏应该设置多少钱,android – Flutter:刷卡后默认标签栏控制器......
  7. oracle禁止自动启动命令,自动启动和关闭Oracle 脚本
  8. macbook服务器文件,使用MacBook生成服务器使用的p12证书文件
  9. ubuntu18.04的ifconfig输出没有ip地址
  10. 机器学习付费专栏的一些简介