data.json

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

    right.pngdata.json