Vue中计算属性的使用

使用成绩需求来实现

详细的代码示例(主要练习 Vue 简单的计算属性)

需求功能技术点
    1. 渲染功能: 不及格高亮、使用v-if v-else结局盒子互斥,使用v-bind:class解决高亮。
    1. 删除功能:点击传递id ,通过filter过滤器过滤然后覆盖原数组,使用指令修饰符。prevent阻止默认行为。
    1. 添加功能:v-model双向绑定,使用指令修饰符 (trim, number)修饰功能。在使用unshift修改数组,v-for会根据数组自动更新视图。
    1. 统计总分,求平均分:使用reduce求和(需要在computed配置项中使用计算属性函数),将计算逻辑返回的结果通过return暴露出来,然后使用差值表达式 通过 属性的方式进行渲染即可。切记计算属性和函数方法长的一样都是函数,但是,使用计算属性必须写属性。{{ 计算属性名 }},后面不要小括号。
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" />
    <link rel="stylesheet" href="./styles/index.css" />
    <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>
          <tbody v-if="list.length > 0">
            <tr v-for="(item,index) in list" :key="item.id">
              <td>{{ index + 1 }}</td>
              <td>{{ item.subject }}</td>
              <td :class="{red: item.score < 60}">{{ item.score}}</td>
              <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>总分:{{ totalCount }}</span>
                <span style="margin-left: 50px">平均分:{{ averageCount }}</span>
              </td>
            </tr>
          </tfoot>
        </table>
      </div>
      <div class="form">
        <div class="form-item">
          <div class="label">科目:</div>
          <div class="input">
            <input v-model.trim="subject"
              type="text"
              placeholder="请输入科目"
            />
          </div>
        </div>
        <div class="form-item">
          <div class="label">分数:</div>
          <div class="input">
            <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="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

    <script>
      const app = new Vue({
        el: '#app',
        data: {
          list: [
            { id: 1, subject: '语文', score: 20 },
            { id: 7, subject: '数学', score: 80 },
            { id: 12, subject: '英语', score: 70 },
          ],
          subject: '',
          score: ''
        },
        methods: {
          del (id) {
            // 判断id,进行过滤不需要删除的项,然后将新数组重新赋值给list
            this.list = this.list.filter(item => item.id !== id)
            // 这句代码的含义就是,当我对数组一次遍历,当前项的id不等于我传过来的全部过滤放到新数组,然后重新赋值,相等的不过滤,就不会再渲染他,===删除。
          },
          add () {
            // 在v-model双向绑定后,我们获取到数据后,使用unshift在数组前面增加即可,因为v-for会自动检测数据个数然后动态渲染
            this.list.unshift({
              // 切记,list对象里面的格式是怎样的,这里也需要保持一致
              id: +new Date(),
              subject: this.subject,
              score: this.score
            })
          }
        },
        computed: {
          // 这里不需要修改,所有我们直接使用简单的计算属性写法即可,注意差值使用属性,不要写成调用方法
          totalCount () {
            // 属性是可以直接通过this访问,甚至都不需要声明
            return  this.list.reduce((sum,item) => sum + item.score ,0)
            // 求和后有返回值,用变量total接受,然后使用return返回给函数,哪里使用我们该函数,就能访问到结果,切记计算属性里面的函数,可以理解为调用函数,但是不要加小括号,切记
          },
          averageCount () {
            // 解决品均分为 NaN的问题,数组没有分数操作会显示,这里判断,如果长度为0,直接返回0 且终止后面代码。
            if (this.list.length === 0) {
              return 0
            }
            // 将返回值,通过return暴露出去,谁使用我们的计算属性名,谁就能得到结果。
            return (this.totalCount / this.list.length).toFixed(2)

          }
        }
      })
    </script>
  </body>
</html>
相关推荐
dsyyyyy11013 小时前
JavaScript变量
开发语言·javascript·ecmascript
kyriewen4 小时前
手写 Promise.all、race、any:不到 30 行代码,解决并发异步的所有姿势
前端·javascript·面试
胡志辉的博客5 小时前
深入浅出理解浏览器事件循环:从一道输出题讲到 Chrome 源码
前端·javascript·chrome·chromium·event loop
代码不加糖5 小时前
js中不会冒泡的事件有哪些?
前端·javascript·vue.js
懂懂tty6 小时前
Vue2与Vue3之间API差异
前端·javascript·vue.js
老毛肚6 小时前
软件测试期末考试
vue.js
小二·6 小时前
Next.js 15 全栈开发实战
开发语言·javascript·ecmascript
杨若瑜7 小时前
本地开发环境慢?localhost的锅!
vue.js
Rain5097 小时前
2.1 Nest.js 项目初始化与模块化架构
开发语言·前端·javascript·后端·架构·数据分析·node.js
拾年2758 小时前
从零手写 Ajax:用原生 XHR 搭建前后端交互全流程
前端·javascript·ajax