基于 vue.js 实现 task-list的基本管理

Code 可以在如下 git 中获取:
https://github.com/slhuang520/vue

基本的项目结构如下:
在这里插入图片描述

taskList.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>任务列表</title>
    <link rel="stylesheet" href="css/taskList.css">
    <script src="../lib/vue.min.js"></script>
</head>
<body>
    <div class="page-top">
        <div class="page-content">
            <h2>任务计划列表</h2>
        </div>
    </div>

    <div class="main">
        <h3 class="big-title">添加任务</h3>
        <input type="text"
               placeholder="例如:吃饭睡觉打豆豆  提示:+回车就可以添加任务"
               class="task-input"
               @keyup.enter="addTodo()"
               v-model="todo"
        >
        <ul class="task-count" v-show="list.length">
            <li class="msg" v-if="idx==0">{{unCheckedCount}}个未完成任务</li>
            <li class="msg" v-if="idx==1">{{checkedCount}}个完成任务</li>
            <li class="msg" v-if="idx==2">{{list.length}}个所有任务</li>
            <li class="action">
                <a href="#" v-on:click="active(0)" class="active">未完成的任务</a>
                <a href="#" v-on:click="active(1)">完成的任务</a>
                <a href="#" v-on:click="active(2)">所有任务</a>
            </li>
        </ul>

        <h3>任务列表</h3>
        <span v-show="(idx==0 && !unCheckedCount)||(idx==1 && !checkedCount)||(idx==2 && !list.length)">目前还没有添加任何任务</span>
        <div>
            <ol class="list">
                <li v-if="(idx==0 && !obj.isChecked)||(idx==1 && obj.isChecked)||(idx==2)" v-for="obj in list">
                    <div v-show="editItem!=obj">
                        <input type="checkbox" v-model="obj.isChecked"><h4 :class="{completed:obj.isChecked}" @dblclick="edit(obj)">{{obj.name}}</h4><i @click="del(obj)">×</i>
                    </div>
                    <input type="text"
                           class="edit"
                           v-show="editItem && editItem === obj"
                           v-model="editItem.name"
                           v-focus="obj === editItem"
                           @blur="blur(obj)"
                           @keyup.enter="blur(obj)"
                           @keyup.esc="rollback(obj)"
                    >
                </li>
            </ol>
        </div>
    </div>
<script src="js/taskList.js"></script>
</body>
</html>

taskList.js

//使用 localStorage 存储数据
var store = {
    save: function (key, value) { //保存数据
        localStorage.setItem(key, JSON.stringify(value)); // localStorage中只能保存 string
    },
    fetch: function (key) {
        return JSON.parse(localStorage.getItem(key)) || [];
    }
};
var list = store.fetch("task-list");
/*var list = [
    {
        title: "v-for",
        name: " v-for指令需要以 site in sites 形式的特殊语",
        isChecked: false
    },
    {
        title: "Vue.js",
        name: "Vue.js 使用了基于 HTML 的模版语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。",
        isChecked: false
    },
    {
        title: "第二部分",
        name: " 使用原生JS实现jQuery的addClass, removeClass, hasClass函数功能",
        isChecked: true
    },
    {
        title: "获取 class 内容",
        name: "判断获取到的 class 是否为空, 如果不为空在前面加个'空格'",
        isChecked: true
    }
];*/
new Vue({
    el: ".main",
    data: {
        list: list,
        todo: "", //添加的数据
        idx: 0, //选中的 menu 下标
        editItem: "", //当前编辑的任务
        beforeName: "" //记录正在编辑的任务的原来的 name
    },
    watch: {
        // list: function () { // 监听 list 的变化,但不可以监听其子对象的变化
        //     store.save("task-list", this.list);
        // }
        list: {
            handler: function () {
                store.save("task-list", this.list);
            },
            deep: true
        }
    },
    computed: {
        unCheckedCount: function () {
            return this.list.filter(function (item) {
                return !item.isChecked;
            }).length;
        },
        checkedCount: function () {
            return this.list.filter(function (item) {
                return item.isChecked;
            }).length;
        }
    },
    methods: {
        addTodo: function (e) { //添加任务
            this.list.push({
                title: this.todo,
                name: this.todo,
                isChecked: false
            });
            this.todo = "";
        },
        active: function (n) {  //切换 menu
            this.idx = n;
            document.getElementsByClassName("active")[0].className = "";
            window.event.target.className = "active";
        },
        del: function (obj) { //删除任务
            var idx = list.indexOf(obj);
            if (idx != -1) { //判断当前操作的是哪个 menu
                list.splice(idx, 1);
            }
        },
        edit: function (obj) { //编辑
            this.editItem = obj;
            this.beforeName = obj.name;
        },
        blur: function (obj) { //失去光标保存
            this.editItem = "";
        },
        rollback: function (obj) {
            obj.name = this.beforeName;
            this.beforeName = "";
            this.editItem = ""; //退出编辑模式
        }
    },
    directives: {
        focus: { //创建获取焦点的指令
            update: function (el, binding) {
                if (binding.value) {
                    console.log(el, binding);
                    el.focus();
                }
            }
        }
    }
});

taskList.css

@charset "utf-8";

html, body, h2 {
    margin: 0;
    padding: 0;
}
.page-top {
    width: 100%;
    text-align: center;
    background-color: #1b6d85;
}
.page-content {
    padding: 5px;
}
.main {
    width: 80%;
    margin: 0 auto;
}
.task-input {
    width: 100%;
    height: 30px;
    line-height: 30px;
}
.task-count {
    padding: 0;
    border-bottom: 1px solid gray;
}
.task-count li{
    list-style: none;
    margin: 10px;
    display: inline-block;
    height: 22px;
}
.task-count .action {
    float: right;
}
.task-count li a {
    border: 1px solid grey;
    padding: 5px;
    margin: 0;
    text-decoration: none;
    float: left;
}
/*.task-count a::after{
    content: "";
}*/
.task-count li a:not(:first-child) {
    border-left: none;
}
.task-count .msg {
    color: #8c2a1b;
}
.task-count .active {
    background-color: lightgray;
    border-bottom-color: lightgray;
}

.list {
    cursor: pointer;
}
.list li {
    border: 1px solid lightgray;
    position: relative;
    height: 40px;
}
.list li:nth-child(2n) {
    background-color: #eee;
}
.list li:hover {
    background-color: #ddd;
}
.list h4 {
    margin: 0;
    height: 40px;
    line-height: 40px;
    display: inline-block;
    padding-left: 5px;
}
.list i {
    float: right;
    width: 15px;
    height: 15px;
    line-height: 15px;
    border: 1px solid #666;
    border-radius: 50% 50%;
    font-family: monospace;
    margin-top: 12px;
    margin-right: 10px;
    border-radius: 50% 50%;
}
.list i:hover {
    background-color: mediumvioletred;
}
.list .edit {
    width: 90%;
    height: 34px;
    line-height: 34px;
    position: absolute;
    top: 0;
    left: 0;
}
.list .completed {
    color: #aaa;
    text-decoration-line: line-through;
}
.list input[type="checkbox"] {
    width: 28px;
    height: 28px;
    margin-top: 7px;
    float: left;
}

画面结果如下:
在这里插入图片描述

引用\[1\]:根据提供的引用内容,版本3.1.3是vue-awesome-swiper的一个旧版本。引用\[2\]中提到了如何全局引入vue-awesome-swiper,并且需要引入swiper的CSS文件。引用\[3\]中展示了如何在Vue组件中使用vue-awesome-swiper来实现轮播图。根据您的需求,您想要在切换slide时更换app组件的背景。 为了实现这个需求,您可以在vue-awesome-swiper的slide切换事件中,通过修改app组件的背景样式来实现背景的更换。您可以在Vue组件中监听swiper的slideChange事件,并在事件回调函数中修改app组件的背景样式。 下面是一个示例代码,展示了如何实现这个需求: ```javascript <template> <div id="home-swiper"> <swiper ref="homeSwiper" :options="homeSwiperOptions" @slideChange="handleSlideChange"> <swiper-slide>...</swiper-slide> <swiper-slide>...</swiper-slide> </swiper> </div> </template> <script> import { swiper, swiperSlide } from "vue-awesome-swiper"; import "swiper/dist/css/swiper.css"; export default { components: { swiper, swiperSlide, }, methods: { handleSlideChange() { // 在这里修改app组件的背景样式 // 例如:this.$root.$el.style.background = "red"; }, }, }; </script> ``` 在handleSlideChange方法中,您可以根据需要修改app组件的背景样式。例如,您可以使用`this.$root.$el.style.background`来修改app组件的背景颜色。请根据您的具体需求进行相应的修改。 希望这个示例能够帮助您实现轮播图并更换app组件的背景。如果您有任何其他问题,请随时提问。 #### 引用[.reference_title] - *1* [【npm install vue-awesome-swiper@3.1.3 -S 】下载成功但是vue-awesome-swiper 用不了](https://blog.csdn.net/Sonnenlicht77/article/details/126951340)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [关于swiper的两种用法(swiper@4.0.7 vue-awesome-swiper@3.1.3)](https://blog.csdn.net/weixin_52259399/article/details/129066576)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [vue-awesome-swiper @3.1.3使用,记录一些bug及解决方法](https://blog.csdn.net/gegegegege12/article/details/121387965)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值