目标
请在 js/store.js
与 components
文件夹下两个组件中补全代码,最终实现可以从英雄列表中选择英雄,建立一支属于自己的队伍的功能。
具体需求如下:
1. 完成可选英雄的渲染
所有英雄的信息存放于 js/heroes.json
中,请在 components/HeroList.js
组件中使用 axios
发送请求(请求地址写死为 ./js/heroes.json
,以免影响检测通过)获取到英雄信息,将其保存至 js/store.js
的 heroes
数组中,并将所有英雄渲染在“可选英雄”列表中(每条英雄信息是一个 li
标签,需要生成对应英雄数量的 li
标签作为子元素插入到 .hero-list ul
中)。
对 js/heroes.json
中英雄信息的解释: js/heroes.json
中存放了每个英雄的信息,以下述信息为例,其中 id
是序号,name
是英雄姓名,ability
是英雄的能力,strength
是英雄的强度。
{ id: 1, name: "绯红女巫", ability: "混沌魔法", strength: 98 }
用于展示可选英雄的 li
标签的 DOM 结构如下:
<li class="hero-item">
<span>name</span>
<span>ability</span>
<span>strength</span>
<button>添加至队伍/已添加</button>
</li>
最终完成效果如下:
2. 实现“添加英雄”功能
在需求 1 实现的基础上,当点击可选英雄左侧的“添加至队伍”按钮时,该按钮文本变为“已添加”,按钮变为禁用状态(按钮的 disabled
属性变为 false
),并且将当前被选择的英雄的信息添加至页面右侧“我的队伍”列表中(英雄信息是一个 li
标签,生成对应结构的 li
标签作为子元素插入到 .team-list ul
中)。
用于展示已选英雄的 li
标签的 DOM 结构如下:
<li class="team-item">
<span>name</span>
<span>strength</span>
<button>移除</button>
</li>
3. 实现“移除英雄”功能
在需求 2 实现的基础上,当点击已选英雄左侧“移除”按钮(.sort-button
)时,该英雄从“我的队伍”列表中被移除,“可选英雄”列表中该英雄左侧“已添加”按钮文本变回“添加至队伍”,且按钮变为可用状态(按钮的 disabled
属性变为 true
)。
4. 实现“按实力排序”功能
在需求 2 实现的基础上,当点击“按实力排序”按钮(.sort-button
)时,将“我的队伍”中的英雄按照英雄强度降序排列。
5. 实现实时显示队伍战斗力功能
在需求 2 、3 实现的基础上,.total-strength
中应实时显示当前队伍的战斗力,即“我的队伍”中所有英雄的强度之和。
最终完成效果如下:
说明:
-
页面中共有 3 个组件,分别是
app
根组件,hero
组件和team
组件,其中后两个组件一直作为app
根组件的子组件出现。而上文中对“可选英雄列表”和“我的队伍列表”的描述分别指hero
组件与team
组件。 -
游戏中的人物数据会有很多界面/组件共享,所以需要存储在
pinia
状态管理器中,减少了程序花销也避免了同步问题。
目标一
HeroList.js
store.js
const { defineStore } = Pinia;
const { ref } = Vue;
const useHeroStore = defineStore("hero", {
state: () => ({
heroes: [], //英雄列表
team: [], // 队伍列表
}),
// TODO:补全代码,实现目标效果
getters: {},
actions: {},
// TODOEnd
});
// TODO:补全代码,实现目标效果
// {{herolist.heroes}}
const HeroList = {
template: `
<div class="hero-list">
<h2>可选英雄</h2>
<ul>
<li class="hero-item" v-for="item in heroList.heroes">
<span>{{item.name}}</span>
<span>{{item.ability}}</span>
<span>{{item.strength}}</span>
<button>添加至队伍</button>
</li>
</ul>
</div>
`,
setup() {
const heroList=useHeroStore();
axios.get("./js/heroes.json").then(res=>{
heroList.heroes=res.data
})
return {
heroList
}
},
};
// TODOEnd
目标二,三
HeroList.js
<button :disabled="item.inTeam" @click="addItem(item)">{{item.inTeam ? '已添加' : '添加至队伍'}}</button>
setup() {
const heroList=useHeroStore();
axios.get("./js/heroes.json").then(res=>{
heroList.heroes=res.data
})
function addItem(item){
console.log(item);
item.inTeam=true
// disabled=false
heroList.team.push(item)
console.log(heroList.team);
}
return {
heroList,
addItem
}
},
TeamList.js
// TODO:补全代码,实现目标效果
const TeamList = {
template: `
<div class="team-list">
<h2>我的队伍</h2>
<ul>
<li class="team-item" v-for="item in heroList.team">
<span>{{item.name}}</span>
<span>{{item.strength}}</span>
<button @click="removeItem(item)">移除</button>
</li>
</ul>
<button class="sort-button">按实力排序</button>
<p class="total-strength">当前队伍战斗力:0 </p>
</div>
`,
setup() {
const heroList=useHeroStore();
function removeItem(item){
heroList.team.pop(item)
item.inTeam=false
console.log(item);
}
return{
heroList,
removeItem
}
},
};
// TODOEnd