今天开发Vue项目,顺手整理一下框架中的常见指令。。。。
一、插值表达式
插值表达式,专业术语称为mastach语法,就是通过两队花括号包含的一个表达式,可以直接执行js表达式语句,方便完成数据和页面的连接。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<p>直接输出变量内容:{{name}}</p>
<p>字符串拼接:{{'姓名'+name}}</p>
<p>js内建函数: {{version.toUpperCase()}}</p>
<p>三元表达式:{{age>18?'成年':'未成年'}}</p>
<p>自定义函数的调用:{{ reverse(version) }}</p>
</div>
<div id="app2">
<span v-bind:title="message">
鼠标悬停几秒钟查看此处动态绑定的提示信息
</span>
</div>
//这里是自己引入的js文件位置,按照自己位置写即可
<script src="./vue.js"></script>
<script>
//el,data,methods都是vue对象中的选项
*let* app = new Vue({
el: '#app',//实例挂在标签的选项
//data中的每个数据都是以键值对的形式存在的
data: {
name: '张三',
version: 'Version1.0',
age: 20
},
methods: {
reverse(*str*) {
//这里简单复习一下字符串和数组的一些内置方法
// split(),括号中写空字符串,代表把str中每个字母切割开,如果不写,代表把str整体作为一个字符串切割
// join(),括号中写空字符串,代表将数组中的每个元素以字符串的形式拼接起来,如果不写,默认以逗号拼接数组中的每个元素
return *str*.split('').reverse().join('')
}
}
})
*let* app2 = new Vue({
el: '#app2',
data: {
message: '页面加载于' + new *Date*().toLocaleString()
}
})
</script>
</body>
</html>
二、vue基础语法(常见指令)
vue中的指令都是**v -**名称固定的语法格式
1、v-text文本渲染指令
注意:如果数据中包含了html标签,不会对其进行解释处理,直接作为字符串显示在页面中
<p>
v-text指令:<span v-text="text"></span>
</p>
2、v-html超文本/富文本渲染指令
注意:(1)与v-text指令不同,v-html指令中如果含有html标签,会对其进行渲染解释,作为代码直接运行;
(2)该指令在实际使用时,一般解释完全安全的数据,可能会造成xss的漏洞。比如,有些可以发表文章的网站,用户文章中含有html语言,会导致在页面中以代码的形式运行,而不是以纯文本的形式展示出来,不满足用户的要求。(备注:此种漏洞,主要是后端开发人员的问题)
<p>
v-html指令:<span v-html="html"></span>
</p>
3、v-once单次加载指令
主要是针对网页中一些特殊的数据进行一次性加载的指令。
那么,什么样的数据,网页中只加载了一次?为什么数据更新的时候这些有单次加载指令的数据不需要更新呢?
回答:网页中的logo,导航菜单,友情链接等类似的视图结构,长时间不会发生变化的数据。
<p>
v-once指令:<span v-html="html" v-once></span>
</p>
4、v-show条件渲染指令
按照条件的真假通过display控制一个元素的显示与隐藏。(比如当用户没有登录时,显示登录或者注册,反之显示欢迎话语)
<p>
v-show网站欢迎语:<span v-show="isLogin">尊敬的用户您好,欢迎访问本系统! </span>
</p>
5、v-if条件渲染指令
根据给定的条件,通过DOM加载完成一个元素的显示/隐藏切换
<p>
v-if网站欢迎语:<span v-if='isLogin'>尊敬的用户您好,欢迎访问本系统!</span>
<span v-else>登录 | 注册</span>
</p>
6、v-bind属性绑定指令
将一个变量的值动态的绑定到标签元素的属性上
<div id="app2">
<span v-bind:title="message">
鼠标悬停几秒钟查看此处动态绑定的提示信息
</span>
</div>
7、v-on事件绑定指令
给指定元素或者标签添加事件处理机制
<button @click="submit">发表留言</button>
<script>
let app = new Vue({
el: '#app',
data: {
// 留言板数据
messageBoards: [{
id: 1,
name: '李白',
publish: '2022-06-06 17:20',
img: './default.jpg',
content: '海客谈瀛洲,烟涛微茫信难求;越人语天姥,云霞明灭或可睹,天姥连天向天横,势拔五岳掩赤城.....'
}]
},
methods: {
submit(e) {
let name = this.messageBoards.name;
let content = this.messageBoards.content;
if (name == undefined || content == undefined) {
alert('输入内容不能为空!');
return;
};
let date = new Date();
let month = date.getMonth() + 1;
let date1 = date.getDate();
let minute = date.getMinutes();
if (month < 10) {
month = '0' + month;
}
if (date1 < 10) {
date1 = '0' + date1;
}
if (minute < 10) {
minute = '0' + minute;
}
let time = date.getFullYear() + '-' + month + '-' + date1 + ' ' + date.getHours() + ':' + minute;
let obj = {
id: this.messageBoards.length > 0 ? this.messageBoards[0].id + 1 : 1,
name: name,
publish: time,
img: './default.jpg',
content: content
};
this.messageBoards.unshift(obj);
this.messageBoards.name = '';
this.messageBoards.content = '';
}
}
})
</script>
8、v-for列表渲染指令
将列表数据进行循环渲染的指令
<div class="box" v-for="item in messageBoards">
<img :src="(item.img)" :title="(item.name)">
<div class="box-right">
<span>{{item.name}}</span>
<span>{{item.publish}}</span><br>
<span>{{item.content}}</span>
</div>
</div>
9、v-model表单数据绑定指令
作用在表单元素上,用于数据双向绑定的执行
<textarea v-model="messageBoards.content" id="mes" cols="30" rows="10"></textarea>
注意:v-model指令绑定数据之后,可以直接操作表单数据,省略原生js获取数据的步骤
三、案例
1、选项卡案例
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{margin: 0; padding: 0; box-sizing: border-box;}
#container{width: 600px;height: 400px;box-shadow: #000 0 0 2px;margin: 20px auto; border-radius: 8px; overflow:hidden;}
ul{list-style:none; height: 50px; display: flex; border-bottom:solid 2px #ddd;}
ul li{flex: 1;text-align: center; line-height: 50px; cursor: pointer;}
ul li.active{background: orangered; color:white;}
#content{position:relative;}
#content div{display: none; position: absolute;left: 0;top: 0; text-align: center;line-height: 100px; font-size: 22px;}
#content div.active{display: block;}
</style>
</head>
<body>
<div id="container">
<ul>
<li :class="activeIndex===0?'active':''"
@click="activeIndex=0">新闻</li>
<li :class="activeIndex===1?'active':''"
@click="activeIndex=1">通知</li>
<li :class="activeIndex===2?'active':''"
@click="activeIndex=2">公告</li>
</ul>
<div id="content">
<div :class="activeIndex===0?'active':''" >新闻内容</div>
<div :class="activeIndex===1?'active':''" >通知内容</div>
<div :class="activeIndex===2?'active':''" >公告内容</div>
</div>
</div>
<script src="./vue.js"></script>
<script>
const app = new Vue({
el: "#container",
data: {
activeIndex: 0 // 当前激活的标题/内容的索引
}
})
</script>
</body>
</html>
2、留言板案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
#app {
width: 900px;
margin: 20px auto;
/* border: 1px solid #000; */
}
#mes {
width: 100%;
height: 200px;
margin: 10px 0;
border: 2px solid #000;
border-radius: 8px;
font-size: 25px;
padding: 20px;
}
#author {
width: 70%;
height: 40px;
line-height: 40px;
vertical-align: middle;
margin: 10px 10px 20px 0;
padding-left: 15px;
outline: none;
}
button {
width: 27%;
height: 45px;
line-height: 45px;
font-size: 18px;
margin: 10px 0px 20px 10px;
vertical-align: middle;
color: #fff;
background-color: #3F48CC;
outline: none;
border: none;
}
.box {
width: 100%;
height: 150px;
padding: 20px 0;
border-bottom: 2px solid #F0F0F0;
}
.box img {
width: 100px;
height: 100px;
float: left;
vertical-align: middle;
}
.box-right {
float: left;
margin-left: 20px;
height: 100%;
vertical-align: middle;
}
.box-right span:nth-of-type(1) {
display: inline-block;
width: 80px;
font-size: 22px;
font-weight: bold;
}
.box-right span:nth-of-type(3) {
display: inline-block;
margin-top: 15px;
font-size: 18px;
}
</style>
</head>
<body>
<div id="app">
<textarea v-model="messageBoards.content" id="mes" cols="30" rows="10"></textarea>
<input type="text" v-model="messageBoards.name" id="author">
<button @click="submit">发表留言</button>
<hr>
<div class="box" v-for="item in messageBoards">
<img :src="(item.img)" :title="(item.name)">
<div class="box-right">
<span>{{item.name}}</span>
<span>{{item.publish}}</span><br>
<span>{{item.content}}</span>
</div>
</div>
</div>
<script src="./vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
// 留言板数据
messageBoards: [{
id: 1,
name: '李白',
publish: '2022-06-06 17:20',
img: './default.jpg',
content: '海客谈瀛洲,烟涛微茫信难求;越人语天姥,云霞明灭或可睹,天姥连天向天横,势拔五岳掩赤城.....'
}]
},
methods: {
submit(e) {
let name = this.messageBoards.name;
let content = this.messageBoards.content;
if (name == undefined || content == undefined) {
alert('输入内容不能为空!');
return;
};
let date = new Date();
let month = date.getMonth() + 1;
let date1 = date.getDate();
let minute = date.getMinutes();
if (month < 10) {
month = '0' + month;
}
if (date1 < 10) {
date1 = '0' + date1;
}
if (minute < 10) {
minute = '0' + minute;
}
let time = date.getFullYear() + '-' + month + '-' + date1 + ' ' + date.getHours() + ':' + minute;
let obj = {
id: this.messageBoards.length > 0 ? this.messageBoards[0].id + 1 : 1,
name: name,
publish: time,
img: './default.jpg',
content: content
};
this.messageBoards.unshift(obj);
this.messageBoards.name = '';
this.messageBoards.content = '';
}
}
})
</script>
</body>
</html>
</html>
留言板案例截图如上
留言板案例截图如上