Vue图书管理案例

Vue图书管理案例

1.图书列表

  • 实现静态列表效果
  • 基于数据实现模板效果
  • 处理每行的操作按钮
编号名称时间操作
1三国演义2020-11-02修改 | 删除
2水浒传2020-11-02修改 | 删除
3红楼梦2020-11-02修改 | 删除
4西游记2020-11-02修改 | 删除

代码实现

@click.prevent - 禁止 a 标签的默认事件

<tbody>
    <tr :key='item.id' v-for='item in books'>
        <td>{{item.id}}</td>
        <td>{{item.name}}</td>
        <td>{{item.date}}</td>
        <td>
            <a href="" @click.prevent>修改</a>
            <span>|</span>
            <a href="" @click.prevent>删除</a>
        </td>
    </tr>
</tbody>
const vm = new Vue({
    el: "#app",
    data: {
        books: [
            {
                id: 1,
                name: "三国演义",
                date: ""
            },
            {
                id: 2,
                name: "水浒传",
                date: ""
            },
            {
                id: 3,
                name: "红楼梦",
                date: ""
            },
            {
                id: 4,
                name: "西游记",
                date: ""
            }
        ]
    }
})

image-20201102145336967

2.添加图书

  • 实现表单的静态效果
  • 添加图书表单域数据绑定
  • 添加按钮事件绑定
  • 实现添加业务逻辑

代码实现

v-model 双向绑定 输入框对应的 value 值

定义一个 handle 点击事件(点击提交,把填写的编号和名称添加到列表中)

在 Vue 实例对象的data中定义 id 和 name 属性

在 methods 中实现 handle 事件

<div>
    <label for="id">
        编号:
    </label>
    <input type="text" id="id" v-model="id">
    <label for="name">
        名称:
    </label>
    <input type="text" id="name" v-model="name">
    <button @click="handle">提交</button>
</div>
const vm = new Vue({
    el: "#app",
    data: {
        id: "",
        name: "",
        books: [
            {
                id: 1,
                name: "三国演义",
                date: ""
            },
            {
                id: 2,
                name: "水浒传",
                date: ""
            },
            {
                id: 3,
                name: "红楼梦",
                date: ""
            },
            {
                id: 4,
                name: "西游记",
                date: ""
            }
        ]
    },
    methods: {
        handle: function(){
            var book = {}
            book.id = this.id
            book.name = this.name
            book.date = ""
            this.books.push(book)
            this.id = ""
            this.name = ""
        }
    }
})

3.修改图书

  • 修改信息填充到表单
  • 修改后重新提交表单
  • 重用添加和修改的方法

代码实现

为修改按钮添加 toEdit 事件,把 tr 的 id 传入

<a href="" @click.prevent="toEdit(item.id)">修改</a>
toEdit: function(id){
    console.log(id);
    // 先通过 id 找到对应的这一行数据
    var book = this.books.filter(function(item){
        return item.id === id
    })
    // console.log(book);
    this.id = book[0].id
    this.name = book[0].name
}

在修改的时候我们不希望能够修改 书籍的编号 ,所以就需要在修改时添加 disabled 属性,如下写法

<input type="text" id="id" v-model="id" :disabled="flag">

可以看到,这是一个 vue 属性,flag是一个变量,Ta 需要在 Vue 实例对象 data中定义,默认为 flag: false

在修改是禁止修改编号,使 flag: true 即可,如下

toEdit: function(id){
    // 禁止修改编号
    this.flag = true
    // console.log(id);
    // 先通过 id 找到对应的这一行数据
    var book = this.books.filter(function(item){
        return item.id === id
    })
    // console.log(book);
    this.id = book[0].id
    this.name = book[0].name
}

另外,提交(handle)事件现在有两件事要做,一是编辑图书,二是添加图书,当 flag 为 true 时去编辑图书,当 flag 为 false 时去添加图书,如下

使用 filter 得到 books 中的所有元素,如果输入框中的 id 等于 要编辑的图书的id,则把输入框中的 name 重新赋值给 书籍的 name

handle: function(){
    if(this.flag){
        // 编辑
        this.books.filter((item)=>{
            // console.log(item);
            if(this.id == item.id){
                item.name = this.name
                return true
            }
        })
        this.flag = false
    }else{
        // 添加
        var book = {}
        book.id = this.id
        book.name = this.name
        book.date = ""
        this.books.push(book)
    }
    this.id = ""
    this.name = ""
}

效果如下

4.删除图书

  • 删除按钮绑定事件处理方法
  • 实现删除业务逻辑

代码实现

三种方法

<a href="" @click.prevent="deleteBook(item.id)">删除</a>
deleteBook: function(id){
    // -----------------方法一(filter)---------------------
    var book = this.books.filter(function(item){
        return item.id === id
    })
    // console.log(book);
    var index = this.books.indexOf(book[0])
    // console.log(index);
    this.books.splice(index, 1)

    // -----------------方法二(findIndex)---------------------
    var index = this.books.findIndex(function(item){
        return item.id === id
    })
    // console.log(index);
    this.books.splice(index, 1)
    // -----------------方法三(filter的重新赋值)---------------
        this.books = this.books.filter(function(item){
        return item.id != id
    })
}

5.常用特性应用场景

  • 过滤器(格式化日期)
  • 自定义指令(获取表单焦点)
  • 计算属性(统计图书数量)
  • 侦听器(验证图书存在性)
  • 生命周期(图书数据处理)

代码实现

首先 Ctrl+C、Ctrl+V 祖传过滤器

Vue.filter('format', function(value, arg) {
    function dateFormat(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 dateFormat(value, arg);
})

然后在需要显示时间的那一格进行使用

 <td>{{item.date | format('yyyy-MM-dd hh:mm:ss')}}</td>

注意:books内不能直接用 this 获取Dao Vue的实例对象,而是获取的 Window 全局对象

直接在添加书籍时添加时间即可,如下

// 添加
var book = {}
book.id = this.id
book.name = this.name
book.date = new Date() // 时间
this.books.push(book)

刷新页面获取焦点也是直接写一个全局 directive ,自定义指令即可,我命名为 focus ,名字可以随便写,el 为需要获取焦点的元素

Vue.directive('focus', {
    inserted: function (el) {
        el.focus();
    }
});

实现效果如下

当图书名已经存在则禁用提交按钮

通过 watch 实时验证图书名称是否已经存在

代码实现

在提交按钮定义一个 flag,同样是设置一个变量,默认值设置为 false

<button @click="handle" :disabled="submitFlag">提交</button>

使用 some 来检测 books 数组中是否有 输入的书籍的 name,如果有则禁止提交,如果没有则可以提交

some() 方法会依次执行数组的每个元素:

  • 如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。
  • 如果没有满足条件的元素,则返回false。
watch: {
    name: function(val){
        var flag = this.books.some(function(item){
            return item.name == val
        })
        console.log(flag);
        if(flag){
            this.submitFlag = true
        }else{
            this.submitFlag = false
        }
    }
}

最后我们需要在 Vue 实例的生命周期的 mounted 阶段(渲染之后,可以获取数据生成的DOM对象)来获取图书数据

mounted: function(){
    // 该生命周期钩子函数被触发的时候,模板已经可以使用
    // 一般此时用于获取后台数据,然后把数据填充到模板
    var data = [
        {
            id: 1,
            name: '三国演义',
            date: 2525609975000
        },{
            id: 2,
            name: '水浒传',
            date: 2525609975000
        },{
            id: 3,
            name: '红楼梦',
            date: 2525609975000
        },{
            id: 4,
            name: '西游记',
            date: 2525609975000
        }
    ]
    this.books = data
}

最后的实现效果是一样的

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
好的,下面是一个简单的实现图书管理案例,具体功能如下: 1. 在页面展示图书列表; 2. 在输入框输入图书名称,按回车键实现图书添加功能(图书名称不能为空); 3. 点击“删除”按钮可以实现删除图书。 代码如下: ``` <template> <div> <h2>图书管理</h2> <div> <input type="text" v-model="newBookName" placeholder="请输入图书名称" @keyup.enter="addBook"> <button @click="addBook">添加</button> </div> <table> <thead> <tr> <th>序号</th> <th>图书名称</th> <th>操作</th> </tr> </thead> <tbody> <tr v-for="(book, index) in bookList" :key="book.id"> <td>{{ index + 1 }}</td> <td>{{ book.name }}</td> <td><button @click="deleteBook(index)">删除</button></td> </tr> </tbody> </table> </div> </template> <script> export default { data() { return { bookList: [ { id: 1, name: 'Vue.js 实战' }, { id: 2, name: 'JavaScript 高级程序设计' }, { id: 3, name: 'CSS 世界' } ], newBookName: '' } }, methods: { addBook() { if (this.newBookName.trim() === '') { return } const id = this.bookList.length > 0 ? this.bookList[this.bookList.length - 1].id + 1 : 1 this.bookList.push({ id, name: this.newBookName }) this.newBookName = '' }, deleteBook(index) { this.bookList.splice(index, 1) } } } </script> ``` 这个组件包含了一个输入框、一个添加按钮和一个表格,其表格列出了当前的图书列表。当用户在输入框输入图书名称并按下回车键或点击添加按钮时,会将输入的图书添加到图书列表。当用户点击删除按钮时,会将对应的图书列表删除。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码小余の博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值