小楼的爸爸是一名程序员,暑假期间,发现小楼在家经常玩手机,于是决定设计一个小游戏让小楼学习成语来加强小楼对成语的理解。 接下来让我们跟着小楼来学学成语吧~
本题已经内置了初始代码,打开实验环境,目录结构如下:
├── index.html
└── js
└── vue.min.js
选中 index.html
右键启动 Web Server 服务(Open with Live Server),让项目运行起来。
接着,打开环境右侧的【Web 服务】,就可以在浏览器中看到如下效果:
完善 index.html
中的 confirm
方法和 getSingleWord
方法。
1.getSingleWord
方法:点击文字后,在变量 idiom
从左到右第一个空的位置加上该文字。
示例一:
idiom=["","","",""],点击热字,则idiom=["热","","",""]
示例二:
idiom=["热","","","眶"],点击泪字,则idiom=["热","泪","","眶"]
示例三:
idiom=["热","泪","盈","眶"],点击任何字,则idiom=["热","泪","盈","眶"]
2.confirm
方法需要校验成语是否输入正确答案,猜中成语 result
为 true
;猜错成语 result
为 false
。
示例一:
tip='形容非常感激或高兴',idiom=["热","泪","盈","眶"],则result返回true
示例二:
tip='形容非常感激或高兴',idiom=["泪","眼","盈","眶"],则result返回false
示例三:
tip='在繁忙中抽出空闲来',idiom=["忙","里","偷","闲"],则result返回true
完成后,最终页面效果如下:
请按照给出的步骤操作,切勿修改默认提供的文件名称、文件夹路径、函数名等。
id
和 class
等属性值及 DOM 结构,以免造成检测失败。<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="./js/vue.min.js"></script>
<title>成语学习</title>
<style>
* {
margin: 0;
padding: 0;
}
#app {
margin: auto;
}
.title {
text-align: center;
padding: 10px 0;
background-image: linear-gradient(-225deg, #69EACB 0%, #EACCF8 48%, #6654F1 100%);
}
.idiom_tips_box {
text-align: center;
margin: 30px 0;
}
.detailed_description {
border-radius: 20px;
padding: 15px 30px;
border-radius: 4px;
font-size: 16px;
}
.idiom_box {
display: flex;
align-items: center;
justify-content: center;
margin: 20px auto;
}
.item_box {
height: 120px;
width: 120px;
display: flex;
align-items: center;
justify-content: center;
font-size: 50px;
border-radius: 8px;
margin-right: 10px;
background: rgb(248, 243, 243);
border: 1px solid #999
}
.optional_words_region {
margin: auto;
margin-top: 50px;
text-align: center;
display: flex;
flex-wrap: wrap;
}
.words {
display: block;
width: 50px;
height: 50px;
margin: 5px;
background: orange;
border: 1px solid black;
border-radius: 4px;
font-size: 40px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
.words:hover {
background: rgb(247, 113, 3);
color: rgb(248, 243, 243);
}
.confirm_btn_box {
margin: 10px auto;
display: flex;
justify-content: center;
cursor: pointer;
}
.confirm_btn {
margin-top: 30px;
border-radius: 8px;
padding: 10px 30px;
color: white;
background: #409eff
}
</style>
</head>
<body>
<div id="app">
<div class="title">成语学习</div>
<!-- 提示 - 描述 -->
<div class="idiom_tips_box">
<span class="detailed_description">提示:{
{tip}}</span>
</div>
<!-- 选中的成语 -->
<div class="idiom_box">
<div class="item_box" v-for="item, index in idiom" @click="clear(index)">{
{item}}</div>
</div>
<div :style="result == null? 'color:#ccc' : result? 'color : red' : ''" style="text-align: center">
{
{result == null? '请点击下方文字组织正确的成语(点击框内文字可清除)' : result? '答案正确' : '答案错误'}}</div>
<!-- 可选区域 -->
<div class="optional_words_region">
<!-- <div>{
{word}}</div> -->
<span class="words" v-for="(item, index) in words.split('')" :key="index" @click="getSingleWord(item)">
{
{item}}
</span>
</div>
<!-- 确定 -->
<div class="confirm_btn_box">
<span class="confirm_btn" @click="confirm">确定</span>
</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
tip: "",
arr: [
{ word: "热泪盈眶", tip: "形容非常感激或高兴" },
{ word: "才华横溢", tip: "指才华充分显露出来" },
{ word: "聚沙成塔", tip: "比喻积少成多" },
{ word: "名垂青史", tip: "形容功业巨大,永远流传" },
{ word: "绝无仅有", tip: "形容极其稀少" },
{ word: "衣衫褴褛", tip: "形容身上衣服破破烂烂" },
{ word: "焕然一新", tip: "形容呈现出崭新的面貌" },
{ word: "并驾齐驱", tip: "比喻齐头并进,不分前后" },
{ word: "博大精深", tip: "形容思想和学识广博高深" },
{ word: "忙里偷闲", tip: "在繁忙中抽出空闲来" }
],
words: '',
idiom: ["", "", "", ""],
result: null
},
created() {
this.tip = this.arr[parseInt(Math.random() * this.arr.length)].tip
this.arr.forEach(item => {
this.words += item.word
});
let words = this.words.split("");
words = this.shuffle(words)
this.words = words.join("")
},
methods: {
// 乱序方法
shuffle(arr) {
let temp, length = arr.length;
for (let i = 0; i < length - 1; i++) {
let index = Math.floor(Math.random() * (length--));
temp = arr[index];
arr[index] = arr[length];
arr[length] = temp;
}
return arr;
},
// 点击文字后,在idiom从左到右第一个空的位置加上该文字
getSingleWord(val) {
this.idiom.some((item, index) => {
if (item === "") {
this.idiom[index] = val
this.$set(this.idiom, index, val)
return true
}
})
},
clear(i) {
this.idiom[i] = ""
this.$set(this.idiom, i, "")
},
// 校验成语是否输入正确答案
confirm() {
let found = false;
this.arr.some((item) => {
if (item.tip === this.tip && this.idiom.join("") === item.word) {
this.result = true;
found = true;
return true;
}
});
if (!found) {
this.result = false;
}
}
}
})
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="./js/vue.min.js"></script>
<title>成语学习</title>
<style>
/* 省略CSS样式 */
</style>
</head>
<body>
<div id="app">
<div class="title">成语学习</div>
<!-- 提示 - 描述 -->
<div class="idiom_tips_box">
<span class="detailed_description">提示:{
{tip}}</span>
</div>
<!-- 选中的成语 -->
<div class="idiom_box">
<div class="item_box" v-for="item, index in idiom" @click="clear(index)">{
{item}}</div>
</div>
<div :style="result == null? 'color:#ccc' : result? 'color : red' : ''" style="text-align: center">
{
{result == null? '请点击下方文字组织正确的成语(点击框内文字可清除)' : result? '答案正确' : '答案错误'}}</div>
<!-- 可选区域 -->
<div class="optional_words_region">
<span class="words" v-for="(item, index) in words.split('')" :key="index" @click="getSingleWord(item)">
{
{item}}
</span>
</div>
<!-- 确定 -->
<div class="confirm_btn_box">
<span class="confirm_btn" @click="confirm">确定</span>
</div>
</div>
<script>
// 省略JavaScript代码
</script>
</body>
</html>
<!DOCTYPE html>
声明文档类型为 HTML5。<html lang="en">
定义文档语言为英语。<head>
标签内包含元数据,如字符集 charset="UTF-8"
,视口设置 width=device-width, initial-scale=1.0
,引入 Vue.js 库 <script src="./js/vue.min.js"></script>
,以及设置页面标题 <title>成语学习</title>
和 CSS 样式。<div id="app">
是 Vue 实例的挂载点,包含了整个游戏界面。<div class="title">成语学习</div>
显示游戏标题。<div class="idiom_tips_box">
显示成语提示信息,{ {tip}}
是 Vue 的插值表达式,用于动态显示提示内容。<div class="idiom_box">
展示用户选中的成语,v-for
指令循环渲染每个成语字符,@click="clear(index)"
绑定点击事件,用于清除选中的字符。<div :style="...">
根据 result
的值显示不同的提示信息,如等待输入、答案正确或错误。<div class="optional_words_region">
是可选字符区域,v-for
指令循环渲染每个可选字符,@click="getSingleWord(item)"
绑定点击事件,用于将选中的字符添加到成语中。<div class="confirm_btn_box">
包含确认按钮,@click="confirm"
绑定点击事件,用于校验用户输入的成语是否正确。* {
margin: 0;
padding: 0;
}
#app {
margin: auto;
}
.title {
text-align: center;
padding: 10px 0;
background-image: linear-gradient(-225deg, #69EACB 0%, #EACCF8 48%, #6654F1 100%);
}
.idiom_tips_box {
text-align: center;
margin: 30px 0;
}
.detailed_description {
border-radius: 20px;
padding: 15px 30px;
border-radius: 4px;
font-size: 16px;
}
.idiom_box {
display: flex;
align-items: center;
justify-content: center;
margin: 20px auto;
}
.item_box {
height: 120px;
width: 120px;
display: flex;
align-items: center;
justify-content: center;
font-size: 50px;
border-radius: 8px;
margin-right: 10px;
background: rgb(248, 243, 243);
border: 1px solid #999
}
.optional_words_region {
margin: auto;
margin-top: 50px;
text-align: center;
display: flex;
flex-wrap: wrap;
}
.words {
display: block;
width: 50px;
height: 50px;
margin: 5px;
background: orange;
border: 1px solid black;
border-radius: 4px;
font-size: 40px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
.words:hover {
background: rgb(247, 113, 3);
color: rgb(248, 243, 243);
}
.confirm_btn_box {
margin: 10px auto;
display: flex;
justify-content: center;
cursor: pointer;
}
.confirm_btn {
margin-top: 30px;
border-radius: 8px;
padding: 10px 30px;
color: white;
background: #409eff
}
* { margin: 0; padding: 0; }
重置所有元素的内外边距为 0。#app { margin: auto; }
使游戏容器在页面中水平居中。.title
设置标题文本居中,添加渐变背景。.idiom_tips_box
和 .detailed_description
设置提示框的文本居中、边距、圆角和字体大小。.idiom_box
使用 Flex 布局使成语字符水平居中,.item_box
设置每个字符框的大小、样式和字体。.optional_words_region
使用 Flex 布局并设置换行,.words
设置每个可选字符的样式和鼠标悬停效果。.confirm_btn_ox
和 .confirm_btn
设置确认按钮的样式和位置。var vm = new Vue({
el: '#app',
data: {
tip: "",
arr: [
{ word: "热泪盈眶", tip: "形容非常感激或高兴" },
{ word: "才华横溢", tip: "指才华充分显露出来" },
{ word: "聚沙成塔", tip: "比喻积少成多" },
{ word: "名垂青史", tip: "形容功业巨大,永远流传" },
{ word: "绝无仅有", tip: "形容极其稀少" },
{ word: "衣衫褴褛", tip: "形容身上衣服破破烂烂" },
{ word: "焕然一新", tip: "形容呈现出崭新的面貌" },
{ word: "并驾齐驱", tip: "比喻齐头并进,不分前后" },
{ word: "博大精深", tip: "形容思想和学识广博高深" },
{ word: "忙里偷闲", tip: "在繁忙中抽出空闲来" }
],
words: '',
idiom: ["", "", "", ""],
result: null
},
created() {
this.tip = this.arr[parseInt(Math.random() * this.arr.length)].tip
this.arr.forEach(item => {
this.words += item.word
});
let words = this.words.split("");
words = this.shuffle(words)
this.words = words.join("")
},
methods: {
// 乱序方法
shuffle(arr) {
let temp, length = arr.length;
for (let i = 0; i < length - 1; i++) {
let index = Math.floor(Math.random() * (length--));
temp = arr[index];
arr[index] = arr[length];
arr[length] = temp;
}
return arr;
},
// 点击文字后,在idiom从左到右第一个空的位置加上该文字
getSingleWord(val) {
this.idiom.some((item, index) => {
if (item === "") {
this.idiom[index] = val
this.$set(this.idiom, index, val)
return true
}
})
},
clear(i) {
this.idiom[i] = ""
this.$set(this.idiom, i, "")
},
// 校验成语是否输入正确答案
confirm() {
let found = false;
this.arr.some((item) => {
if (item.tip === this.tip && this.idiom.join("") === item.word) {
this.result = true;
found = true;
return true;
}
});
if (!found) {
this.result = false;
}
}
}
})
el: '#app'
将 Vue 实例挂载到 HTML 中 id 为 app
的元素上。data
对象定义了游戏所需的数据,包括成语提示 tip
,成语数组 arr
,可选字符 words
,用户输入的成语 idiom
,以及结果 result
。created()
在 Vue 实例创建完成后调用,用于初始化游戏数据。它随机选择一个成语的提示并将所有成语的字符打乱作为可选字符。shuffle(arr)
方法用于打乱数组元素顺序。getSingleWord(val)
方法在用户点击可选字符时,将字符添加到 idiom
数组中第一个空的位置。clear(i)
方法用于清除 idiom
数组中指定位置的字符。confirm()
方法用于校验用户输入的成语是否正确,通过比较用户输入的成语和当前提示对应的正确成语来判断。四、工作流程 ▶️
created
钩子函数被调用。confirm
方法。通过以上 HTML、CSS 和 JavaScript 的协同工作,实现了一个简单的成语学习小游戏。