首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在vue中用条件模板分隔开结束标记而不产生编译错误?

如何在vue中用条件模板分隔开结束标记而不产生编译错误?
EN

Stack Overflow用户
提问于 2017-09-10 15:19:53
回答 3查看 8.2K关注 0票数 6

我试图做一些条件模板,在这里,我必须分开一些元素的开始和结束标记。但是,直到它们处于相同的条件模板标记中,才能使其工作。一旦我将开始标记放置到一个条件模板,将结束标记放置到另一个条件模板,我就会得到一个错误。例如:

代码语言:javascript
复制
<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="..">标记中。我知道这个错误:

代码语言:javascript
复制
(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.

如何在不破坏代码的情况下分离条件模板标记中的任何起始标记和结束标记?

编辑以添加完整代码

这是我想要用来生成菜单的路线。

代码语言:javascript
复制
// 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
}
];

这是递归组件的父级。

代码语言:javascript
复制
// 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>

这是问题反复出现的部分。

代码语言:javascript
复制
// 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>

全误差输出

代码语言:javascript
复制
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
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-09-12 07:19:27

好吧,我找不到为什么我得到"-标签没有匹配的结束标签“错误。但是毫无疑问,它应该工作,因为@RoyJ用条件()呈现显示了分隔标记。我的猜测是,当多个递归发生时,会在不同的作用域中创建(分离)一些打开和结束标记,因为每个递归都像一个新组件一样开始。因此,vue无法在相应的作用域中找到相关的结束标记,并抛出该错误。

我的解决办法是不要将结束标记与起始标记分开。相反,我创建了一个额外的组件,我将其放置在主循环中,进入该组件后,我将关闭标记,而不需要附加的条件渲染。新组件处理其余的递归。我同意这件事,但要注意这个问题。感谢所有的帮助努力。

这是我的解决办法:

代码语言:javascript
复制
// 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>

我从这个部分中删除了递归,正如我所说的,在一个模板标记中关闭了标记,而没有将它们分开。

代码语言:javascript
复制
// 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>

这是我告诉过的新组件。这是现在反复出现的部分。

代码语言:javascript
复制
// 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>
票数 0
EN

Stack Overflow用户

发布于 2017-09-10 17:31:53

这对我来说真的很好。使用模板是规避合法的HTML限制的一种推荐方法。你能做一个能展示问题的片段吗?然后说你在哪个平台上运行它,以防万一它依赖于平台?

代码语言:javascript
复制
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
  }
});
代码语言:javascript
复制
<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>

票数 1
EN

Stack Overflow用户

发布于 2017-09-10 15:58:56

根据html标准,vue编译器将检查是否有适当的元素打开和结束标记。在您的示例中,开始标记<ul>没有得到正确处理。

您可以将代码更新为折叠。

代码语言:javascript
复制
<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>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46142300

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档