在一个组件模板中调用这个组件本身

right.pngdata.json

  1. <style>
  2. img{
  3. width: 12px;
  4. opacity: 0.5;
  5. }
  6. img.active{
  7. transform: rotate(90deg);
  8. opacity: 1;
  9. }
  10. ul{
  11. overflow: hidden;
  12. margin: 0;
  13. }
  14. /* 子列表展开闭合动画 */
  15. .v-enter, .v-leave-to{
  16. max-height: 0;
  17. }
  18. .v-enter-active, .v-leave-active{
  19. transition: 1s;
  20. }
  21. .v-enter-to, .v-leave{
  22. max-height: 200px;
  23. }
  24. </style>
  25. <body>
  26. <script src='https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js'></script>
  27. <div id='myApp'>
  28. <h1>递归组件</h1>
  29. <my-com v-for="item in list" :data="item" :key="item.title"></my-com>
  30. </div>
  31. <!-- 组件模板 -->
  32. <template id='myTem'>
  33. <div>
  34. <img
  35. @click="open=!open"
  36. :class="open? 'active': ''"
  37. src="./right.png"
  38. v-if="data.list.length"
  39. >
  40. <b @click="open=!open">
  41. {{data.title}}
  42. <span v-if="data.list.length">({{data.list.length}})</span>
  43. </b>
  44. <transition>
  45. <ul v-if='open'>
  46. <!-- 递归组件: 在一个组件模板中调用这个组件本身 -->
  47. <li v-for="item in data.list" is="my-com" :data="item" :key="item.title"></li>
  48. </ul>
  49. </transition>
  50. </div>
  51. </template>
  52. <script>
  53. Vue.component('myCom', {
  54. template: '#myTem',
  55. props: ["data"],
  56. data(){return { open: false }}
  57. })
  58. new Vue({
  59. el: '#myApp',
  60. data: {
  61. list: []
  62. },
  63. created() {
  64. fetch("./data.json").then(res=>{
  65. return res.json()
  66. }).then(res=>{
  67. this.list = res
  68. })
  69. },
  70. })
  71. </script>
  72. </body>