如果我们希望把数据显示到模板(template)中,使用最多的语法是 “Mustache”语法 (双大括号) 的文本插值。
并且我们前端提到过,data返回的对象是有添加到Vue的响应式系统 中,当data中的数据发生改变时,对应的内容也会发生更新。
当然,Mustache中不仅仅可以是data中的属性,也可以是一个JavaScript的表达式:
下面这种写法是语句不是表达式,所以是错误的:
v-once用于指定元素或者组件只渲染一次,当数据发生变化时,元素或者组件以及其所有的子元素将视为静态内容并且跳过,该指令可以用于性能优化。
如果添加到父节点,那么所有的子节点也是只会渲染一次:
用于更新元素的 textContent,等价于"Mustache"语法,而且"Mustache"语法更灵活。
默认情况下,如果我们展示的内容本身是 html 的,那么vue并不会对其进行特殊的解析。如果我们希望这个内容被Vue可以解析出来,那么可以使用 v-html 来展示。
效果如下:
v-pre用于跳过元素和它的子元素的编译过程,显示原始的Mustache标签。
跳过不需要编译的节点,加快编译的速度。
效果如下:
这个指令保持在元素上直到关联组件实例结束编译。
v-cloak 和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到组件实例准备完毕,主要用于解决闪动问题,现在Vue3一般不会出现这个问题了。
<div> 不会显示,直到编译结束。
前面讲的一系列指令,主要是将值插入到模板内容中。但是,除了内容需要动态来决定外,某些属性我们也希望动态来绑定。比如动态绑定a元素的href属性,动态绑定img元素的src属性。
绑定属性我们使用 v-bind: ,缩写 : ,用于动态地绑定一个或多个 attribute,或一个组件 prop 到表达式。
v-bind用于绑定一个或多个属性值,或者向另一个组件传递props值(这个学到组件时再介绍),在开发中,有哪些属性需要动态进行绑定呢?还是有很多的,比如的链接src、网站的链接href、动态绑定一些类、样式等等。
v-bind有一个对应的语法糖,也就是简写方式,在开发中,我们通常会使用语法糖的形式,因为更简洁。
注意 :Vue2 template模板中只能有一个根元素,Vue3 template模板中允许有多个根元素。
在开发中,有时候我们的元素class也是动态的,比如:当数据为某个状态时,字体显示红色,当数据另一个状态时,字体显示黑色。
绑定class有两种方式:对象语法,数组语法。
① 对象语法:我们可以传给 :class (v-bind:class 的简写) 一个对象,以动态地切换 class。
② 数组语法:我们可以把一个数组传给 :class,以应用一个 class 列表;
我们可以利用v-bind:style来绑定一些CSS内联样式,这是因为某些样式我们需要根据数据动态来决定,比如某段文字的颜色,大小等等。
CSS属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名。
绑定style有两种方式:对象语法,数组语法。
① 对象语法:
② 数组语法: :style 的数组语法可以将多个样式对象应用到同一个元素上
在某些情况下,我们属性的名称可能也不是固定的。
前面我们无论绑定src、href、class、style,属性名称都是固定的,如果属性名称不是固定的,我们可以使用 :[属性名]=“值” 的格式来定义,这种绑定的方式,我们称之为动态绑定属性。
如果我们希望将一个对象的所有属性,绑定到元素上的所有属性,应该怎么做呢?非常简单,我们可以直接使用 v-bind 绑定一个对象。
如下:info对象会被拆解成div的各个属性。
前面我们绑定了元素的内容和属性,在前端开发中另外一个非常重要的特性就是交互。
在前端开发中,我们需要经常和用户进行各种各样的交互,这个时候,我们就必须监听用户发生的事件,比如点击、拖拽、键盘事件等等。
在Vue中如何监听事件呢?使用v-on指令。接下来我们来看一下v-on的用法:
我们可以使用v-on来监听一下点击的事件:
v-on:click可以写成@click,是它的语法糖写法:
当然,我们也可以绑定其他的事件:
如果我们希望一个元素绑定多个事件,这个时候可以传入一个对象:
当通过methods中定义方法,以供@click调用时,需要注意参数问题:
情况一:如果该方法不需要额外参数,那么方法后的()可以不添加,并且方法的实现不用参数,直接就可以打印event。
情况二:如果需要同时传入某个参数和event时,可以通过$event传入事件,并且方法的实现必须按顺序写明参数。
@keyupenter 代表enter键d起的时候会调用onEnter方法,我们一般在方法里面获取输入的值:
在某些情况下,我们需要根据当前的条件决定某些元素或组件是否渲染,这个时候我们就需要进行条件判断了。
Vue提供了下面的指令来进行条件判断:
下面我们来对它们进行学习。
v-if、v-else、v-else-if 用于根据条件来渲染某一块的内容,这些内容只有在条件为true时,才会被渲染出来,这三个指令与JavaScript的条件语句 if、else、else if 类似。
v-if 的渲染原理:v-if是惰性的,当条件为false时,其判断的内容完全不会被渲染或者会被销毁掉,当条件为true时,才会真正渲染条件块中的内容。
因为v-if是一个指令,所以必须将其添加到一个元素上,但是如果我们希望切换的是多个元素呢?
如果此时我们使用div包裹,div会被渲染到界面上来,但是我们并不希望div被渲染,这个时候,我们可以选择使用template,template元素可以当做不可见的包裹元素,并且 v-if 可以添加到 template 上,但是最终template不会被渲染出来,类似于小程序中的block。
v-show和v-if的用法看起来是一致的,也是根据一个条件决定是否显示元素或者组件。
首先,在用法上的区别:
其次,本质的区别:
开发中如何进行选择呢?
在真实开发中,我们往往会从服务器拿到一组数据,并且需要对其进行渲染。这个时候我们可以使用v-for来完成,v-for类似于JavaScript的for循环,可以用于遍历一组数据。
v-for的基本格式是 "item in 数组" ,数组通常是来自data或者prop,也可以是其他方式,item是我们给每项元素起的一个别名,这个别名可以自定来定义。
我们知道,在遍历一个数组的时候会经常需要拿到数组的索引,如果我们需要索引,可以使用格式 "(item, index) in 数组" ,注意顺序,数组元素项item在前面,索引项index在后面。
类似于v-if,你可以使用 template 元素来循环渲染一段包含多个元素的内容。
我们使用template来对多个元素进行包裹,而不是使用div来完成,因为div会被渲染,template不会被渲染。而且如果有ul,ul里面不推荐放div,只推荐放li。
Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新,这些被包裹过的方法包括:
上面的方法会直接修改原来的数组,所以视图会跟着更新。但是某些方法不会替换原来的数组,而是会生成新的数组,比如 filter()、concat() 和 slice(),这时候我们可以通过重新赋值的方式触发视图更新,如下:
在使用v-for进行列表渲染时,我们通常会给元素或者组件绑定一个key属性。
这个key属性有什么作用呢?
我们先来看一下官方的解释:key属性主要用在Vue的虚拟DOM算法,在新旧nodes对比时辨识VNodes。如果不使用key,Vue会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法,而使用key时,它会基于key的变化重新排列元素顺序,并且会移除/销毁key不存在的元素。
官方的解释对于初学者来说并不好理解,比如下面的问题:
什么是新旧nodes,什么是VNode?
没有key的时候,如何尝试修改和复用的?
有key的时候,如何基于key重新排列的?
我们先来解释一下VNode的概念:
VNode的全称是Virtual Node,也就是虚拟节点。事实上,无论是组件还是元素,它们最终在Vue中表示出来的都是一个个VNode。VNode的本质是一个JavaScript的对象。
如果我们不只是一个简单的div,而是有一大堆的元素,那么它们应该会形成一个VNode Tree。
我们先来看一个案例:这个案例是当我们点击按钮时会在li中间插入一个f。
我们可以确定的是,这次更新对于ul和button是不需要进行更新,需要更新的是我们li的列表。在Vue中,对于相同父元素的子元素节点并不会重新渲染整个列表,因为对于列表中 a、b、c、d它们都是没有变化的。在 *** 作真实DOM的时候,我们只需要在中间插入一个f的li即可。
那么Vue中对于列表的更新究竟是如何 *** 作的呢?
Vue事实上会对于有key和没有key会调用两个不同的方法,有key,那么就调用 patchKeyedChildren方法,没有key,那么就调用 patchUnkeyedChildren方法。
没有key的diff算法:
我们会发现上面的diff算法效率并不高,c和d来说它们事实上并不需要有任何的改动,但是因为我们的c被f所使用了,所有后续所有的内容都要一次进行改动,并且最后进行新增。
有key的diff算法:
所以我们可以发现,Vue在进行diff算法的时候,会尽量利用我们的key来进行优化 *** 作,在没有key的时候我们的效率是非常低效的,在进行插入或者重置顺序的时候,保持相同的key可以让diff算法更加的高效。
/
图的遍历演示
以邻接多重表为存储结构,实现连通无向图的深度优先和广度优先遍历
以用户指定的结点为起点,分别输出每种遍历下的结点访问序列和相应生成树的边集
/
#include<iostream>
# include <stringh>
# include <malloch>
# include <conioh>
using namespace std;
int visited[30];
# define MAX_VERTEX_NUM 30
# define OK 1
//typedef int VertexType;
typedef int InfoType;
typedef struct ArcNode //弧
{
int adjvex;
struct ArcNode nextarc;
}ArcNode;
typedef struct VNode//表头
{
int data;
ArcNode firstarc;
}VNode,AdjList[MAX_VERTEX_NUM];
typedef struct//图
{
AdjList vertices;
int vexnum,arcnum;
int kind;
}ALGraph;
void CreateDG(ALGraph &G)
{
int k,i,v1;
cout<<endl<<"请输入结点个数: ";
cin>>Gvexnum;
cout<<"请输入弧的个数: ";
cin>>Garcnum;
for(i=1;i<=Gvexnum;i++)//初使化表头
{
Gvertices[i]data=i;
Gvertices[i]firstarc=NULL;
}
for(k=1;k<=Gvexnum;k++) //输入边
{
int v2;
cout<<"请输入与结点"<<k<<"相邻的边数:";
cin>>v2;
cout<<"请输入与第"<<k<<"个结点相连的结点编号: ";
cin>>v1;
ArcNode p;
p=(ArcNode)malloc(sizeof(ArcNode));
if(!p) exit(-1);
p->adjvex=v1;
p->nextarc=NULL;
Gvertices[k]firstarc=p;
for(int i=1;i<v2;i++)
{
int m;
cout<<"请输入与第"<<k<<"个结点相连的结点编号: ";
cin>>m;
ArcNode q;
q=(ArcNode )malloc(sizeof(ArcNode));//动态指针
if(!q) exit(-1);
q->adjvex=m; //顶点给P
q->nextarc=NULL;
p->nextarc=q;
p=q;
//free(q);
}
//free(p);
}
}
void DFS (ALGraph G,int v )//深度搜索
{
visited[v]=1;
cout<<Gvertices[v]data<<" ";
ArcNode x;
x=(ArcNode)malloc(sizeof(ArcNode));
if(!x) exit(-1);
x=Gvertices[v]firstarc;
int w;
for (;x;x=x->nextarc)
{ w=x->adjvex;
if(visited[w]==0)
DFS(G,w);
}
}
void DFSB (ALGraph G,int v)//深度搜索的边集
{
visited[v]=1;
ArcNode y;
y=(ArcNode)malloc(sizeof(ArcNode));
if(!y) exit(-1);
y=Gvertices[v]firstarc;
int u=Gvertices[v]data;
int w;
for(;y;y=y->nextarc)
{ w=y->adjvex;
if(visited[w]==0)
{
cout<<u<<"--->"<<w<<endl;
DFSB(G,w);
}
}
}
typedef struct QNode
{
int data;
QNode next;
}QNode,QueuePtr;
typedef struct
{
QueuePtr front;
QueuePtr rear;
}LinkQueue;
void InitQueue (LinkQueue &Q)//建立一个空队列
{
Qfront=Qrear=(QueuePtr)malloc(sizeof(QNode));
if(!Qfront) exit(-1);
Qfront->next=NULL;
}
void EnQueue (LinkQueue &Q,int e)//进队
{
QNode p;
p=(QNode)malloc(sizeof(QNode));
if(!p) exit(-1);
p->data=e;
p->next=NULL;
Qrear->next=p;
Qrear=p;
//free(p);
}
int DeQueue (LinkQueue &Q,int &e)//出队
{
if(Qfront==Qrear)
return -1;
QNode p;
p=(QNode)malloc(sizeof(QNode));
if(!p) exit(-1);
p=Qfront->next;
e=p->data;
Qfront->next=p->next;
if(Qrear==p)
Qrear=Qfront;
free(p);
return e;
}
int QueueEmpty (LinkQueue Q)//判断队列是否为空
{
if(Qfront==Qrear)
return 1;
return 0;
}
void BFS(ALGraph G,int v)//广度搜索
{
int u;
LinkQueue Q;
InitQueue(Q);
if(visited[v]==0)
{
visited[v]=1;
cout<<Gvertices[v]data<<" ";
EnQueue(Q,v);
while(QueueEmpty(Q)!=1)
{
DeQueue(Q,u);
ArcNode z;
z=(ArcNode)malloc(sizeof(ArcNode));
if(!z) exit(-1);
z=Gvertices[u]firstarc;
/
for(int w=z->adjvex;w>=0;w=z->nextarc->adjvex)
{
if(visited[w]==0)
{
visited[w]=1;
cout<<w<<" ";
EnQueue(Q,w);
}
}/
int w;
for(;z;z=z->nextarc)
{ w=z->adjvex;
if(visited[w]==0)
{
visited[w]=1;
cout<<w<<" ";
EnQueue(Q,w);
}
}
}
}
}
void BFSB (ALGraph G,int v)//广度搜索的边集
{
int u;
LinkQueue Q;
InitQueue(Q);
if(visited[v]==0)
{
visited[v]=1;
EnQueue(Q,v);
while(QueueEmpty(Q)!=1)
{
DeQueue(Q,u);
ArcNode r;
r=(ArcNode)malloc(sizeof(ArcNode));
if(!r) exit(-1);
r=Gvertices[u]firstarc;
int w;
for(;r!=NULL;r=r->nextarc)
{ w=r->adjvex;
if(visited[w]==0)
{
visited[w]=1;
cout<<u<<"--->"<<w<<endl;
EnQueue(Q,w);
}
}
}
}
}
int main()
{
int i;
ALGraph G;
CreateDG(G);
int x;
cout<<"请输入结点数:";
cin>>x;
cout<<"邻接表为:"<<endl;
for(int j=1;j<=x;j++)
{
cout<<Gvertices[j]data<<" ";
ArcNode p;
p=(ArcNode)malloc(sizeof(ArcNode));
if(!p) exit(-1);
p=Gvertices[j]firstarc;
while(p)
{
cout<<p->adjvex<<" ";
p=p->nextarc;
}
cout<<endl;
}
cout<<"请输入第一个要访问的结点序号:"<<endl;
int n;
cin>>n;
for( i=0;i<30;i++)
visited[i]=0;
cout<<"广度搜索:"<<endl;
BFS(G,n);
for( i=0;i<30;i++)
visited[i]=0;
cout<<endl;
cout<<"边集:"<<endl;
BFSB(G,n);
for( i=0;i<30;i++)
visited[i]=0;
cout<<"深度搜索:"<<endl;
DFS(G,n);
for( i=0;i<30;i++)
visited[i]=0;
cout<<endl;
cout<<"边集:"<<endl;
DFSB(G,n);
//system("pause");
return 0;
}
前几天上机刚好做了这个,个人感觉很完美,尽管老师说用的是邻接表而不是多重表,太简单,但还不错,界面输入过程比较繁琐,要严格按照提示来输入,是无向图,等级太低,没办法把执行结果粘出来,应该能看懂吧
#include<iostreamh>
#include<stdlibh>
#include<malloch>
#define maxsize 50
struct arcnode //定义边结点 链表结点
{
int adjvex; //弧头顶点的位置
struct arcnode nextarc; //指向相同弧尾的下一条弧的指针
};
struct vnode //定义顶点结点
{
int data; //顶点数据
struct arcnode firstarc; //指向第一条已该点为弧尾的弧
};
int m,n,v;
void creatgraph (struct vnode a[maxsize]);
void dfstraverse(struct vnode a[maxsize]);
void bfstraverse(struct vnode a[maxsize]);
void main()
{
struct vnode adjlist[maxsize];
int cord;
do
{
cout<<"——主菜单——"<<endl;
cout<<"1建立无向图的邻接表"<<endl;
cout<<"2深度遍历图"<<endl;
cout<<"3广度遍历图"<<endl;
cout<<"4结束程序运行"<<endl;
cout<<"————————————"<<endl;
cout<<"请输入你的选择(1, 2, 3, 4:)"<<endl;
cin>>cord;
switch(cord)
{
case 1:creatgraph(adjlist);
break;
case 2:dfstraverse(adjlist);
break;
case 3:bfstraverse(adjlist);
break;
case 4:exit(0);
}
}while(cord<=4);
}
void creatgraph(struct vnode a[maxsize])
{
//a[maxsize]存放顶点
int i,j,k;
struct arcnode p;
cout<<"请输入边数和顶点数:"<<endl;
cin>>m>>n;
for(k=0;k<n;k++) //初始化
{
a[k]data=k+1;
a[k]firstarc=NULL;
}
cout<<"输入两个相关联的顶点:"<<endl;
for(k=0;k<m;k++) //m代表边数
{
cin>>i>>j;
//输入为无向图
p=(struct arcnode)malloc(sizeof(struct arcnode));
p->adjvex=j; //弧头顶点的位置
p->nextarc=a[i-1]firstarc; //把指向第一条以该点为弧尾的弧给指向相同弧尾的下一条弧的指针
a[i-1]firstarc=p;
p=(struct arcnode)malloc(sizeof(struct arcnode));
p->adjvex=i;
p->nextarc=a[j-1]firstarc;
a[j-1]firstarc=p;
}
cout<<endl;
for(k=0;k<n;k++)
{
cout<<"顶点"<<a[k]data<<"相关联的顶点是:";
p=a[k]firstarc;
while(p)
{
cout<<p->adjvex<<" ";
p=p->nextarc;
}
cout<<endl;
}
}
void dfstraverse(struct vnode a[maxsize]) //深搜
{
struct arcnode p,ar[maxsize]; //ar[maxsize]作为顺序栈,存放遍历过程中边结点的地址
int x,y,i,top=-1;
int visited[maxsize]; //用做存放已遍历过顶点的标记
for(i=0;i<n;i++) //初始化,标记为0
visited[i]=0;
cout<<"输入遍历的第一个顶点"<<endl; //输入遍历的初始点
cin>>x; //输入图遍历的始顶点的编号
cout<<x;
visited[x-1]=1; //标记已访问的顶点
//下一个要遍历的顶点所关联的边结点,向量表的下标从0开始
p=a[x-1]firstarc; //指向第一条已该点为弧尾的弧
while((p) || (top>=0))
{
if(!p)
{
p=ar[top]; //ar[maxsize]作为顺序栈,存放遍历过程中边结点的地址
top--;
}
y=p->adjvex; //弧头顶点的位置
if(visited[y-1]==0) //若未遍历过,则遍历,并且下一个顶点进栈,从本顶点出发继续按深度遍历
{
visited[y-1]=1; //访问后进行标记
cout<<"->"<<y; //输出该顶点
p=p->nextarc; //指向相同弧尾的下一条弧的指针
if(p)
{
top++;
ar[top]=p; //ar[maxsize]作为顺序栈,存放遍历过程中边结点的地址
}
p=a[y-1]firstarc;
}
else
p=p->nextarc;
}
cout<<endl;
}
void bfstraverse(struct vnode a[maxsize]) //广搜
{
//数组a[max]为顺序栈列存放刚遍历过的顶点号
struct arcnode p;
int x,y,i,front=-1,rear=-1,ar[maxsize],visited[maxsize];//数组ar[maxsize]为顺序队列存放刚遍历过的顶点号
for(i=0;i<n;i++) //初始化标记数组
visited[i]=0;
cout<<"输入遍历的第一个顶点"<<endl;
cin>>x;
cout<<x;
visited[x-1]=1;
p=a[x-1]firstarc; //指向第一条已该点为弧尾的弧
while((p) || (front!=rear))
{
if(!p)
{
front++;
y=ar[front];
p=a[y-1]firstarc; //指向第一条已该点为弧尾的弧
}
y=p->adjvex; //弧头顶点的位置
if(visited[y-1]==0) //遍历顺点并插入队列
{
visited[y-1]=1;
cout<<"->"<<y;
rear++;
ar[rear]=y;
}
p=p->nextarc; //指向相同弧尾的下一条弧的指针
}
cout<<endl;
}
以上就是关于Vue3基础-模板语法全部的内容,包括:Vue3基础-模板语法、编程实现以邻接表或邻接矩阵为存储结构,图的广度和深度优先搜索、用邻接矩阵存储无向图,并用深度优先和广度优先遍历搜索输出序列,要能运行的,并把运行的结果截图下来等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)