最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue組件化開發(fā)的必備技能之組件遞歸

 更新時間:2022年01月29日 10:46:34   作者:前端阿飛  
組件是可以在它們自己的模板中調(diào)用自身的,不過它們只能通過?name?選項來做這件事,下面這篇文章主要給大家介紹了關(guān)于Vue組件化開發(fā)的必備技能之組件遞歸的相關(guān)資料,需要的朋友可以參考下

前言

不知道大家有沒遇到過這樣的場景:渲染列表數(shù)據(jù)的時候,列表的子項還是列表。如果層級少尚且可以用幾個for循環(huán)搞定,但是層級多或者層級不確定就有點(diǎn)無從下手了。

其實這就是樹形結(jié)構(gòu)數(shù)據(jù),像常見的組織架構(gòu)圖,文件夾目錄,導(dǎo)航菜單等都屬于這種結(jié)構(gòu)。很多組件庫都帶有樹形組件,但往往樣式不是我們想要的,改起來也非常的費(fèi)勁。那么,如何自己渲染這些數(shù)據(jù)呢?答案就是——組件遞歸!

效果展示

以上就是使用組件遞歸,并加入簡單交互的展示效果。點(diǎn)擊節(jié)點(diǎn)會在控制臺輸出節(jié)點(diǎn)對應(yīng)的數(shù)據(jù),如果有子節(jié)點(diǎn),則會展開或收起子節(jié)點(diǎn)。接下來我們就看看如何實現(xiàn)以上效果吧!

渲染完整數(shù)據(jù)

渲染數(shù)據(jù)這一步非常簡單,首先是把樹形結(jié)構(gòu)封裝成一個列表組件,其次判斷每一項有沒有子節(jié)點(diǎn),如果有子節(jié)點(diǎn),再使用自身組件去渲染就可以了。

src/components/myTree.vue

<template>
  <div class="tree-item">
    <div v-for="item in treeData" :key="item.id">
      <div class="item-title">{{ item.name }}</div>
      <div v-if="item.children && item.children.length" class="item-childen">
        <my-tree :treeData="item.children"></my-tree>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'myTree',
  props: {
    treeData: {
      type: Array,
      default: () => []
    }
  }
}
</script>

<style lang="scss" scoped>
.tree-item {
  .item-title {
    padding: 4px 8px;
  }
  .item-childen {
    padding-left: 20px;
  }
}
</style>

src/App.vue

<template>
  <my-tree :tree-data="treeData"></my-tree>
</template>

<script>
const treeData = [
  { id: 1, name: '一級1' },
  {
    id: 2,
    name: '一級2',
    children: [
      { id: 3, name: '二級2-1' },
      { id: 4, name: '二級2-2' }
    ]
  },
  {
    id: 5,
    name: '一級3',
    children: [
      {
        id: 6,
        name: '二級3-1',
        children: [
          { id: 7, name: '三級3-1-1' },
          { id: 8, name: '三級3-1-2' }
        ]
      },
      { id: 9, name: '二級3-2' },
      { id: 10, name: '二級3-3' }
    ]
  }
]
import myTree from '@/components/myTree.vue'
export default {
  components: {
    myTree
  },
  data() {
    return {
      treeData: treeData
    }
  }
}
</script>

效果如下

獲取節(jié)點(diǎn)數(shù)據(jù)

接下來我們要做的是,點(diǎn)擊節(jié)點(diǎn)時在控制臺輸出對應(yīng)的數(shù)據(jù)。首先我們使用 $emit,將一級節(jié)點(diǎn)的 item 傳遞出去,也就是子傳父的方法,相信大家都會。

其次是將內(nèi)層節(jié)點(diǎn)的數(shù)據(jù)傳遞出去,同樣使用子傳父的方法,只是我們需要給組件里面的 my-tree 綁定@node-click="$emit('node-click', $event)",這樣每次子級每次都可以調(diào)用父級的 node-click 方法,父級又調(diào)用它的父級 node-click 方法,最終調(diào)的都是最外層的 node-click 方法,我們只需要在這個過程中,把數(shù)據(jù)傳遞過去就可以了。這塊有點(diǎn)繞,相信大家多看幾遍應(yīng)該可以看懂。修改如下:

src/components/myTree.vue

<div class="item-title" @click="itemNodeClick(item)">{{ item.name }}</div>
<div v-if="item.children && item.children.length" class="item-childen">
  <my-tree
    :treeData="item.children"
    @node-click="$emit('node-click', $event)"
  ></my-tree>
</div>
...
itemNodeClick(item) {
  this.$emit("node-click", item)
}

src/App.vue

<my-tree :tree-data="treeData" @node-click="nodeClick"></my-tree>
...
nodeClick(val) {
  console.log(val)
}

效果如下

動態(tài)展開收起

這一步的思路是給組件設(shè)置一個數(shù)組,數(shù)組中存放的是當(dāng)前列表中需要展開的節(jié)點(diǎn)的id,當(dāng)點(diǎn)擊節(jié)點(diǎn)的時候添加或刪除節(jié)點(diǎn)id,然后判斷每個節(jié)點(diǎn)的id在不在這個數(shù)組,在則顯示子節(jié)點(diǎn),不在則隱藏子節(jié)點(diǎn)。

src/components/myTree.vue

<div class="item-title" @click="nodeClick(item)">
  <span>{{ item.name }}</span>
  <span v-if="item.children && item.children.length">
    [{{ isOpen(item.id) ? '-' : '+' }}]
  </span>
</div>
<div
  v-if="item.children && item.children.length"
  v-show="isOpen(item.id)"
  class="item-childen"
>
  <my-tree
    :treeData="item.children"
    @node-click="$emit('node-click', $event)"
  ></my-tree>
</div>
...
data() {
  return {
    expandedKeys: [] // 當(dāng)前列表需要展開的節(jié)點(diǎn)id組成的數(shù)組
  }
},
methods: {
  nodeClick(item) {
    this.$emit('node-click', item)
    if (item.children && item.children.length) {
      let index = this.expandedKeys.indexOf(item.id)
      if (index > -1) {
        // 如果當(dāng)前節(jié)點(diǎn)id存在數(shù)組中,則刪除
        this.expandedKeys.splice(index, 1)
      } else {
        // 如果當(dāng)前節(jié)點(diǎn)id不存在數(shù)組中,則添加
        this.expandedKeys.push(item.id)
      }
    }
  },
  isOpen(id) {
    // 判斷節(jié)點(diǎn)id在不在數(shù)組中,在則顯示,不在則隱藏
    return this.expandedKeys.includes(id)
  }
}

效果如下

最后我們再添加一些樣式,就大功告成啦!

完整代碼

src/components/myTree.vue

<template>
  <div class="tree-item">
    <div v-for="item in treeData" :key="item.id">
      <div class="item-title" @click="nodeClick(item)">
        <span>{{ item.name }}</span>
        <span v-if="item.children && item.children.length">
          [{{ isOpen(item.id) ? '-' : '+' }}]
        </span>
      </div>
      <div
        v-if="item.children && item.children.length"
        v-show="isOpen(item.id)"
        class="item-childen"
      >
        <my-tree
          :treeData="item.children"
          @node-click="$emit('node-click', $event)"
        ></my-tree>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'myTree',
  props: {
    treeData: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      expandedKeys: [] // 當(dāng)前展開的節(jié)點(diǎn)id組成的數(shù)組
    }
  },
  methods: {
    nodeClick(item) {
      this.$emit('node-click', item)
      if (item.children && item.children.length) {
        let index = this.expandedKeys.indexOf(item.id)
        if (index > -1) {
          // 如果當(dāng)前節(jié)點(diǎn)id存在數(shù)組中,則刪除
          this.expandedKeys.splice(index, 1)
        } else {
          // 如果當(dāng)前節(jié)點(diǎn)id不存在數(shù)組中,則添加
          this.expandedKeys.push(item.id)
        }
      }
    },
    isOpen(id) {
      // 判斷節(jié)點(diǎn)id在不在數(shù)組中,在則顯示,不在則隱藏
      return this.expandedKeys.includes(id)
    }
  }
}
</script>

<style lang="scss" scoped>
.tree-item {
  cursor: pointer;
  .item-title {
    padding: 4px 8px;
    &:hover {
      background: #eee;
    }
  }
  .item-childen {
    padding-left: 20px;
  }
}
</style>

src/App.vue

<template>
  <my-tree :tree-data="treeData" @node-click="nodeClick"></my-tree>
</template>

<script>
const treeData = [
  { id: 1, name: '一級1' },
  {
    id: 2,
    name: '一級2',
    children: [
      { id: 3, name: '二級2-1' },
      { id: 4, name: '二級2-2' }
    ]
  },
  {
    id: 5,
    name: '一級3',
    children: [
      {
        id: 6,
        name: '二級3-1',
        children: [
          { id: 7, name: '三級3-1-1' },
          { id: 8, name: '三級3-1-2' }
        ]
      },
      { id: 9, name: '二級3-2' },
      { id: 10, name: '二級3-3' }
    ]
  }
]
import myTree from '@/components/myTree.vue'
export default {
  components: {
    myTree
  },
  data() {
    return {
      treeData: treeData
    }
  },
  methods: {
    nodeClick(val) {
      console.log(val)
    }
  }
}
</script>

效果如下

以上就是今天的分享!有興趣的小伙伴可以動手試一哈,把組件進(jìn)一步封裝,或修改成自己想要的樣式。 Vue官方的樹形視圖:cn.vuejs.org/v2/examples…

總結(jié)

到此這篇關(guān)于Vue組件化開發(fā)的必備技能之組件遞歸的文章就介紹到這了,更多相關(guān)Vue組件遞歸內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 基于Vue3和Element Plus實現(xiàn)自動導(dǎo)入功能

    基于Vue3和Element Plus實現(xiàn)自動導(dǎo)入功能

    在 Vue 3 項目中,結(jié)合  Element Plus  實現(xiàn)自動導(dǎo)入可以顯著減少代碼量,提升開發(fā)效率,Element Plus 提供了官方的自動導(dǎo)入插件  unplugin-vue-components  和  unplugin-auto-import,以下是如何配置和使用的詳細(xì)步驟,需要的朋友可以參考下
    2025-03-03
  • Vue中通過屬性綁定為元素綁定style行內(nèi)樣式的實例代碼

    Vue中通過屬性綁定為元素綁定style行內(nèi)樣式的實例代碼

    這篇文章主要介紹了Vue中通過屬性綁定為元素綁定style行內(nèi)樣式,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-04-04
  • vue3中使用百度地圖的簡單步驟

    vue3中使用百度地圖的簡單步驟

    最近項目要用到百度地圖api,好久沒用到地圖,就百度了一番,下面這篇文章主要給大家介紹了關(guān)于vue3中使用百度地圖的簡單步驟,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-06-06
  • vue定時器設(shè)置和關(guān)閉頁面時關(guān)閉定時器方式

    vue定時器設(shè)置和關(guān)閉頁面時關(guān)閉定時器方式

    這篇文章主要介紹了vue定時器設(shè)置和關(guān)閉頁面時關(guān)閉定時器方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • vue+element項目實時監(jiān)聽div寬度的變化

    vue+element項目實時監(jiān)聽div寬度的變化

    這篇文章主要介紹了vue+element項目里實時監(jiān)聽某個div寬度的變化,然后執(zhí)行相應(yīng)的事件,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧
    2024-08-08
  • Vue2項目中對百度地圖的封裝使用詳解

    Vue2項目中對百度地圖的封裝使用詳解

    近期項目需求相關(guān)地圖限定使用百度地圖,功能比較簡單,下面這篇文章主要給大家介紹了關(guān)于Vue2項目中對百度地圖的封裝使用的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • 前端vue項目如何使用Decimal.js做加減乘除求余運(yùn)算

    前端vue項目如何使用Decimal.js做加減乘除求余運(yùn)算

    decimal.js是使用的二進(jìn)制來計算的,可以更好地實現(xiàn)格化式數(shù)學(xué)運(yùn)算,對數(shù)字進(jìn)行高精度處理,使用decimal類型處理數(shù)據(jù)可以保證數(shù)據(jù)計算更為精確,這篇文章主要給大家介紹了關(guān)于前端vue項目如何使用Decimal.js做加減乘除求余運(yùn)算的相關(guān)資料,需要的朋友可以參考下
    2024-05-05
  • Vue彈窗的兩種實現(xiàn)方式實例詳解

    Vue彈窗的兩種實現(xiàn)方式實例詳解

    這篇文章主要介紹了Vue彈窗的兩種實現(xiàn)方式,一種使用.sync修飾符另一種使用v-model,本文通過實例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • vue開發(fā)拖拽進(jìn)度條滑動組件

    vue開發(fā)拖拽進(jìn)度條滑動組件

    這篇文章主要為大家詳細(xì)介紹了vue開發(fā)拖拽進(jìn)度條滑動組件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • 如何設(shè)置Vue全局公共方法

    如何設(shè)置Vue全局公共方法

    這篇文章主要介紹了如何設(shè)置Vue全局公共方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05

最新評論

河曲县| 安泽县| 内黄县| 大悟县| 赣榆县| 三亚市| 大田县| 本溪市| 工布江达县| 兴国县| 山西省| 元谋县| 寿阳县| 华坪县| 克山县| 南雄市| 商都县| 洛川县| 北海市| 鹿泉市| 资溪县| 西和县| 偃师市| 小金县| 阿克陶县| 佛山市| 石棉县| 图木舒克市| 边坝县| 秦皇岛市| 星座| 长泰县| 临桂县| 华池县| 务川| 鞍山市| 镇平县| 余姚市| 荆州市| 于都县| 视频|