• Vue.js列表渲染&关于列表元素的key&列表过滤与排序


    饮水思源:https://www.bilibili.com/video/BV1Zy4y1K7SH?p=30&spm_id_from=pageDriver

    一、关于key

    反例

    一个反例,用index作为key出bug

    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="UTF-8" />
      <title></title>
      <script src="JS/vue.js"></script>
    </head>
    
    <body>
      <div id="root">
        <h1>{{header}}</h1>
        <ul>
          <!-- 
            key相当于人类的身份证,保证每条数据的key不同就行 。
            1 key只存在于虚拟DOM中
            2 由于虚拟DOM对比算法,采用index作为key时,如果在开头
              或者中间等地方插入,或者其它一些破坏顺序的操作,可能导致,例如
              key=1对应数据实质上已经替换了(不是同一个人了),言下之意,
              1这个身份证号对应的人突然换了一个,虚拟DOM实际上根据key=1去对
              比两个不同的人来对页面进行更新(错位对比),那么不仅可能造成效率问题,
              也可能导致一些出乎意料的其它问题。结论,尽量不用index做id
          -->
    
          <li v-for="(article, index) in articles" :key="index">
            {{article.title}} --- index = {{index}}
            <input type="text">
          </li>
        </ul>
    
        <button id="btnAdd">添加一篇文章</button>
      </div>
    
      <script>
        const articles = [
          {
            id: 1,
            title: '这个是文章1'
          },
          {
            id: 2,
            title: '这个是文章2'
          },
          {
            id: 3,
            title: '这个是文章3'
          },
        ]
    
        const vm = new Vue({
          el: "#root",
          data: {
            header: "key 的原理探究 --- 一个出错的例子",
            articles: articles,
          },
        })
    
        let i = 4;
        document.querySelector("#btnAdd").addEventListener("click", () => {
          articles.unshift({
            id: i,
            title: `这个是文章${i++}`,
          })
        })
      </script>
    </body>
    

    正例

    修改一下,一个正确的例子,用唯一的id作key:

    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="UTF-8" />
      <title></title>
      <script src="JS/vue.js"></script>
    </head>
    
    <body>
      <div id="root">
        <h1>{{header}}</h1>
        <ul>
          <li v-for="(article, index) in articles" :key="article.id">
            {{article.title}} --- index = {{index}}
            <input type="text">
          </li>
        </ul>
    
        <button id="btnAdd">添加一篇文章</button>
      </div>
    
      <script>
        const articles = [
          {
            id: 1,
            title: '这个是文章1'
          },
          {
            id: 2,
            title: '这个是文章2'
          },
          {
            id: 3,
            title: '这个是文章3'
          },
        ]
    
        const vm = new Vue({
          el: "#root",
          data: {
            header: "key 的原理探究 --- 一个正确的例子",
            articles: articles,
          },
        })
    
        let i = 4;
        document.querySelector("#btnAdd").addEventListener("click", () => {
          articles.unshift({
            id: i,
            title: `这个是文章${i++}`,
          })
        })
      </script>
    </body>
    </html>
    View Code

    二、列表过滤(监视器VS.计算属性)

    效果:

    监视器实现

    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="UTF-8" />
      <title></title>
      <script src="JS/vue.js"></script>
    </head>
    
    <body>
      <div id="root">
        <input type="text" placeholder="请输入文章标题" v-model="keyWord">
        <ul v-show="!searchMode">
          <li v-for="(x, index) in allArticles" :key="x.id">
            #{{index}}# 标题:{{x.title}} 创建时间:{{x.create_time}}
          </li>
        </ul>
        <ul v-show="searchMode">
          <li v-for="(x, index) in filArticles" :key="x.id">
            #{{index}}# 标题:{{x.title}} 创建时间:{{x.create_time}}
          </li>      
        </ul>
      </div>
    
      <script>
        const articles = [
          {
            id: 1,
            title: '文章123',
            create_time: '2022-01-22',
          },
          {
            id: 2,
            title: '文章345',
            create_time: '2022-01-27',
          },
          {
            id: 3,
            title: '文章567',
            create_time: '2022-01-11',
          },
          {
            id: 4,
            title: '文章6789',
            create_time: '2022-01-05',
          },
        ]
    
        const vm = new Vue({
          el: "#root",
          data: {
            allArticles: articles,
            keyWord: "",
            searchMode: false,
            filArticles: [],
          },
          watch: {
            keyWord(newVal) {
              if (newVal === "") {
                this.searchMode = false;
              } else {
                this.searchMode = true;
                this.filArticles = this.allArticles.filter(x => {
                  return x.title.indexOf(newVal) !== -1;
                })
              }
            },
          }
        })
      </script>
    </body>
    </html>

    计算属性实现

    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="UTF-8" />
      <title></title>
      <script src="JS/vue.js"></script>
    </head>
    
    <body>
      <div id="root">
        <input type="text" placeholder="请输入文章标题" v-model="keyWord">
        <ul v-show="!searchMode">
          <li v-for="(x, index) in allArticles" :key="x.id">
            #{{index}}# 标题:{{x.title}} 创建时间:{{x.create_time}}
          </li>
        </ul>
        <ul v-show="searchMode">
          <li v-for="(x, index) in filArticles" :key="x.id">
            #{{index}}# 标题:{{x.title}} 创建时间:{{x.create_time}}
          </li>      
        </ul>
      </div>
    
      <script>
        const articles = [
          {
            id: 1,
            title: '文章123',
            create_time: '2022-01-22',
          },
          {
            id: 2,
            title: '文章345',
            create_time: '2022-01-27',
          },
          {
            id: 3,
            title: '文章567',
            create_time: '2022-01-11',
          },
          {
            id: 4,
            title: '文章6789',
            create_time: '2022-01-05',
          },
        ]
    
        const vm = new Vue({
          el: "#root",
          data: {
            allArticles: articles,
            keyWord: "",
          },
          computed: {
            searchMode() {
              return this.keyWord !== "";
            },
            filArticles() {
              return this.allArticles.filter(x => {
                  return x.title.indexOf(this.keyWord) !== -1;
              })
            }
          }
        })
      </script>
    </body>
    </html>
    计算属性实现.js

    三、列表排序

    效果:

    实现:

    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="UTF-8" />
      <title></title>
      <script src="JS/vue.js"></script>
    </head>
    
    <body>
      <div id="root">
        <input type="text" placeholder="请输入文章标题" v-model="keyWord">
        <button v-on:click="sortByTime">按时间排序</button>
        <button v-on:click="sortByDefault">原顺序</button>
        <ul>
          <li v-for="(article, index) in filArticles" :key="article.id">
            #{{index}}# {{article.title}} 创建时间{{article.create_time}}
          </li>
        </ul>
      </div>
    
      <script>
        const allArticles = [
          {
            id: 1,
            title: '章123',
            create_time: '2022-01-22',
          },
          {
            id: 2,
            title: '文章345',
            create_time: '2022-01-27',
          },
          {
            id: 3,
            title: '章567',
            create_time: '2022-01-11',
          },
          {
            id: 4,
            title: '文章6789',
            create_time: '2022-01-05',
          },
          {
            id: 5,
            title: '文章6789',
            create_time: '2022-01-01',
          },
        ]
    
        const vm = new Vue({
          el: "#root",
          data: {
            keyWord: "",
            sortType: 0, // 0 原顺序 1 按时间排序
          },
          computed: {
            filArticles() {
              let tmpArr = allArticles.filter(article => {
                return article.title.indexOf(this.keyWord) !== -1;
              })
    
              if (this.sortType) {
                tmpArr.sort((a, b) => {
                  return a.create_time > b.create_time ? 1 : -1
                })
              }
    
              return tmpArr
            }
          },
          methods: {
            sortByTime() {
              this.sortType = 1;
            },
            sortByDefault() {
              this.sortType = 0;
            },
          },
        })
      </script>
    </body>
    </html>
  • 相关阅读:
    将kali linux装入U盘 制作随身携带的kali linux
    arch/manjaro linux configuration
    python资源

    JSP通过AJAX获取服务端的时间,在页面上自动更新
    Spark基础
    MapReduce基础
    HDFS基础
    C#输出杨辉三角形
    Java窗体居中显示的2种方法
  • 原文地址:https://www.cnblogs.com/xkxf/p/15827482.html
Copyright © 2020-2023  润新知