vue第十单元(动态组件 keep-alive(钩子函数) 递归组件(name) 组件命名约定)
第十单元(动态组件 keep-alive(钩子函数) 递归组件(name) 组件命名约定)
#课程目标
- 熟练掌握动态组件的实现
- 掌握keep-alive缓存组件,以及相应的钩子函数
- 熟练掌握递归组件,以及递归组件的实现原理
- 了解组件的命名约定
#知识点
#1.动态组件
 首先得明白什么叫做动态组件,让多个组件使用同一个挂载点,并动态切换,这就是动态组件。
#1.1<component>元素
在vue中,可以通过使用保留的 <component> 元素,动态地绑定到它的 is 特性,可以实现动态组件
<template>
  <div>
  	<button @click="change">切换页面</button>
	<!--保留component元素  使用is显示相应的组件 实现动态组件-->
  	<component :is="currentView"></component>
  </div>
</template>
<script>
import Aa from '@/components/Aa'
import Bb from '@/components/Bb'
export default {
  name: 'Index',
  data () {
    return {
    	index:0,
        //将组件放进数组中
    	arr:[Aa,Bb],
    }
  },
  methods:{
  	change(){
      //改变index的值,在0和1中来回切换
      this.index = (++this.index)%2;
    }
  },
  computed:{
    //返回当前显示的数组
    currentView(){
        return this.arr[this.index];
    }
  }
}
</script>
#1.2动态组件的缓存(<keep-alive>  )
<keep-alive> 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和 <transition> 相似,<keep-alive> 是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在父组件链中
基础用法
<template>
  <div>
  	<button @click="change">切换页面</button>
	<!--keep-alive的使用方式,直接包在组件外面即可,里面的组件即可实现组件缓存-->
	<keep-alive>
    	<!--保留component元素  使用is显示相应的组件 实现动态组件-->
  		<component :is="currentView"></component>
	</keep-alive>
  </div>
</template>
<script>
import Aa from '@/components/Aa'
import Bb from '@/components/Bb'
export default {
  name: 'Index',
  data () {
    return {
    	index:0,
        //将组件放进数组中
    	arr:[Aa,Bb],
    }
  },
  methods:{
  	change(){
      //改变index的值,在0和1中来回切换
      this.index = (++this.index)%2;
    }
  },
  computed:{
    //返回当前显示的数组
    currentView(){
        return this.arr[this.index];
    }
  }
}
</script>
注意:既然是缓存,那么重新切换组件时,组件中相应的vue的生命周期函数,将不会再被触发(如:beforeCreate,created,beforeMount,mounted,beforeUpdate,updated,beforeDestroy,destroyed)
keep-alive元素中最后渲染的结果是,要求同时只有一个子元素被渲染(只能有一个根组件,和template元素类似),所以,我们也可以在keep-alive元素中写v-if判断组件的显示和隐藏:
<template>
  <div>
  	<button @click="change">切换页面</button>
	<!--keep-alive的使用方式,直接包在组件外面即可,里面的组件即可实现组件缓存-->
	<keep-alive>
    	<Aa v-if="index==0"></Aa>
		<Bb v-if="index==1"></Bb>
	</keep-alive>
  </div>
</template>
<script>
import Aa from '@/components/Aa'
import Bb from '@/components/Bb'
export default {
  name: 'Index',
  data () {
    return {
    	index:0,
        //将组件放进数组中
    	arr:[Aa,Bb],
    }
  },
  methods:{
  	change(){
      //改变index的值,在0和1中来回切换
      this.index = (++this.index)%2;
    }
  },
   components:{
	Aa,Bb
   }
  }
}
</script>
#1.3 缓存组件中的钩子函数activated 和 deactivated
activated 和 deactivated 在 <keep-alive> 树内的所有嵌套组件中触发
activated===>这个函数是在组件被切换显示的时候,触发该函数
deactivated===>这个函数是在组件被切换隐藏的时候,触发该函数
//Aa.vue组件  当这个组件显示或者隐藏时  会触发activated或者deactivated
<template>
  <div>
  	{{msg}}
  </div>
</template>
<script>
export default {
  name: 'Aa',
  data () {
    return {
    	msg:'我是Aa'
    }
  },
  //显示时触发该函数
  activated(){
  	console.log('a来了')
  },
  //隐藏时触发该函数
  deactivated(){
  	console.log('a走了')
  }
}
</script>
#1.4组件有条件地缓存 include和exclude
- include和- exclude属性允许组件有条件地缓存,见语义化命名,就知道前者是包含,后者则是排除。
- 二者都可以用逗号分隔字符串、正则表达式或一个数组来表示 。
- 匹配首先检查组件自身的 name选项,如果name选项不可用,则匹配它的局部注册名称(父组件components选项的键值)。
- 匿名组件不能被匹配。
<!-- 逗号分隔字符串 -->
<keep-alive include="Aa">
    <Aa v-if="index==0"></Aa>
	<Bb v-if="index==1"></Bb>
</keep-alive>
<!-- 正则表达式 (使用 v-bind) -->
<keep-alive :include="/Aa|Bb/">
    <Aa v-if="index==0"></Aa>
	<Bb v-if="index==1"></Bb>
</keep-alive>
<!-- 数组 (使用 v-bind)  -->
<keep-alive :include="['Aa', 'Bb']">
    <Aa v-if="index==0"></Aa>
	<Bb v-if="index==1"></Bb>
</keep-alive>
#2.递归组件
 对于一些有规律的 dom 结构,我们可以通过递归方式来生成这个结构,那么在vue的模板中,我们能不能递归生成dom,答案是肯定的,在vue的组件中能够调用自己本身,不过它们只能通过 name 选项来做这件事。
首先为了使用递归组件需要准备一份数据,既然要用递归组件,那么对我们的数据格式肯定是需要满足递归的条件的,就像下边这样,这是一个树状的递归数据。
  data () {
    return {
      list: [
        {
          name: '苹果',
          cList: [
            { name: '二级苹果1' },
            {
              name: '二级苹果2',
              cList: [
                { name: '三级苹果1', cList: [{ name: '四级苹果1' }] }
              ]
            }
          ]
        },
        { name: '香蕉' },
        {
          name: '西瓜',
          cList: [{ name: '二级西瓜1' }, { name: '二级西瓜2' }]
        }
      ]
    }
  }
接下来,我们就用这个树状数据,做一个简单版的树状菜单。树状菜单,也是递归组件最常用的方法之一。
首先,我们先创建一个tree组件,这个组件作为使用递归组件的父组件,我们来看下具体写法
<template>
  <div>
    <my-trees :list="list"></my-trees>
  </div>
</template>
<script>
import myTrees from './treeMenus'
export default {
	name:"Tree",
  components: {
    myTrees
  },
  data () {
    return {
      list: [
        {
          name: '苹果',
          cList: [
            { name: '二级苹果1' },
            {
              name: '二级苹果2',
              cList: [
                { name: '三级苹果1', cList: [{ name: '四级苹果1' }] }
              ]
            }
          ]
        },
        { name: '香蕉' },
        {
          name: '西瓜',
          cList: [{ name: '二级西瓜1' }, { name: '二级西瓜2' }]
        }
      ]
    }
  },
  methods: {}
}
</script>
<my-trees />就是我们说的递归组件,当使用它时,只需要把上边我们定义好的数据通过props的方式传进去即可。
接下来,递归组件接收到了父组件传递的数据,就可以进行递归啦,我们来看下边treeMenus.vue中的实现:
<template>
  <ul>
    <li v-for="(item,index) in list " :key="index">
      <p>{{item.name}}</p>
      <tree-menus :list="item.cList"></tree-menus>
    </li>
  </ul>
</template>
 <style>
   ul{
    padding-left: 20px!important;
   }
 </style>
<script>
	export default{
		name:'treeMenus',
		props:{
			list: Array
		}
	}
</script>
注意一开始所说,name属性的使用,你可以把它当作从import导入了一个组件并注册,我们在temlpate可以使用<tree-menus></tree-menus>使用子组件自身进行递归了。
#3.组件命名约定
当注册组件(或者 props)时,可以使用 kebab-case ,camelCase ,或 TitleCase 。
// 在组件定义中
components: {
  // 使用 camelCase 形式注册
  'kebab-cased-component': { /* ... */ },
  'camelCasedComponent': { /* ... */ },
  'TitleCasedComponent': { /* ... */ }
}
在 HTML 模版中,请使用 kebab-case 形式:
<!-- 在HTML模版中始终使用 kebab-case -->
<kebab-cased-component></kebab-cased-component>
<camel-cased-component></camel-cased-component>
<title-cased-component></title-cased-component>
当使用字符串模式时,可以不受 HTML 的 case-insensitive 限制。这意味实际上在模版中,你可以使用 camelCase 、 PascalCase 或者 kebab-case 来引用你的组件和 prop:
<!-- 在字符串模版中可以用任何你喜欢的方式-->
<my-component></my-component>
<myComponent></myComponent>
<MyComponent></MyComponent>
如果组件未经 slot 元素传递内容,你甚至可以在组件名后使用 / 使其自闭合:
<my-component/>
当然,这只在字符串模版中有效。因为自闭的自定义元素是无效的 HTML ,浏览器原生的解析器也无法识别它。
#授课思路

#案例和作业
使用递归组件方式完成如下图的多级菜单

vue第十单元(动态组件 keep-alive(钩子函数) 递归组件(name) 组件命名约定)的更多相关文章
- vue组件级路由钩子函数介绍,及实际应用
		正如其名,vue-router 提供的导航钩子主要用来拦截导航,让它完成跳转或取消. 有多种方式可以在路由导航发生时执行钩子:全局的.单个路由独享的.或者组件级的. 一.全局钩子 你可以使用 rout ... 
- vue组件级路由钩子函数(beforeRouteEnter/beforeRouteUpdate/beforeRouteLeave)
		1.vue组件级路由钩子函数(beforeRouteEnter/beforeRouteUpdate/beforeRouteLeave):http://www.menvscode.com/detail/ ... 
- vue第二十单元(vux的配置中模块modules的用法)
		第二十单元(vux的配置中模块modules的用法) #课程目标 1.什么是module? 2.怎么用module? 3.样板代码目录结构 #知识点 #1.modules 在Vue中State使用是单 ... 
- vue组件路由守卫钩子函数(beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave)
		用法:与mounted,created等同级并列. export default { data() { return { } }, methods: { go() { this.$router.pus ... 
- vue 组件中的钩子函数 不能直接写this
		export default { data(){ return { num: 18 } }, beforeRouteEnter(to, from, next){ next(vm=>{ vm.nu ... 
- vue学习目录 vue初识 this指向问题 vue组件传值 过滤器 钩子函数 路由 全家桶 脚手架 vuecli element-ui   axios bus
		vue学习目录 vue学习目录 Vue学习一之vue初识 Vue学习二之vue结合项目简单使用.this指向问题 Vue学习三之vue组件 Vue学习四之过滤器.钩子函数.路由.全家桶等 Vue学习之 ... 
- Vue 路由知识三(过渡动画及路由钩子函数)
		路由的过渡动画:让路由有过渡动画,需要在<router-view>标签的外部添加<transition>标签,标签还需要一个name属性. <transition nam ... 
- vue学习(五)生命周期 的钩子函数
		生命周期的钩子函数 主要有以下几种 beforeCreate created beforeMount mounted beforeUpdate updated activated deactivate ... 
- [前端] VUE基础 (5) (过滤器、生命周期、钩子函数)
		一.过滤器 过滤器分为局部过滤器和全局过滤器. 1.局部过滤器 <body> <div id="app"> </div> <script ... 
随机推荐
- Cypress系列(90)- Cypress.Cookies 命令详解以及如何跨测试用例共享 Cookies
			如果想从头学起Cypress,可以看下面的系列文章哦 https://www.cnblogs.com/poloyy/category/1768839.html Cypress.Cookies 共有三个 ... 
- 应届生应聘阿里,腾讯,美团90%会被问到的Netty面试题!史上最全系列!
			1.BIO.NIO 和 AIO 的区别? BIO:一个连接一个线程,客户端有连接请求时服务器端就需要启动一个线程进行处理.线程开销大.伪异步 IO:将请求连接放入线程池,一对多,但线程还是很宝贵的资源 ... 
- 已安装的nginx添加其他模块
			总体操作就是添加新模块并重新编译源码,然后把编译后的nginx可执行文件覆盖原来的那个即可.1 查看已安装的参数nginx -V拷贝那些巴拉巴拉的参数,后面编译的时候使用 2 下载相同版本号的源码,解 ... 
- Guitar Pro吉他指弹入门——日式指弹的pm技巧
			在上一篇指弹的文章中,笔者向大家介绍了一下美式指弹,以及他独树一帜的三指法.那么这一期的文章,我将介绍另一个指弹界的大流派--日式指弹,日式指弹曲子向来以细腻而多变的情绪以及表达出来的艳丽色彩著称,今 ... 
- mac搭建mnmp环境
			brew安装nginx brew install nginx 安装php56 brew tap homebrew/dupes brew tap josegonzalez/homebrew-php br ... 
- kafka producer 概要(看源码前,最好能掌握)
			kafakproducer概要(看源码前,最好能理解) 摘要 kafak 被设计用来作为一个统一的平台来处理庞大的数据的实时工具,在设计上有诸多变态的要求 它必须具有高吞吐量才能支持大量事件流 ... 
- Python学习第四天----模块儿导入
			1.命名空间 模块儿的名字加上文件的名字,就是命名空间. python如何区分一个普通的文件夹和一个包的? 在一个文件夹下有一个特定的文件__init__.py,此时这个文件夹就是一个包.(前后各两个 ... 
- java41
			2019.8.7全部回顾完毕 收获:搞懂了以前不理解的内容 学会了Markdown语法 1. 将首字母变大写 public class _02将首字母变大写 { public static void ... 
- oracle set oracle_sid=xxxxxx
			本地有多个实例,在cmd 输入 set oracle_sid=xxxxx 来指定要连接的实例 sqlplus xxxx/xxxx@1.1.1.1.1/sid 连接数据库 
- Python音视频开发:消除抖音短视频Logo的图形化工具实现
			☞ ░ 前往老猿Python博文目录 ░ 一.引言 在<Python音视频开发:消除抖音短视频Logo和去电视台标的实现详解>节介绍了怎么通过Python+Moviepy+OpenCV实现 ... 
