Vue学习第二天

vue学习第二天

经过前一天的知识点学习,那么今天我们主要以案例练习为主,多敲代码,提高代码量才是学习编程的王道。

1、key的作用

假设现在有一个需求,在页面循环data中的数组。很简单,有手就行,分分钟写出来。

 <div id="app">
    <ul>
      <li v-for="(item, i) in list">
        <input type="checkbox"> {{item.name}}
      </li>
    </ul>
<script>
    var vm = new Vue({
      el: '#app',
      data: {
        list: [
          { id: 1, name: '诡秘之主' },
          { id: 2, name: '诛仙' },
          { id: 3, name: '惊悚乐园' }
        ]
      }
    });
  </script>
  </div>

写完之后,需求进行升级。要求可以手动在列表的头部添加一本书。好,没问题,有手就行,分分钟写出来。

HTML中添加如下代码:

<form>
  <input type="text" v-model="name">
  <input type="submit" value="添加" @click.prevent="add">
</form>

因为我们需要获取输入框中输入的书籍名称,所以这里使用了v-model数据双向绑定。

那么就需要在vue实例中的data属性中添加一个name属性

data: {
    list: [
        { id: 1, name: '诡秘之主' },
        { id: 2, name: '诛仙' },
        { id: 3, name: '惊悚乐园' }
    ],
    name:""
}

接下来在vue实例的methods属性中实现添加方法。

methods: {
    add(){
        let newPerson = {name: this.name, id: this.list.length + 1};
        this.list.unshift(newPerson);
        this.name = "";
    }
}

好,需求已经实现完了。不过现在,有一个非常严重的问题出现了。什么问题呢?我们来看一下

首先,因为我们使用的是多选框,是可以有选中状态的,所以我们在添加新书之前,先选中诛仙
在这里插入图片描述

然后再添加新书
在这里插入图片描述

这个时候我们发现,诛仙的状态状态被改变了,变成了未选中,诡秘之主从未选中变成了选中,这是为什么呢?

原因

vue和react都实现了一套虚拟DOM,使我们可以不直接操作DOM元素,只操作数据便可以重新渲染页面。而隐藏在背后的原理便是其高效的Diff算法。

vue为了提高效率,在更新已渲染过的元素列表时,会采用“就地复用”策略。

比如一下这个情况:

img

我们希望可以在B和C之间加一个F,Diff算法默认执行起来是这样的:

img

即把C更新成F,D更新成C,E更新成D,最后再插入E,是不是很没有效率?

所以我们需要使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点。
所以一句话,key的作用主要是为了高效的更新虚拟DOM
修改HTML中的代码如下,在被v-for循环的标签中添加:key="item.id" 【注意】key一定要是唯一的。

<ul>
      <li v-for="(item, i) in list" :key="item.id">
        <input type="checkbox"> {{item.name}}
      </li>
</ul>

再次尝试选中诛仙,再添加新书,效果如下:
在这里插入图片描述

2、案例:Tab切换

css样式

* {
    margin: 0;
    padding: 0;
}

ul,
li {
    list-style: none;
}

.tab {
    width: 800px;
    border: 1px solid #000;
}

.tab ul {
    display: flex;
}

.tab li {
    width: 200px;
    height: 50px;
    background: #f00;
    border: 1px solid #000;
    line-height: 50px;
    text-align: center;
}

.tab .tabcont div {
    width: 100%;
    border: 1px solid #00f;
}
.tab .tabcont div img{
    width: 100%;
    vertical-align: top;
}

.tab .active {
    background-color: yellow;
}
<div id="app">
        <div class="tab">
            <ul>
                <li v-for="(item,index) of list" :class="isActive(index)" @click="toggle(index)">{{item.title}}</li>
            </ul>
            <div class="tabcont">
                <div v-for="(item,index) of list" v-show="isShow(index)">
                    <img :src="item.path" alt="">
                </div>
            </div>
        </div>
    </div>
 const vm = new Vue({
            el: '#app',
            data: {
                list: [{
                        id: 1,
                        title: '武则天',
                        path: "img/0.jpg",
                    },
                    {
                        id: 2,
                        title: '李白',
                        path: "img/1.jpg",
                    },
                    {
                        id: 3,
                        title: '伽罗',
                        path: "img/2.jpg",
                    },
                    {
                        id: 4,
                        title: '大乔',
                        path: "img/3.jpg",
                    }
                ],
                cur: 0
            },
            methods: {
                isActive(index) {
                    return index == this.cur ? 'active' : ''
                },
                isShow(index) {
                    return index == this.cur ? true : false
                },
                toggle(index) {
                    this.cur = index;
                }
            }
        });

3、案例: TodoList

3.1 线上案例演示

http://www.todolist.cn/

3.2 案例需求分析

  • 用户输入待办事项,回车后添加进”正在进行“,并清空文本框

  • 在”正在进行"列表项单击,添加进“已经完成”列表

  • 在”已经完成"列表项单击,添加进“正在进行”列表

  • 在相应列表项中单击“删除”,删除该项目

3.3代码

<div id="app">
    <!-- 输入框 -->
    <h1>ToDoList <input type="text" v-model="thing" @keyup.enter="addNew"></h1>

    <!-- 待办列表 -->
    <h2>正在完成 ---{{pending.length}}</h2>
    <ul>
        <li v-for="(item,index) in pending">
            <button @click="addResolve(index)">添加到已完成</button>
            <span>{{item}}</span>
            <button @click="delPending(index)">删除</button>
        </li>
    </ul>

    <!-- 已完成列表 -->
    <h2>已经完成---{{resolve.length}}</h2>
    <ul>
        <li v-for="(item,index) in resolve">
            <button @click="addPending(index)">添加到未完成</button>
            <span>{{item}}</span>
            <button @click="delResolve(index)">删除</button>
        </li>
    </ul>
</div>
 const vm = new Vue({
        el: '#app', //挂载点
        data: {
            thing: '',
            pending: [],
            resolve: []
        },
        methods: {
            // 添加待办事项
            addNew() {
                this.pending.push(this.thing);
                this.thing = ''
            },
            // 单击正在完成项目,切换到已经完成
            addResolve(index) {
                this.resolve.push(this.pending[index]);
                this.pending.splice(index, 1);
            },
            // 单击已经完成项目,切换到正在完成
            addPending(index) {
                this.pending.push(this.resolve[index]);
                this.resolve.splice(index, 1);
            },
            //删除正在完成项目
            delPending(index) {
                this.pending.splice(index, 1);
            },
            // 删除已经完成项目 
            delResolve(index) {
                this.resolve.splice(index, 1);
            }
        }
    });
  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值