李恒道 发表于 2022-3-1 18:21:07

[油猴脚本开发指南]列表渲染

# 列表渲染

在html中如果我们想要循环渲染一段内容该怎么办

使用js+for循环,然后生成一个模板,再插入到html中

但是在vue我们有一个更好的语法糖,就是v-for

# v-for

首先在data声明一个items的数组数据

```
Vue.createApp({
data() {
    return {
      items: [{ message: 'Foo' }, { message: 'Bar' }]
    }
}
}).mount('#array-rendering')
```

在模板中可以直接

```
"item in items"
```

这个时候item就是items数组中的每一个对象

```javascript
<ul id="array-rendering">
<li v-for="item in items">
    {{ item.message }}
</li>
</ul>

```

![图片.png](data/attachment/forum/202203/01/180558rqocdh5qou3zugnq.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

我们还有其他参数,比如可以使用v-for="(item,index) in items"

item,index是可以随便名字的,第一个是对象,第二个则是当前的索引顺序

Vue的数据是

```javascript
Vue.createApp({
data() {
    return {
      parentMessage: 'Parent',
      items: [{ message: 'Foo' }, { message: 'Bar' }]
    }
}
}).mount('#array-with-index')
```

而模板则可以

```javascript
<ul id="array-with-index">
<li v-for="(item, index) in items">
    {{ parentMessage }} - {{ index }} - {{ item.message }}
</li>
</ul>

```

![图片.png](data/attachment/forum/202203/01/180551rzk9xf9o91abf2ak.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

我们也可以使用of代替in来作为分隔符,它更接近js迭代器的语法,但是这里我个人是不太推荐这种写法的

因为个人喜好

# 在v-for使用对象

除了遍历数组,我们也可以直接遍历对象,会直接获取属性的内容

Vue为

```javascript
Vue.createApp({
data() {
    return {
      myObject: {
      title: 'How to do lists in Vue',
      author: 'Jane Doe',
      publishedAt: '2016-04-10'
      }
    }
}
}).mount('#v-for-object')
```

此时模板为

```javascript
<ul id="v-for-object" class="demo">
<li v-for="value in myObject">
    {{ value }}
</li>
</ul>

```

![图片.png](data/attachment/forum/202203/01/180833oznbsihsfijpibi6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

也可以使用()写法,这时第二项是属性名,第三项为index

```javascript
<li v-for="(value, name, index) in myObject">
{{ index }}. {{ name }}: {{ value }}
</li>

```

![图片.png](data/attachment/forum/202203/01/180908krwjz4hju0jl2h2h.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

注意

遍历的时候使用object.keys函数的结果进行遍历,不保证在不同引擎下的结果和顺序一致

# 维护状态

在v-for的情况下,我们通常会就地更新,通常如果想要更高效的运行,需要对每个节点标识一个身份

设置一个的key,目前推荐对每一个v-for都强制设置key



```javascript
<div v-for="item in items" :key="item.id">
<!-- 内容 -->
</div>

```

key只能使用字符串和数值类型

# 数组更新检测

Vue对数组的更新方法进行了封装,如果调用了对应的函数,将会触发视图的重新更新,修改的方法为

```javascript
    push()
    pop()
    shift()
    unshift()
    splice()
    sort()
    reverse()
```

# 替换数组

当调用一些不改变原始数组,返回一个新数组的函数,如fileter,concat,slice等函数

我们直接使用新数组替换旧输入



```javascript
example1.items = example1.items.filter(item => item.message.match(/Foo/))
```

这个时候因为key值和内容值的显示值相等,这个时候重新渲染的损耗依然是非常低的

# 显示排序后的结果

我们可以不变更原始数据,而使用计算属性,返回一个处理后的数据,然后进行渲染

```javascript
data() {
return {
    numbers: [ 1, 2, 3, 4, 5 ]
}
},
computed: {
evenNumbers() {
    return this.numbers.filter(number => number % 2 === 0)
}
}

```

```javascript
<li v-for="n in evenNumbers" :key="n">{{ n }}</li>

```

在计算属性不适用的情况下,我们也可以直接使用函数

但是能使用计算属性的情况下,不要使用函数

因为计算属性存在缓存,相比函数损耗更大

```javascript
data() {
return {
    sets: [[ 1, 2, 3, 4, 5 ], ]
}
},
methods: {
even(numbers) {
    return numbers.filter(number => number % 2 === 0)
}
}

```

```javascript
<ul v-for="numbers in sets">
<li v-for="n in even(numbers)" :key="n">{{ n }}</li>
</ul>

```

# 在v-for使用整数

我们在v-for也可以使用整数,这时候模板将会重复对应个数

```javascript
<div id="range" class="demo">
<span v-for="n in 10" :key="n">{{ n }} </span>
</div>

```

# 在template使用v-for

我们可以在外包裹一层template

这个时候template相当于一个虚拟的元素,仅是在逻辑上的元素,实际渲染的时候不会显示

相比使用div等进行渲染,少渲染了元素,同时在ul内,应使用li渲染,使用template进行循环渲染

更符合html语义和结构

```javascript
<ul>
<template v-for="item in items" :key="item.msg">
    <li>{{ item.msg }}</li>
    <li class="divider" role="presentation"></li>
</template>
</ul>

```

# v-for和v-if组合使用

v-if的优先级更高,同时v-if没用权限访问v-for的变量,还有就是不推荐将二者组合使用

下列例子无法正常运行

```javascript
<!-- 这将抛出一个错误,因为“todo” property 没有在实例上定义 -->

<li v-for="todo in todos" v-if="!todo.isComplete">
{{ todo.name }}
</li>

```

可以将v-for移动到template标签来进行修正

```javascript
<template v-for="todo in todos" :key="todo.name">
<li v-if="!todo.isComplete">
    {{ todo.name }}
</li>
</template>

```

# 在组件使用v-for

我们可以在组件上使用v-for,同时绑定对应的数据

这里使用了v-for和ket

而item和index是传入组件的数据,组件将使用props属性进行接受

```javascript
<my-component
v-for="(item, index) in items"
:item="item"
:index="index"
:key="item.id"
></my-component>

```

unity韩 发表于 2022-3-2 13:18:31

高产哥哥nb

李恒道 发表于 2022-3-2 15:27:53

unity韩 发表于 2022-3-2 13:18
高产哥哥nb

哥哥牛逼!

王一之 发表于 2022-3-4 14:21:38

这和油猴有什么关系呢?

李恒道 发表于 2022-3-4 16:05:26

王一之 发表于 2022-3-4 14:21
这和油猴有什么关系呢?
等开始搞工程化的之后
想直接webpack+element+vue开始撸代码...
这个之前跟哥哥也说过
如果不讲vue基础知识
直接原生js跳成工程化感觉跨越太大了
于是决定水一下vue官方教程,到时候视频顺着讲
然后感觉好像刷一遍文档还不错,我就掺着ast编译结果+文档讲了

Hangover 发表于 2022-3-7 20:53:29

王一之 发表于 2022-3-4 14:21
这和油猴有什么关系呢?

油猴也可以引入vue写脚本,感觉方便很多
页: [1]
查看完整版本: [油猴脚本开发指南]列表渲染