我想创建一个包含多个按钮组的网页。现有代码是
$(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>