前言
Vue.js 是一个用于构建用户界面的渐进式 JavaScript 框架。它的设计目标是通过采用易于上手的结构和强大的功能,使前端开发变得更加简便和高效。以下是 Vue.js 的一些关键特性和优点:
核心特性
- 声明式渲染
- Vue.js 使用声明式语法来描述用户界面,数据和视图是双向绑定的。当数据变化时,视图会自动更新。
- 组件系统
- Vue.js 提供了一个灵活的组件系统,允许开发者将 UI 分解成可复用的组件,每个组件都有自己的逻辑和样式。
- 单文件组件 (SFC)
- Vue.js 允许开发者将 HTML、CSS 和 JavaScript 放在同一个
.vue
文件中,这样可以更容易地管理组件。
- 虚拟 DOM
- Vue.js 使用虚拟 DOM 来优化更新过程,通过最小化实际 DOM 操作来提高性能。
- 反应式数据绑定
- Vue.js 提供了响应式的数据绑定系统,使得数据与 DOM 之间的同步变得简单和高效。
- 指令
- Vue.js 提供了一组内置指令(如
v-bind
、v-model
和v-for
),帮助开发者轻松地操作 DOM。
优点
- 易于上手
- Vue.js 的学习曲线较低,适合新手入门,并且文档详细、社区活跃。
- 灵活性
- Vue.js 可以与现有项目集成,也可以用于构建复杂的单页面应用(SPA)。
- 性能高效
- 得益于虚拟 DOM 和响应式系统,Vue.js 在处理大量数据更新时表现出色。
- 生态系统
- Vue.js 拥有丰富的生态系统,包括 Vue Router、Vuex、Vue CLI 等工具和库,支持开发者在不同场景下使用。
- 强大的社区支持
- Vue.js 有一个全球活跃的社区,提供了大量的插件、教程和支持资源。
知识点
1. 创建 Vue 实例
2. v-bind 数据绑定
3. @click 点击事件绑定
4. v-show 显示或隐藏元素
项目效果
原始效果
删除数据
添加数据
源代码
.score-case { width: 1000px; margin: 50px auto; display: flex; } .score-case .table { flex: 4; } .score-case .table table { width: 100%; border-spacing: 0; border-top: 1px solid #ccc; border-left: 1px solid #ccc; } .score-case .table table th { background: #f5f5f5; } .score-case .table table tr:hover td { background: #f5f5f5; } .score-case .table table td, .score-case .table table th { border-bottom: 1px solid #ccc; border-right: 1px solid #ccc; text-align: center; padding: 10px; } .score-case .table table td.red, .score-case .table table th.red { color: red; } .score-case .table .none { height: 100px; line-height: 100px; color: #999; } .score-case .form { flex: 1; padding: 20px; } .score-case .form .form-item { display: flex; margin-bottom: 20px; align-items: center; } .score-case .form .form-item .label { width: 60px; text-align: right; font-size: 14px; } .score-case .form .form-item .input { flex: 1; } .score-case .form .form-item input, .score-case .form .form-item select { appearance: none; outline: none; border: 1px solid #ccc; width: 200px; height: 40px; box-sizing: border-box; padding: 10px; color: #666; } .score-case .form .form-item input::placeholder { color: #666; } .score-case .form .form-item .cancel, .score-case .form .form-item .submit { appearance: none; outline: none; border: 1px solid #ccc; border-radius: 4px; padding: 4px 10px; margin-right: 10px; font-size: 12px; background: #ccc; } .score-case .form .form-item .submit { border-color: #069; background: #069; color: #fff; }
<!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" /> <link rel="stylesheet" href="./static/styles/index.css" /> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> <title>Document</title> </head> <body> <div id="app" class="score-case"> <div class="table"> <table> <thead> <tr> <th>编号</th> <th>科目</th> <th>成绩</th> <th>操作</th> </tr> </thead> <!-- 1 --> <!-- 这里有两个 tbody,只能保留一个 --> <!-- 通过 v-if v-else 如果有成绩则渲染,没有则显示无数据 --> <!-- 如果使用 v-show 则在页面中 tbody 节点还是存在只是不展示,而 v-if v-else 则直接销毁 --> <tbody v-if="list.length > 0"> <!-- v-for 遍历渲染数据 --> <tr v-for="(item, index) in list" :key="item"> <td>{{ index + 1 }}</td> <td>{{ item.subject }}</td> <!-- 需求:不及格加红 --> <!-- v-bind 绑定 class --> <td :class="{ red: item.score < 60 }">{{ item.score }}</td> <!-- @click 绑定点击事件 --> <!-- .prevent 阻止跳转 --> <td><a @click.prevent="del(item.id)" href="#">删除</a></td> </tr> </tbody> <tbody v-else> <tr> <td colspan="5"> <span class="none">暂无数据</span> </td> </tr> </tbody> <tfoot> <tr> <td colspan="5"> <span>总分:{{ totalScore }}</span> <span style="margin-left: 50px">平均分:{{ averageScore }}</span> </td> </tr> </tfoot> </table> </div> <div class="form"> <div class="form-item"> <div class="label">科目:</div> <div class="input"> <!-- v-model 绑定元素实时获取数据 --> <!-- .trim 删除字符串的头尾空白符实现过滤 --> <input v-model.trim="subject" type="text" placeholder="请输入科目"/> </div> </div> <div class="form-item"> <div class="label">分数:</div> <div class="input"> <!-- .number 转为数字 --> <input v-model.number="score" type="text" placeholder="请输入分数"/> </div> </div> <div class="form-item"> <div class="label"></div> <div class="input"> <button @click="add()" class="submit">添加</button> </div> </div> </div> </div> <script src="../vue.js"></script> <script> const app = new Vue({ el: '#app', data: { list: [ { id: 1, subject: '语文', score: 20 }, { id: 7, subject: '数学', score: 99 }, { id: 12, subject: '英语', score: 70 }, ], subject: '', score: '' }, // computed 是一个对象,其中的每个属性都是一个计算属性 computed: { totalScore () { // reduce 方法接收两个参数:一个回调函数和一个初始值。 // 回调函数接收两个参数:sum(累加器)和 item(当前项)。 // 回调函数的返回值将作为下一次调用的 sum 参数。 // 初始值是 0,表示累加开始时的值。 return this.list.reduce((sum, item) => sum + item.score, 0) }, averageScore () { // 除数不能为 0 if (this.list.length !== 0) { // toFixed(2) 结果保留两位小数 return this.totalScore / this.list.length.toFixed(2) } return 0 } }, methods: { del (id) { // filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素 // 这是一个箭头函数,它接收数组中的每个元素作为参数(在这里是 item)。 // item.id !== id:这是一个比较操作,检查 item 的 id 属性是否不等于传递给 filter 方法的 id 参数。如果不等于,返回 true;如果等于,返回 false this.list = this.list.filter(item => item.id !== id) }, add () { // 当用户输入为空时,不让添加 if (this.subject | this.score === '') { alert('输入不可为空') return } if (typeof this.score !== 'number') { alert('成绩请输入数字') return } // unshift() 方法可向数组的开头添加一个或更多元素,并返回新的长度 this.list.unshift({ // id 不用管,因为上面写好了,添加就是 1 id: Date(), subject: this.subject, score: this.score }) // 输入完后清空输入框的内容 this.subject = '', this.score = '' } }, }) </script> </body> </html>