zoukankan      html  css  js  c++  java
  • vue第十单元(动态组件 keep-alive(钩子函数) 递归组件(name) 组件命名约定)

    第十单元(动态组件 keep-alive(钩子函数) 递归组件(name) 组件命名约定)

    #课程目标

    1. 熟练掌握动态组件的实现
    2. 掌握keep-alive缓存组件,以及相应的钩子函数
    3. 熟练掌握递归组件,以及递归组件的实现原理
    4. 了解组件的命名约定

    #知识点

    #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组件有条件地缓存 includeexclude
    • 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 ,浏览器原生的解析器也无法识别它。

    #授课思路

    #案例和作业

    使用递归组件方式完成如下图的多级菜单

  • 相关阅读:
    [转]SVN服务器搭建和使用(二)
    [转]SVN服务器搭建和使用(一)
    BZOJ 2049 Sdoi2008 Cave 洞穴勘测
    BZOJ 1589 Usaco2008 Dec Trick or Treat on the Farm 采集糖果
    BZOJ 2796 POI2012 Fibonacci Representation
    BZOJ 2115 Wc2011 Xor
    BZOJ 3105 CQOI2013 新Nim游戏
    BZOJ 2460 Beijing2011 元素
    BZOJ 3687 简单题
    BZOJ 1068 SCOI2008 压缩
  • 原文地址:https://www.cnblogs.com/yzy521/p/14132044.html
Copyright © 2011-2022 走看看