在使用 element-ui 开发的过程中,表单组件的使用相当频繁,其使用方式也比较简单,只要根据官网示例操作即可掌握。不过刚开始使用它的小蓝却遇到了一个问题:本来一个完整的表单已经出现在页面上了,可是调皮的小猫跳到键盘上一顿“操作”后表单凭空消失了......机智的你来帮他查找原因并修复这个 bug 吧~
本题已经内置了初始代码,打开实验环境,目录结构如下:
├── element-ui-2.15.10
│ ├── index.css
│ └── index.js
├── index.html
├── js
│ ├── http-vue-loader.js
│ └── vue.min.js
└── myform.vue
其中:
index.html
是主页面。myform.vue
是封装的表单组件文件。js
是用于存放 Vue.js 相关文件的文件夹。element-ui-2.15.10
是存放 element-ui 的文件夹。选中 index.html
右键启动 Web Server 服务(Open with Live Server),让项目运行起来。
接着,打开环境右侧的【Web 服务】,就可以在浏览器中看到如下效果:
初始代码中的
index.html
在浏览器中并没有显示出来表单组件myform
。考生需要认真检查提供的代码,找出表单消失的原因,并修复掉,最终让表单“重见天日”。效果如下:
id
、class
、DOM 结构、以及函数名等,以免造成无法判题通过。<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>凭空消失的 TA</title>
<script src="./js/vue.min.js"></script>
<script src="./js/http-vue-loader.js"></script>
<!-- 引入 element-ui 样式 -->
<script src="./element-ui-2.15.10/index.js"></script>
<link rel="stylesheet" href="./element-ui-2.15.10/index.css" />
</head>
<body>
<div id="app">
<myform ref="myform" :form="form"></myform>
</div>
</body>
<script type="text/javascript">
Vue.use(httpVueLoader);
var vm = new Vue({
components: {
myform: "url:./myform.vue",
},
el: "#app",
data: {
that: this,
test: "hello",
form: {
name: "test-name",
region: "",
date1: "2022/9/22",
date2: "15:00:00",
delivery: false,
type: [],
resource: "",
desc: "this is a test.",
},
},
});
</script>
</html>
//index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>凭空消失的 TA</title>
<script src="./js/vue.min.js"></script>
<script src="./js/http-vue-loader.js"></script>
<!-- 引入 element-ui 样式 -->
<script src="./element-ui-2.15.10/index.js"></script>
<link rel="stylesheet" href="./element-ui-2.15.10/index.css" />
</head>
<body>
<div id="app">
<myform ref="myform" :form="form"></myform>
</div>
</body>
<script type="text/javascript">
Vue.use(httpVueLoader);
var vm = new Vue({
components: {
myform: "url:./myform.vue",
},
el: "#app",
data: {
that: this,
test: "hello",
form: {
name: "test-name",
region: "",
date1: "2022/9/22",
date2: "15:00:00",
delivery: false,
type: [],
resource: "",
desc: "this is a test.",
},
},
});
</script>
</html>
<head>
)部分: <meta charset="UTF-8">
:设置文档的字符编码为 UTF - 8,确保能正确显示各种字符。<meta http - equiv="X - UA - Compatible" content="IE=edge">
:告诉 IE 浏览器以最新的渲染模式渲染页面,可提高页面在 IE 浏览器中的兼容性。<meta name="viewport" content="width=device - width, initial - scale = 1.0">
:用于响应式设计,设置视口宽度为设备宽度,初始缩放比例为 1.0,使页面在不同设备上能更好地适配。<title>凭空消失的TA</title>
:设置网页的标题为 “凭空消失的 TA”。<script src="./js/vue.min.js"></script>
:引入 Vue.js 的核心库,这是构建 Vue 应用的基础,它提供了 Vue 的各种功能,如数据绑定、组件系统等。<script src="./js/http - vue - loader.js"></script>
:该文件可能是用于通过 HTTP 加载 Vue 组件的加载器,在这里用于支持从 URL 加载myform.vue
组件。<script src="./element - ui - 2.15.10/index.js"></script>
:引入 Element - UI 的 JavaScript 文件,Element - UI 是基于 Vue.js 的组件库,此文件包含了各种组件的定义和功能实现。<link rel="stylesheet" href="./element - ui - 2.15.10/index.css">
:引入 Element - UI 的样式文件,为 Element - UI 组件提供外观样式。<body>
)部分: <div id="app">
:定义了 Vue 应用的挂载点,所有 Vue 组件将在这个div
元素内渲染。<myform ref="myform" :form="form"></myform>
:使用自定义组件myform
,并通过ref
属性为其提供一个引用,方便在父组件中访问该子组件实例。:form="form"
是一个动态绑定,将父组件vm
的form
数据对象传递给myform
组件。<script>
)部分: Vue.use(httpVueLoader);
:使用httpVueLoader
插件,使其功能生效,以便能够从 URL 加载 Vue 组件。var vm = new Vue({... });
:创建一个 Vue 实例vm
。 components
:定义了当前 Vue 实例使用的组件,这里注册了myform
组件,其值"url:./myform.vue"
表示通过httpVueLoader
从./myform.vue
文件加载该组件。el: "#app"
:指定 Vue 实例挂载到id
为app
的 DOM 元素上。data
:定义了 Vue 实例的数据对象,其中包含that
(虽然这里使用this
在数据对象中定义不太合适,可能会导致问题,但代码中未实际使用到其错误特性)、test
和form
。form
对象包含了表单中各个字段的初始值,这些值将传递给myform
组件。//myform.vue
<template>
<div class="main">
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="活动名称">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="活动区域">
<el-select v-model="form.region" placeholder="请选择活动区域">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item label="活动时间">
<el-col :span="11">
<el-date-picker
type="date"
placeholder="选择日期"
v-model="form.date1"
style="width: 100%"
></el-date-picker>
</el-col>
<el-col class="line" :span="2">-</el-col>
<el-col :span="11">
<el-time-picker
placeholder="选择时间"
v-model="form.date2"
style="width: 100%"
></el-time-picker>
</el-col>
</el-form-item>
<el-form-item label="即时配送">
<el-switch v-model="form.delivery"></el-switch>
</el-form-item>
<el-form-item label="活动性质">
<el-checkbox-group v-model="form.type">
<el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
<el-checkbox label="地推活动" name="type"></el-checkbox>
<el-checkbox label="线下主题活动" name="type"></el-checkbox>
<el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="特殊资源">
<el-radio-group v-model="form.resource">
<el-radio label="线上品牌商赞助"></el-radio>
<el-radio label="线下场地免费"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="活动形式">
<el-input type="textarea" v-model="form.desc"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">立即创建</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
module.exports = {
props: {
form: {
type: Object,
default: () => {
return {
name: "",
region: "",
date1: "",
date2: "",
delivery: false,
type: [],
resource: "",
desc: "",
};
},
},
},
methods: {
onSubmit() {
console.log("submit!");
},
},
};
</script>
<style scoped>
.main {
width: 60%;
margin: 0 auto;
}
.tools {
margin-top: 20px;
text-align: center;
}
</style>
<template>
)部分: <div class="main">
:定义了一个包含整个表单的div
元素,class
为main
,并在样式部分设置了其宽度为页面的 60%,且水平居中显示。<el - form ref="form" :model="form" label - width="80px">
:使用 Element - UI 的表单组件el - form
,ref
为form
(可在组件内部通过this.$refs.form
访问该表单实例),:model="form"
将表单绑定到从父组件传递过来的form
数据对象,label - width
设置表单标签的宽度为 80px。<el - form - item>
组件: <el - form - item>
代表表单中的一个字段,如 “活动名称”“活动区域” 等。每个字段包含一个标签(<el - form - item>
的label
属性)和对应的表单控件(如<el - input>
、<el - select>
等)。<el - input v - model="form.name"></el - input>
将el - input
输入框的值与form
对象的name
属性进行双向数据绑定,用户在输入框中输入的值会实时更新form.name
,反之亦然。<script>
)部分: module.exports = {... }
:使用 Node.js 风格的模块导出方式,定义了myform.vue
组件的配置对象。props
:定义了组件接收的属性,这里只有form
属性,它是一个对象类型,并且提供了一个默认值函数,当父组件没有传递form
属性时,会使用默认值对象,其中包含了表单各个字段的默认初始值。methods
:定义了组件的方法,这里只有onSubmit
方法,当用户点击 “立即创建” 按钮时会调用该方法,目前该方法只是在控制台打印 “submit!”。<style>
)部分: scoped
属性,确保样式只应用于当前组件内的元素,不会影响其他组件。.main
类设置了组件整体的宽度和水平居中样式。.tools
类设置了一个margin - top
和文本居中样式,但在模板中未看到使用该类的元素。三、工作流程 ▶️
index.html
,解析并执行其中的 JavaScript 代码。http - vue - loader
、Element - UI 的相关文件,初始化 Vue 环境和 Element - UI 组件库。vm
,vm
的data
中的form
对象包含了表单的初始数据,myform
组件被注册并准备从./myform.vue
加载。http - vue - loader
根据"url:./myform.vue"
从myform.vue
文件加载组件定义。myform.vue
组件的模板被解析,form
属性从父组件vm
传递过来,表单中的各个控件通过v - model
与form
对象的相应属性进行双向数据绑定。form
对象中的数据会实时更新。myform.vue
组件的onSubmit
方法,在这个例子中,该方法只是在控制台打印 “submit!”,实际应用中可能会进行表单验证、数据提交等操作。通过上述两个文件的协同工作,实现了一个具有基本数据绑定和交互功能的表单。