Vue.js列表渲染&关于列表元素的key&列表过滤与排序
索引
- 一、关于key
- 反例
- 正例
- 二、列表过滤(监视器VS.计算属性)
- 监视器实现
- 计算属性实现
- 三、列表排序
饮水思源: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>
<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>
二、列表过滤(监视器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>