我想创建一个包含多个按钮组的网页。现有代码是

$(document).ready(function() {
  $(".nav-link").click(function() {
      console.log(this);
  });
});

Vue.component('nav-bar', {
    props: ['navs'],
    template: `<ul class="nav">
        <li v-for="nav in [{id: 0, text: 'Vege'}, {id:1, text: 'Ch'}]"
            v-bind:item="nav"
            v-bind:key="nav.id">
                <a class="nav-link" v-on:click="setactive($event)">{{ nav.text }}</a></li>
    </ul>`,
    methods: {
        setactive: function(event) {
            $(event.target).closest('ul').find('a.active').removeClass('active');
            $(event.target).addClass('active');
        },
    created: function() {
        $(this).find('a').first().addClass('active');
    }
    }
});

var app = new Vue({
    el: '#app',
    data: {
        navs: [
            { id: 0, text: 'Vegetables' },
            { id: 1, text: 'Cheese' },
            { id: 2, text: 'Milk' }
        ]
    }
});

.nav {
    display: flex;
    flex-wrap: wrap;
    list-style: none;
}
.nav-link.active {
    color: #fff;
    background-color: #007bff;
}
.nav-link {
    color: #4183c4;
    text-decoration: none;
    background-color: transparent;
    border-radius: .25rem;
    padding: .5rem 1rem;
}

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="app">
    <nav-bar></nav-bar>
</div>

我的问题是:
如果将<li v-for="nav in [{id: 0, text: 'Vege'}, {id:1, text: 'Ch'}]"更改为<li v-for="nav in navs",则根本不显示任何内容。怎么了?
为什么第一个项的类在创建时没有设置为active
如何将导航项直接提供给<nav-bar>
我不想使用bootstrap按钮组。

最佳答案

如果将<li v-for="nav in [{id: 0, text: 'Vege'}, {id:1, text: 'Ch'}]"更改为<li v-for="nav in navs",则根本不显示任何内容。怎么了?
这取决于navs的值。我们需要查看准确的代码来进行故障排除。
如何将导航项直接提供给<nav-bar>
要将navs的值从App传递到<nav-bar>,请使用v-bind

<div id="app">
  <nav-bar v-bind:navs="navs" />

  <!-- OR shorthand for v-bind -->
  <nav-bar :navs="navs" />
</div>

为什么第一个项的类在创建时没有设置为active
DOM尚未在created生命周期挂钩中标记,因此jQuery无法找到要设置为活动的元素。由于要查询的元素是动态添加的(通过navs属性),因此必须:
等待navs属性更改(而不是使用生命周期挂钩)。为此使用watcher
Vue.component('nav-bar', {
  watch: {
    navs: {
      handler() { /* SEE NEXT STEP */ },
      immediate: true, // call handler immediately in case `navs` data is already available
    }
  }
})

等到元素在$nextTick中添加到DOM。
// in watch:
handler() {
  this.$nextTick(() => {
    $(this).find('a').first().addClass('active');
  });
},

Vue.component('nav-bar', {
  props: ['navs'],
  template: `<ul class="nav" ref="list">
        <li v-for="nav in navs"
            v-bind:item="nav"
            v-bind:key="nav.id">
          <a class="nav-link" v-on:click="setactive($event)">{{ nav.text }}</a>
        </li>
      </ul>`,
  methods: {
    setactive: function(event) {
      $(event.target).closest('ul').find('a.active').removeClass('active');
      $(event.target).addClass('active');
    },
  },
  watch: {
    navs: {
      immediate: true,
      handler() {
        this.$nextTick(() => {
          $(this.$refs.list).find('a').first().addClass('active');
        });
      }
    }
  }
});

var app = new Vue({
  el: '#app',
  data: {
    navs: [{
        id: 0,
        text: 'Vegetables'
      },
      {
        id: 1,
        text: 'Cheese'
      },
      {
        id: 2,
        text: 'Milk'
      }
    ]
  }
});

.nav {
  display: flex;
  flex-wrap: wrap;
  list-style: none;
}

.nav-link.active {
  color: #fff;
  background-color: #007bff;
}

.nav-link {
  color: #4183c4;
  text-decoration: none;
  background-color: transparent;
  border-radius: .25rem;
  padding: .5rem 1rem;
}

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="app">
  <nav-bar :navs="navs"></nav-bar>
</div>

09-16 18:33