zoukankan      html  css  js  c++  java
  • 如何使用vue递归组件

      首先我们要知道,既然是递归组件,那么一定要有一个结束的条件,否则就会使用组件循环引用,最终出现“max stack size exceeded”的错误,也就是栈溢出。那么,我们可以使用v-if="判断条件"作为递归组件的结束条件。当遇到v-if为false时,组件将不会再进行渲染

    1. 准备一个树状的递归数据  这里演示一个侧边栏组件

    navigation: [
            {
              types: 1,
              id: "0",
              name: "首页",
              path: "/jiaowu_system/home",
              icon: "icon_hrIndex.png",
              children: []
            },
            {
              types: 1,
              id: "1",
              name: "教学资源",
              path: "",
              icon: "jiaowu_system_jiaoxueziyuan.png",
              children: [
                {
                  types: 2,
                  id: "1 - 1",
                  name: "学校信息",
                  path: "/jiaowu_system/SchoolInformation",
                  icon: "",
                  children: []
                },
                {
                  types: 2,
                  id: "1 - 2",
                  name: "管理部门信息",
                  path: "/jiaowu_system/administration",
                  icon: "",
                  children: []
                }
              ]
            },
            {
              types: 1,
              id: "2",
              name: "教学计划",
              path: "",
              icon: "jiaowu_system_jihua.png",
              children: []
            }
    ]

    2. 创建一个简单的递归组件 

     // 这里 我是通过name实现递归效果的 你可以把它当作从import导入了一个组件并注册,我们在temlpate可以使用<list-menu></list-menu>使用子组件自身进行递归了   默认不展示子组件,只能在父组件点击的时候才会展示 使用的 v-show  减少渲染消耗

    <template>
      <div class="list">
        <div @click.prevent="handleClick">
          {{ model.name }}
        </div>
        <div v-show="reveal" v-if="isDispaly" style="margin-left:20px;">
          <list-menu v-for="item in model.children" :key="item.id" :model="item" />
        </div>
      </div>
    </template>
    
    <script>
    export default {
      name: "listMenu",
      components: {},
      props: ["model"],
      data() {
        return {
          reveal: false
        };
      },
      methods: {
        handleClick() {
          if (this.isDispaly) {
            this.reveal = !this.reveal;
          }
        }
      },
      computed: {
        isDispaly() {
          return this.model.children && this.model.children.length;
        }
      }
    };
    </script>
    
    <style scoped>
    div {
       100px;
      margin: 20px 0;
    }
    </style>

    上述代码中我们需要注意,这个组件必须含有 name 这个属性,因为没有 name 这个属性会造成控件自身不能调用自身, 当使用它时,只需要把上边我们定义好的数据通过props的方式传进去即可

    3. 我们创建一个sidebar组件,这个组件作为使用递归组件的父组件 

      // navigation的数据在上面 需要copy 

    <template>
      <div class="sidebar">
        <div v-for="menu in navigation" :key="menu.id">
          <list-menu :model="menu"></list-menu>
        </div>
      </div>
    </template>
    
    <script>
    import listMenu from "./list";
    export default {
      name: "sidebar",
      components: {
        listMenu
      },
      props: {},
      data() {
        return {
          navigation: [] // 数据太长 就不在这里面写了
        };
      }
    };
    </script>

      好了 我们就实现了一个简单的递归侧边栏组件,这段代码只是简单的做了下递归组件的使用。对于折叠树状菜单来说,我们一般只会去渲染一级的数据,当点击一级菜单时,再去渲染一级菜单下的结构,如此往复。那么v-if就可以实现我们的这个需求,当v-if设置为false时,递归组件将不会再进行渲染,设置为true时,继续渲染。组件中的name不仅可以递归的时候使用 还可以当项目使用keep-alive时,可搭配组件name进行缓存过滤

    一个简单的小实例

    <div id="app"> 
        <keep-alive exclude="Detail">
            <router-view/>
        </keep-alive>
    </div>
  • 相关阅读:
    获取文件mime类型
    PHP的CURL
    PHP curl报错“Problem (2) in the Chunked-Encoded data”解决方案
    MySQL中的group_concat函数
    MYSQL批量修改表前缀与表名sql语句
    ubuntu18.04 无法连接有线
    ffmpeg接收udp输入的h264文件流,推流到rtmp服务器
    nginx-rtmp
    tf.image.crop_and_resize
    tf.reduce_sum
  • 原文地址:https://www.cnblogs.com/dachengzizi/p/12132966.html
Copyright © 2011-2022 走看看