第十节:Vue指令:v-for列表循环

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第十节:Vue指令:v-for列表循环相关的知识,希望对你有一定的参考价值。

参考技术A 用 v-for 指令根据一组数组的选项列表进行渲染。

通过数组的索引获取数组的数据

这种写法在数据很多的时候或者数据发生更新的时候处理就会很繁琐,
因此我们可以使用v-for指令来循环数组

基本数组的循环

v-for 还支持一个可选的第二个参数为当前项的索引。

数组项为对象的循环

使用索引

同时我们也可以用 of 替代 in 作为分割符

语法

示例:

也可以用 v-for 指令来循环对象。

第一个参数是训练遍历对象的属性值:

第二个的参数为对象的属性(键名):

还可以通过第三个参数来获取索引值:

使用 v-for 更新已渲染的元素列表时,默认用 就地复用 策略;列表数据修改的时候,他会根据key值去判断某个值是否修改,如果修改,则重新渲染这一项,否则复用之前的元素; 我们在使用的使用经常会使用 index (即数组的下标)来作为 key ,但其实这是不推荐的一种使用方法;

key值的使用其实是和vue响应式已经虚拟DOM有关, 那么我们通过下面的例子来了解一下

例子:

数据

页面渲染

但是数据发生了变化,

如果数据是这一种变化的话, 那么index没什么问题

数据前后变化的结果

这样vue就会分析到 其他的数据 都不需要改变,只需要在新增一个DOM节点,然后添加新增的数据就可以了

可以输入我们是在数组中间插入的数据就会不一样为了

这时数据的对比

通过上面清晰的对比,发现除了第一个数据可以复用之前的之外,另外三条数据都需要重新渲染;

是不是很惊奇,我明明只是插入了一条数据,怎么三条数据都要重新渲染?而我想要的只是新增的那一条数据新渲染出来就行了

最好的办法是使用数组中不会变化的那一项作为 key 值,对应到项目中,即每条数据都有一个唯一的 id ,来标识这条数据的唯一性;使用 id 作为 key 值,我们再来对比一下向中间插入一条数据,此时会怎么去渲染

此时数据的变化

现在对比发现只有一条数据变化了,就是 id 为4的那条数据,因此只要新渲染这一条数据就可以了,其他都是就复用之前的;

为什么需要key属性: 虚拟DOM的diff算法,

当某一层有很多相同的节点时,也就是列表节点时,Diff算法的更新过程

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

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

所以我们需要使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点。

所以一句话,key的作用主要是为了高效的更新虚拟DOM。另外vue中在使用相同标签名元素的过渡切换时,也会使用到key属性,其目的也是为了让vue可以区分它们,否则vue只会替换其内部属性而不会触发过渡效果。

建议尽可能在使用 v-for 时提供 key ,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。

v-if和v-for一起使用,v-for的优先级要高于v-if

可能会想到v-if和v-for是用的两种情况

那么接下来好好看看这两种情况

第一种情况: 为了过滤一个列表中的项目

为了过滤项目内容,我们可能会如下调用:

在这种情况下,请将 users 替换为一个计算属性(比如 activeUsers ),让其返回过滤后的列表。

示例详解:

如果现在只想显示价格在22元以上的水果,我们可能会这么写

这么写固然会得到你想要的效果, 但是因为v-for和v-if优先级的关系, 所以将会经过如下的运算

因此,哪怕我们只渲染出一小部分内容,也得在每次重新渲染的时候遍历整个列表,无论价格是否满足我们的条件

随意我们推荐使用计算属性, 在计算属性中处理过滤事宜, 计算属性会在计算完毕后缓存内容,提高遍历的效率

这样我们得到的结果是一样的,但是我们获得了如下的好处

第二种情况: 为了避免渲染本应该被隐藏的列表

也就是根据条件类判断列表的显示我们也后可能会使用下面的方法调用

实例详解:

原理是一样的, 就是如果这么写, 还是会循环遍历每一个数据,然后判断是不是显示. 一样浪费

所以我们将 v-if 移动到容器元素,这样我们就不用对每一个元素都进行判断是否显示, 取而代之的是,我们只检查判断一次,且不会在 isShow 为假的时候还循环运算 v-for。

有时,我们想要显示一个数组的过滤或排序副本,而不实际改变或重置原始数据。在这种情况下,可以使用计算属性和方法来过滤数据

我们上面讲过了计算属性,下面来看看方法的使用

总结示例:

自动化测试第十节---多线程继承列表推导发邮件

1、列表推导:

举例:生成100以内奇数的list

 

‘‘‘如果i是数,for循环处理后得到的值i会循环传入number列表‘‘‘
names=[‘nyy‘,‘wxc‘,1234,[‘aaa‘],‘丹丹‘
number=[i for i in range(1,100) if i%2!=0]
print(number)

2、继承
class AxFarther(object):
def __init__(self,op):
self.op=op
print(‘父类:‘,op)
def makeMoney(self):
print("1000W")
# axf=AxFarther(‘抽烟,喝酒‘)#打印“抽烟,喝酒”

# #重写父类的构造方法
class Ax(AxFarther):
def __init__(self,op,code):
print(‘子类:‘,code)
self.code = code
def makeMoney(self):#重写父类的方法
print(‘子类方法:‘, "2000W")
ax=Ax(‘抽烟,喝酒‘,‘python‘)#打印“子类: python”
ax.makeMoney()#打印"子类方法: 2000W"

#修改父类构造方法,在父类构造方法基础上,添加新功能
class Ax(AxFarther):
def __init__(self,op,code):
AxFarther.__init__(self,op)#先把原来的调用一下,有父类的功能,如果想修改父类的构造方法,就先调用以下父类的构造方法,经典类必须这么写,新式类两种都行
# super(Ax,self).__init__(op)#作用同上,super里传的是本类,super会自动找到父类的构造方法
print(‘子类:‘,code)
self.code=code
def makeMoney(self):#重写父类的方法
print(‘子类方法:‘,"2000W")
ax=Ax(‘抽烟,喝酒‘,‘python‘)#打印父类: 抽烟,喝酒/n子类: python
ax.makeMoney()#打印"子类方法: 2000W"

3、多线程
#程序一运行,首先有个主线程
#循环创建10个子线程,让这十个子线程去运行axb这个函数
#主线程继续走,打印了‘game over‘
import threading,time#每个程序默认有一个主线程
def axb(name):
# time.sleep(1)
print(‘hahaha‘,name)
print(time.strftime(‘%Y%m%d%H%M%S‘,time.localtime()))#同时启动,时间一致
for i in range(1000):#循环启动十个线程,执行函数axb,子线程,threading启动的都是子线程
t = threading.Thread(target=axb, args=(i,)) # 实例化一个线程,启动一个线程
t.start()
print(‘game over‘)

#怎么获取到多线程执行的函数里面的返回值
import time, requests,threading
run_times=[]
objs=[]
def blog(url):
s_time=time.time()
r=requests.get(url).text
e_time=time.time()
run_time=e_time-s_time
run_times.append(run_time)
url=‘http://www.nnzhp.cn/archives/527‘
for i in range(100):#通过多线程指定运行的函数,不能获取到函数的返回值
t=threading.Thread(target=blog,args=(url,))
t.start()
objs.append(t)
for obj in objs:#等待所有子线程执行完
obj.join()
avg=sum(run_times)/len(run_times)
print("平均时间是:",avg)
4、多进程
from multiprocessing import Process
import time
def test(i):
time.sleep(1)
print(i)
if __name__==‘__main__‘:
for i in range(10):
p = Process(target=test, args=(i,))
p.start()
5、守护线程
#主线程执行完了,那么不管子线程有没有执行完,都一起结束
import time,threading
def test():
time.sleep(2)
print(‘hahaha‘)
for i in range(5):
t=threading.Thread(target=test)
t.setDaemon(True)#设置子线程为守护线程(此程序中主线程建立完子线程后就结束了,所以什么都打印不出来)
t.start()
6、锁
# from threading import Lock
a=0
# lock=Lock()#申请一把锁
def test():
global a
# lock.acquire()#加锁,python3可以不用手动加锁
a+=1
# lock.release()#解锁,python3可以不用手动解锁
import threading
#多线程在处理一个任务的时候,同时操作一个变量
for i in range(1000):
t = threading.Thread(target=test)
t.start()
print(a)

7、例子:保存多个html-多线程-爬虫
import requests,threading,time
def write_html(url,name):
r = requests.get(url)
with open(name,‘w‘,encoding=‘utf-8‘) as fw:
fw.write(r.text)
urls=[‘www.nnzhp.cn‘,‘besttest.cn‘,‘www.imdsx.cn‘,‘sb.nnzhp.cn‘,‘bbs.besttest.cn‘]
objs = []#存放每个线程
start_time = time.time()
for url in urls:
new_url = ‘http://‘+url
file_name = url+‘.html‘ #www.nnzhp.cn.html
t = threading.Thread(target=write_html,args=(new_url,file_name))
objs.append(t)
t.start()
# t.join()#主线程等待
#.join就是主线程在等待每个子线程执行完成。
#1、先启动10个线程,让他们在跑着
#2、主线程再等他们
# for obj in objs:
# print(‘每次的obj‘,obj)
# obj.join()
# write_html(new_url,file_name)
end_time = time.time()
print(‘程序总共运行了‘,end_time-start_time)
# cases
# a.xls b.xls c.xls
8、发邮件-带有附件
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
# from email.header import Header
def send_mail(sender,pwd,receiver,content,subject,mailhost=‘smtp.qq.com‘,port=465):
msg = MIMEMultipart()
file = ‘a.txt‘
att = MIMEText(open(file, encoding=‘utf8‘).read()) # 发送的附件对象
att["Content-Type"] = ‘application/octet-stream‘
att["Content-Disposition"] = ‘attachment;filename="%s"‘ % file
msg.attach(att) # 把附件添加到邮件里面
msg.attach(MIMEText(content)) # 邮件正文内容添加到msg邮件对象里面
msg[‘Subject‘]=subject
msg[‘From‘]=sender
msg[‘To‘]=receiver

smtp=smtplib.SMTP_SSL(mailhost,port)
smtp.login(sender,pwd)
smtp.sendmail(sender,receiver,msg.as_string())
smtp.quit()
print(‘email send success.‘)

sender = ‘XXX‘ # 发送者账号
pwd = ‘XXX‘ # 发送者密码
receiver = ‘XXX‘
subject = ‘测试邮件标题‘
content = ‘这里是邮件内容‘
send_mail(sender,pwd,receiver,content,subject)

9、发送普通邮件
import smtplib
from email.mime.text import MIMEText
def send_mail(sender,pwd,receiver,content,subject,mailhost=‘smtp.qq.com‘,port=465):
mail=MIMEText(content)
mail[‘Subject‘]=subject
mail[‘From‘]=sender
mail[‘To‘]=receiver
smtp=smtplib.SMTP_SSL(mailhost,port)
smtp.login(sender,pwd)
smtp.sendmail(sender,receiver,mail.as_string())
smtp.quit()
print(‘email send success.‘)

sender = ‘XXX‘ # 发送者账号
pwd = ‘XXX‘ # 发送者密码
receiver = ‘XXX‘
subject = ‘测试邮件标题‘
content = ‘这里是邮件内容‘
send_mail(sender,pwd,receiver,content,subject)
 


 
 

以上是关于第十节:Vue指令:v-for列表循环的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js 循环语句

Vue—列表渲染v-for指令

VUE指令-列表渲染v-for

vue中v-if和v-for指令最好不要同时使用

vue3条件语句和循环语句

vue中的v-for循环指令使用