programing

컴파일 오류가 발생하지 않고 vue에서 조건부 템플릿별로 열기 및 닫기 태그를 구분하는 방법은 무엇입니까?

procenter 2022. 12. 9. 22:20
반응형

컴파일 오류가 발생하지 않고 vue에서 조건부 템플릿별로 열기 및 닫기 태그를 구분하는 방법은 무엇입니까?

일부 요소의 열기 태그와 닫기 태그를 분리해야 하는 조건부 템플릿을 시도하고 있습니다.그러나 동일한 조건부 템플릿 태그가 있어야 작동합니다.하나의 조건부 템플릿에 시작 태그를 붙이고 다른 조건부 템플릿에 닫는 태그를 붙이면 오류가 발생합니다.예를 들어 다음과 같습니다.

<template>
    <div>
        <template v-if="show">
            <ul>
                <li>
                    one
                </li>
        </template>

        // OTHER CONDITIONAL STUFF IN BETWEEN

        <template v-if="show">
                <li>
                    two
                </li>
            </ul>
        </template>
    </div>  
</template>

<script>
export default {
    data() {
        return {
            show: false
        }
    }
}
</script>

여기서 오류가 발생하는 이유는 오프닝이<ul>태그 앤 클로즈</ul>태그는 이산형입니다.<template v-if="..">태그. 다음 오류가 나타납니다.

(Emitted value instead of an instance of Error) 
  Error compiling template:

    <div>

  <template v-if="show">
      <ul>
          <li>
              one
          </li>
  </template>

  <template v-if="show">
          <li>
              two
          </li>
      </ul>
  </template>

    </div>  

  - tag <ul> has no matching end tag.

어떻게 하면 코드를 끊지 않고 조건부 템플릿 태그 내에서 시작 태그와 종료 태그를 분리할 수 있습니까?


전체 코드를 추가하기 위해 편집됨

이것은 메뉴를 생성하기 위해 사용하는 경로입니다.

// routers.js
export let routers = [
{
    name: 'Main Menu 1',
    parent: 0,
}, {
    name: 'Main Menu 2',
    parent: 0
    children: [
        {
            name: 'Menu Item 1-1'
        },{    
            name: 'Menu Item 1-2',
            children: [
                {    
                    name: 'Menu Item 2-1',
                },{    
                    name: 'Menu Item 2-2',
                },{    
                    name: 'Menu Item 2-3',
                    children: [{
                        name: 'SHIT'
                    }]
                }
            ]
        }
    ]
}, {
    name: 'Main Menu 3',
    parent: 0
}
];

이것은 재귀 구성 요소의 부모입니다.

// left-side.vue
<template>
    <aside class="left-side sidebar-offcanvas">
        <section class="sidebar">
            <div id="menu" role="navigation">
                <navigation-cmp :routes="routes"></navigation-cmp>
            </div>
        </section>
    </aside>
</template>

<script>
import navigationCmp from './navigationCmp';

import {routers} from '../../router/routers';

export default {
    name: "left-side",
    computed: {
        routes(){
            return routers;
        }
    },
    components: {
        navigationCmp,
    },
}
</script>

이것은 문제가 재발하는 부품입니다.

// navigationCmp.vue
<template>
    <ul class="navigation">

        <template v-for="item in routes">

            <template v-if="item.parent == 0">
                <template v-if="!!item.children">
                    <li class="menu-dropdown">
                        <a href="javascript:void(0)"> 
                            <i class="menu-icon ti-check-box"></i> 
                            <span class="mm-text">{{ item.name }}</span> 
                            <span class="fa arrow"></span> 
                        </a>
                        <ul class="sub-menu">
                </template>
                <template v-if="!item.children">
                    <router-link to="/" tag="li" exact>
                        <a class="logo"><i class="menu-icon ti-desktop"></i><span class="mm-text">{{ item.name }}</span></a>
                    </router-link>                    
                </template>
            </template>

            <template v-if="!!item.children" v-for="child in item.children" >
                <template v-if="!!child.children">
                    <a href="javascript:void(0)">
                        <i class="fa fa-fw ti-receipt"></i> {{ child.name }}
                        <span class="fa arrow"></span>
                    </a>
                    <ul class="sub-menu form-submenu">
                </template>
                <template v-if="!child.cildren">
                    <router-link tag="li" to="/form-elements" exact>
                        <a class="logo"><i class="menu-icon ti-cup"></i><span class="mm-text"> {{ child.name }} </span></a>
                    </router-link>
                </template>

                <navigation-cmp v-if='!!child.children&&child.children.length>0' :routes='[child]'> </navigation-cmp>

                <template v-if="!!child.children">
                    </ul>
                </template>

            </template>


            <template v-if="!!item.children&&item.parent==0">
                        </ul>
                    </li>
            </template>

        </template>

    </ul>
</template>

<script>
export default {
    name: 'navigation-cmp',
    props: {
        routes: Array,
    }
}
</script>

완전 오류 출력

main.js:43552 [WDS] Errors while compiling. Reload prevented.
main.js:43558 ./~/vue-loader/lib/template-compiler?{"id":"data-v-dfd6e000"}!./~/vue-loader/lib/selector.js?type=template&index=0!./src/components/layout/navigationCmp.vue
(Emitted value instead of an instance of Error) 
  Error compiling template:

  <ul class="navigation">

      <template v-if="!item.hidden" v-for="item in routes">

          <template v-if="item.parent == 0">
              <template v-if="show">
                  <li class="menu-dropdown">
                      <a href="javascript:void(0)"> 
                          <i class="menu-icon ti-check-box"></i> 
                          <span class="mm-text">{{ item.name }}</span> 
                          <span class="fa arrow"></span> 
                      </a>
                      <!-- <ul class="sub-menu"> -->
              </template>
              <template v-if="!item.children">
                  <router-link to="/" tag="li" exact>
                      <a class="logo"><i class="menu-icon ti-desktop"></i><span class="mm-text">{{ item.name }}</span></a>
                  </router-link>                    
              </template>
          </template>

                  </li>



          <!-- <template v-if="!!item.children&&item.parent == 0"> -->
                      <!-- </ul> -->
          <!-- </template> -->

      </template>

  </ul>

  - tag <li> has no matching end tag.

 @ ./src/components/layout/navigationCmp.vue 5:2-192
 @ ./~/babel-loader/lib?cacheDirectory!./~/vue-loader/lib/selector.js?type=script&index=0!./src/components/layout/left-side.vue
 @ ./src/components/layout/left-side.vue
 @ ./~/babel-loader/lib?cacheDirectory!./~/vue-loader/lib/selector.js?type=script&index=0!./src/components/layout/layout.vue
 @ ./src/components/layout/layout.vue
 @ ./src/router/routes.js
 @ ./src/router/router.js
 @ ./src/main.js
 @ multi (webpack)-dev-server/client?http://localhost:8080 webpack/hot/dev-server ./src/main.js
errors  @   main.js:43558
sock.onmessage  @   main.js:43801
./node_modules/sockjs-client/lib/event/eventtarget.js.EventTarget.dispatchEvent @   main.js:22579
(anonymous) @   main.js:23332
./node_modules/sockjs-client/lib/main.js.SockJS._transportMessage   @   main.js:23330
./node_modules/sockjs-client/lib/event/emitter.js.EventEmitter.emit @   main.js:22483
WebSocketTransport.ws.onmessage

사실 이건 나한테 잘 먹힌다.템플릿 사용은 법적 HTML 제한을 회피하기 위해 권장되는 방법입니다.문제를 드러내는 스니펫을 만들 수 있습니까?플랫폼에 따라 달라지는 경우를 대비해서 어떤 플랫폼에서 실행하고 있는지 말씀해 주시겠습니까?

var spec = {
  template: '#nav-template',
  props: {
    routes: Array,
  }
};

new Vue({
  el: '#app',
  data: {
    routes: [{
      parent: 0,
      children: 1,
      name: 'first'
    }, {
      parent: 1,
      children: 0,
      name: 'second'
    }]
  },
  components: {
    navigationCmp: spec
  }
});
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
// navigationCmp.vue
<div id="app">
  <aside class="left-side sidebar-offcanvas">
    <section class="sidebar">
      <div id="menu" role="navigation">
        <navigation-cmp :routes="routes"></navigation-cmp>
      </div>
    </section>
  </aside>
</div>

<template id="nav-template">
  <ul class=" navigation ">
    <template v-for="item in routes ">

      <template v-if="item.parent==0 ">
        <template v-if="!!item.children ">
          <li class="menu-dropdown ">
            <a href="javascript:void(0) ">
              <i class="menu-icon ti-check-box "></i>
              <span class="mm-text ">{{ item.name }}</span>
              <span class="fa arrow "></span>
            </a>
            <ul class="sub-menu ">
        </template>
        <template v-if="!item.children ">
          <router-link to="/ " tag="li " exact>
            <a class="logo "><i class="menu-icon ti-desktop "></i><span class="mm-text ">{{ item.name }}</span></a>
          </router-link>
        </template>
      </template>

      <template v-if="!!item.children " v-for="child in item.children ">
        <template v-if="!!child.children ">
          <a href="javascript:void(0) ">
            <i class="fa fa-fw ti-receipt "></i> {{ child.name }}
            <span class="fa arrow "></span>
          </a>
          <ul class="sub-menu form-submenu ">
        </template>
        <template v-if="!child.cildren ">
          <router-link tag="li " to="/form-elements " exact>
            <a class="logo "><i class="menu-icon ti-cup "></i><span class="mm-text "> {{ child.name }} </span></a>
          </router-link>
        </template>

        <navigation-cmp v-if='!!child.children&&child.children.length>0' :routes='[child]'> </navigation-cmp>

        <template v-if="!!child.children ">
          </ul>
        </template>

      </template>


      <template v-if="!!item.children&&item.parent==0 ">
        </ul>
        </li>
      </template>

    </template>

  </ul>
</template>

html 표준에 따라 vue 컴파일러는 태그 열기 및 닫기 요소가 올바른지 확인합니다.당신의 경우 오프닝 태그<ul>적절하게 처리되지 않았습니다.

코드를 폴로 업데이트 할 수 있습니다.

<template>
    <div>
        <template v-if="show">
            <ul>
                <li>
                    one
                </li>
            </ul>
        </template>

        // OTHER CONDITIONAL STUFF IN BETWEEN

        <template v-if="show">
            <ul>
                <li>
                    two
                </li>
            </ul>
        </template>
    </div>  
</template>

<script>
export default {
    data() {
        return {
            show: false
        }
    }
}
</script>

네, "-tag has not matched end tag" 에러가 발생하는 이유를 찾을 수 없었습니다.그러나 @RoyJ가 조건부 () 렌더링을 통해 분리 태그를 보여주었기 때문에 작동해야 한다는 것은 의심의 여지가 없습니다.재귀가 여러 번 발생할 경우 각 재귀가 새로운 컴포넌트와 같이 시작되므로 다른 범위에서 일부 열기 및 닫기 태그가 생성(분리)될 수 있습니다. 따라서 vue는 해당 범위에서 관련 닫힘 태그를 찾을 수 없으며 해당 오류를 발생시킵니다.

회피책은 시작 태그에서 닫힘 태그를 분리하지 않는 것입니다.대신 메인 루프 내에 배치하는 추가 구성요소를 작성하고 해당 구성요소를 입력한 후 추가 조건부 렌더링 없이 태그를 닫습니다.새로운 컴포넌트가 나머지 재발을 처리합니다.저는 이걸로 하겠습니다만, 그 문제를 주시해 주세요.도와주셔서 감사합니다.

회피책은 다음과 같습니다.

// left-side.vue
<template>
    <aside class="left-side sidebar-offcanvas">
        <section class="sidebar">
            <div id="menu" role="navigation">
                <navigation-cmp></navigation-cmp>
            </div>
        </section>
    </aside>
</template>

<script>
import navigationCmp from './navigationCmp';

export default {
    name: "left-side",
    components: {
        navigationCmp,
    },
}
</script>

이 부분에서 재귀를 제거하고 앞서 말한 것처럼 태그를 분리하지 않고 하나의 템플릿 태그로 닫았습니다.

// navigationCmp.vue
<template>
    <ul class="navigation">
        <template v-for="route in routes">

            <li v-if="!!route.children" class="menu-dropdown">
                <a href="javascript:void(0)">
                    <i class="menu-icon ti-check-box"></i>
                    <span class="mm-text">{{ route.name }}</span>
                    <span class="fa arrow"></span>
                </a>
                <ul class="sub-menu">
                    <navigation-sub :route="route"></navigation-sub>
                </ul>
            </li>
            <router-link v-else to="/" tag="li" exact>
                <a class="logo"><i class="menu-icon ti-desktop"></i><span class="mm-text">{{ route.name }}</span></a>
            </router-link>

        </template>
    </ul>
</template>

<script>
import {routers} from '../../router/routers';
import navigationSub from './navigationSub';

export default {
    computed: {
        routes(){
            return routers;
        }
    },
    components: {
        navigationSub
    }
}
</script>

이것은 제가 말씀드린 새로운 부품입니다.이게 반복적인 부분이에요

// navigationSub.vue
<template>
<span>
    <template v-for="child in route.children">
        <li v-if="!!child.children">
            <a href="javascript:void(0)">
                <i class="fa fa-fw ti-receipt"></i> {{ child.name }} 
                <span class="fa arrow"></span>
            </a>
            <ul class="sub-menu form-submenu">
                <navigation-sub :route="child"></navigation-sub>
            </ul>
        </li>
            <a class="logo"><i class="menu-icon ti-cup"></i><span class="mm-text">{{ child.name }}</span></a>
        </router-link>
    </template>
</span>
</template>

<script>
export default {
    name: 'navigation-sub',
    props: ['route']
}
</script>

언급URL : https://stackoverflow.com/questions/46142300/how-to-separate-opening-and-closing-tag-by-conditional-template-in-vue-without-g

반응형