Vue-实现图书管理

一:项目的铺垫

(1):数组的方法

数组相关APL
    变异方法 (mutation method) ---修改原始数据
    push() pop() shift() unshift() splice() sort() reverse()
    替换数组---生成新数组
    filter()、concat() 和 slice()
<body>
  <div id="app">
    <div>
      <input type="text" v-model="fname">
      <button @click="add">添加</button>
      <button @click="del">删除</button>
      <button @click="change">替换</button>
    </div>
    <div>
      <ul>
        <li :key="item.id" v-for="(item,index) in fruit">
          {{item}}
        </li>
      </ul>
    </div>
  </div>
  <script src="../js/vue.js"></script>
  <script>
    let vm = new Vue({
      el: "#app",
      data: {
        fname: '',
        fruit: ['apple', 'banana', 'pear']
      },
      methods: {
        add: function () {
          this.fruit.push(this.fname);
        },
        del: function () {
          this.fruit.pop(this.fname);
        },
        change: function () {
          this.fruit = this.fruit.slice(0, 2); //不会影响原始数据,所以在赋值回去
        }
      }
    });
  </script>
</body>

(2):动态响应处理数据

  动态响应处理数据
      1:Vue.set(vm.items, indexOfItem, newValue)
       或者 vm.$set(vm.items, indexOfItem, newValue)
        01:参数一:要处理的数组名称 02:参数二:要处理的数组索引 03:要处理数组的值
      2:vm.items.splice(newLength)
<body>
  <div id="app">
    <div>
      <ul>
        <li v-for="(item,index) in list" :key="item.index">{{item}}</li>
      </ul>
    </div>
    <div>{{info.name}}</div>
    <div>{{info.age}}</div>
    <div>{{info.gender}}</div>
  </div>
  <script src="../js/vue.js"></script>
  <script>
    let vm = new Vue({
      el: "#app",
      data: {
        list: ['apple', 'banana', 'pear'],
        info: {
          name: 'pink',
          age: 18,
        }
      }
    });
    Vue.set(vm.list, 2, 'lemo'); //修改了list数据的索引号为2的数据为lemo
    vm.$set(vm.list, 2, 'pear'); //修改了list数据的索引号为2的数据为pear
    vm.$set(vm.info, 'gender', 'female'); //修改了info对象中gender属性的设置为female
    //以下不是响应式的
    // vm.info.gender = 'male'; 
    // vm.list[1] = 'lemo';
  </script>
</body>

二:图书管理

在这里插入图片描述
思路:
/*
常用属性应用场景
1:过滤器—格式化日期
2:自定义指令—获取表单焦点
3:计算属性—统计图书数量
4:监听器—验证图书存在性
5:生命周期—图书数据处理
*/

    第一步:图书列表的渲染
    	1:构造视图,利用v-for循环去渲染数据
    第二步:添加图书
    	1:点击提交,需要把id与name存入一个对象,然后推入books(数组)数据之中
    	2:并且清空表单的内容
    	3:
    第三步:修改图书
    	1:点击修改图书-这是根据id来判断点击了哪一个,所以在修改处需要一个点击事件并且传递id过去(item.id)
    	2:禁止编辑id---这需要一个flag标志来判断(disable=“flag”)
    	3:点击修改后,把对应的数据传递到上面的表单内(依靠filter方法,根据id是否相等,返回一个新的数组)
    	4:再启动编辑功能,修改后,把数据再一次保存如books数据中,由于编辑功能逻辑可以写在添加功能里面,判断调价是id的标志为真的话,为编辑状态,为假就是添加状态
    	5:在编辑状态里面修改数据,利用some方法(根据当前的id去更新数组中对应的数据)---但是需要借助箭头函数
    	6:最后不管是添加还是修改,都需要表单的内容清空
    第四步:删除图书
    	1:  //根据点击的item的id删除,这可以借助filter方法,过滤。
    第五步:图书的总数
    	computed: {
        total: function () {
          //计算图书的总数 就是数组中的长度
          return this.books.length;
        }
      },
      第六步:mounted---生命周期此处,渲染数据,因此把数据拿到此处,并且赋值给books
 <title>图书管理</title>
  <style>
    [v-cloak] {
      display: none;
    }

    #app {
      width: 600px;
      height: 500px;
      margin: 10px auto;
      text-align: center;
    }

    .book {
      background-color: orange;
    }

    table {
      border-collapse: collapse;
    }

    thead {
      background-color: orange;
      height: 50px;
    }

    td {
      width: 200px;
      border: 1px solid #ccc;
    }

    tr:nth-child(1) {
      border-bottom: 1px solid #ccc;
    }

    td:nth-child(1) {
      width: 80px;
    }

    .grid .total {
      height: 30px;
      line-height: 30px;
      background-color: orange;
      border-top: 1px solid #ccc;
    }
  </style>
</head>

<body>
  <div id="app" v-cloak>
    <div class="grid">
      <h2>图书管理</h2>
      <div class="book">
        <label for="id">编号:</label>
        <input type="text" id="id" v-model="id" :disabled="flag" v-focus>
        <label for="name">名称:</label>
        <input type="text" id="name" v-model="name">
        <button @click="submit">提交</button>
      </div>
      <div class="total">
        <span>图书总数: </span>
        <span>{{total}}</span>
      </div>
      <table>
        <thead>
          <td>编号</td>
          <td>名称</td>
          <td>时间</td>
          <td>操作</td>
        </thead>
        <tbody>
          <tr v-for="(item,index) in books" :key="item.id">
            <td>{{item.id}}</td>
            <td>{{item.name}}</td>
            <td>{{item.date | format('yyyy-MM-dd hh:mm:ss')}}</td>
            <td>
              <a href="" @click.prevent="toEdit(item.id)">修改</a>
              <span>|</span>
              <a href="" @click.prevent="del(item.id)">删除</a>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
  <script src="../js/vue.js"></script>
  <script>
    Vue.directive('focus', {
      inserted: function (el) {
        el.focus();
      }
    });
    //使用过滤器格式化日期
    Vue.filter('format', function (value, arg) {
      function dateForamt(date, format) {
        if (typeof date === 'string') {
          var mts = date.match(/(\/Date\((\d+)\)\/)/);
          if (mts && mts.length >= 3) {
            date = parseInt(mts[2]);
          }
        }
        date = new Date(date);
        if (!date || date.toUTCString() == "Invalid Date") {
          return "";
        }
        var map = {
          "M": date.getMonth() + 1, //月份 
          "d": date.getDate(), //日 
          "h": date.getHours(), //小时 
          "m": date.getMinutes(), //分 
          "s": date.getSeconds(), //秒 
          "q": Math.floor((date.getMonth() + 3) / 3), //季度 
          "S": date.getMilliseconds() //毫秒 
        };
        format = format.replace(/([yMdhmsqS])+/g, function (all, t) {
          var v = map[t];
          if (v !== undefined) {
            if (all.length > 1) {
              v = '0' + v;
              v = v.substr(v.length - 2);
            }
            return v;
          } else if (t === 'y') {
            return (date.getFullYear() + "").substr(4 - all.length);
          }
          return all;
        });
        return format;
      }
      return dateForamt(value, arg);
    });
    let vm = new Vue({
      el: "#app",
      data: {
        flag: false,
        id: "",
        name: "",
        books: ""
      },
      methods: {
        submit: function (val) { //提交事件
          if (this.flag) { //为真,证明id被禁用,为编辑状态
            //修改里面的数据,然后把数据保存到books里面---就是根据当前的id去更新数组中对应的数据some方法
            this.books.some((item) => {
              if (item.id == this.id) {
                item.name = this.name;
                return true;
              }
              this.flag = false;
            })
          } else {
            //添加图书  
            let book = {};
            book.id = this.id;
            book.name = this.name;
            book.date = ""
            this.books.push(book);
          }
          this.id = "";
          this.name = "";
        },
        //修改图书,禁止编辑id
        toEdit: function (id) {
          // console.log(id);
          this.flag = true;
          var book = this.books.filter(function (item) {
            return item.id == id;
          });
          // console.log(book); //返回一个新的数组,然后把数组中的数据,填充到表单内
          this.id = book[0].id;
          this.name = book[0].name;

        },
        //删除
        del: function (id) {
          //根据点击的item的id删除,这可以借助filter方法,过滤
          this.books = this.books.filter(function (item) {
            return item.id != id; //返回的是,不包含点击过的id
          });
        }
      },
      computed: {
        total: function () {
          //计算图书的总数 就是数组中的长度
          return this.books.length;
        }
      },
      mounted: function () {
        var data = [{
            id: 1,
            name: '三国演义',
            date: 2525609975001
          },
          {
            id: 2,
            name: '水浒传',
            date: 2525609975001
          }, {
            id: 3,
            name: '西游记',
            date: 2525609975001
          }, {
            id: 4,
            name: '红楼梦',
            date: 2525609975001
          }
        ];
        this.books = data;
      }
    });
  </script>
</body>
发布了12 篇原创文章 · 获赞 2 · 访问量 302

猜你喜欢

转载自blog.csdn.net/weixin_43845137/article/details/105136369
今日推荐