376 vue指令:v-model (常用),v-text 和 v-html,v-bind (常用),操作样式,v-on,v-for,v-pre,v-once,v-cloak
- 解释:指令 ,Directives, 是带有
v-
前缀的特殊属性,可以在html标签中使用,可以看成特殊的html属性 - 作用:指令提供了一些特殊的功能,当指令绑定到标签上时,可以给标签增加一些特殊的行为
- 比如 : v-model、 v-bind、 v-if、 v-for 等等
- 【本质:底层:DOM 操作。】
指令 : directives
- 解释 : 带有 v-前缀 的特殊属性 , 特殊标记
- 作用 : 提供一些特殊 的功能 , 给 html 添加额外的功能
<div title='哈哈' v-if v-for></div>
- 比如 : v-model v-bind v-text ....
- 位置 : <XXX 位置></XXX>
- 特点 : v- wx:if ng- mg-
- 说明 : v-if、 v-model,底层:DOM 操作
6.1 v-model (常用)
说明 : 用在
表单
元素中, 用来实现数据双向绑定
(input checkbox 等等)
作用 : 将数据txt
和文本框的值
绑定到一起, 任何一方发生改变,都会引起对方的改变
注意 : v-model 在不同类型的表单元素中,该指令的作用不同
<!-- 文本输入框 绑定的是值 -->
<input type="text" v-model="txt" />
<!-- 多选框 绑定的选中状态 -->
<input type="checkbox" v-model="isChecked" />
09-指令1-v-model(重点).html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<!--
指令1 v-model 双向数据绑定
说明 : 把 `input的value值` 和 `data里的msg` 绑定到了一起,一方改变,另外一方也会 跟着改变
调试工具 : devTools
场景 : v-model 一般使用在表单元素上 (单选框 多选框 文本输入框 下拉框 文本域等等)
注意点 : v-model 使用在不同的表单元素上, 绑定的值不一样
v-model 绑定到文本输入框里面 => 绑定是字符串类型的内容
v-model 绑定到多选框里面 ==> 绑定是布尔类型true/false
-->
<div id="app">
<!-- 文本输入框 -->
<input type="text" v-model="msg" />
<!-- <h1 v-model="msg">我是h1</h1> -->
<!-- 多选框 -->
<input type="checkbox" v-model="isChecked" />
<!-- 使用v-bind也可以,动态绑定属性 -->
<input type="checkbox" name="" id="" :checked="isChecked">
<!-- 下面这样不行,只要写了checked,不管值是true、false,都会选 -->
<input type="checkbox" name="" id="buxing" checked>
<button>按钮</button>
</div>
<script src="./vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
msg: '测试信息',
isChecked: false
}
})
document.querySelector('button').onclick = function () {
document.querySelector('#buxing').checked = !document.querySelector('#buxing').checked
}
</script>
</body>
</html>
6.2 v-text 和 v-html
说明 : 设置文本内容
- v-text : 相当于之前的 innerText , 设置文本内容(不识别 html 标签) == 标签内部{
- v-html : 相当于之前的 innerHTML , 设置文本内容(是被 html 标签)
- 数据
msg1: '<a>这是一条信息</a>',
msg2: '<a href="#">我也是一条信息</a>'
10-指令2-v-text和v-html.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<!--
v-text 和 v-html 指令
1、(1)v-text 相当于 之前的 innerText,不能识别标签;(2)和 {{}} 效果是一样的 , 区别: 位置 不一样
2、v-html 相当于 之前 innerHTML,识别标签
-->
<div id="app">
<div v-text="msg1"></div>
<div>{{ msg1 }}</div>
<hr />
<div v-html="msg2"></div>
</div>
<script src="./vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
msg1: '<h1>测试v-text</h1>',
msg2: '<h1>测试v-html</h1>'
}
})
</script>
</body>
</html>
6.3 v-bind (常用)
说明 : 动态绑定数据 (单向) 【由M到V。】
出现原因 : 在 HTML 属性中, 无法使用插值表达式
// 加载静态数据
<a href="https://wbaidu.com">aaa</a>
// 想加载动态数据 {{ }}可以获取data中的数据,但是 {{}} 不能使用在属性中, 只能出现的标签内容里
<a href="{{ src }}">aaa</a>
// 所以使用v-bind
<a v-bind:href="{{ src }}">aaa</a> ok
<img v-bind:src="src"> ok
缩略 : v-bind 全部省略,只留下一个
:
改为 :
<a :href="src">aaa</a> ok
<img :src="src" /> ok
以后 使用
静态加载数据 :<a href="https://wbaidu.com">aaa</a>
动态加载数据 :<a :href="href">aaa</a>
11-指令3-v-bind(重点).html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<!--
1. {{}} 不能用在属性值上, 一般使用在 标签内容部分, <XX>位置</XX>
2. v-bind 动态绑定一个数据 (单向 m => v)
3. v-bind 的语法糖 :属性='data里的一个属性'
4. v-bind 一般使用在属性上, 任意标签皆可使用
5. 动态绑定一个数据, 既然有个{{}},为什么要要有v-bind?
{{}} 用在标签内容上面 , 不能用在属性上 , 所以才会添加 v-bind
-->
<div id="app">
<!-- 静态的显示一个数据 -->
<!-- <div>测试信息</div> -->
<!-- 动态的显示 -->
<!-- <div>{{ msg }}</div> -->
<!-- 假如说使用在属性上面 -->
<!-- 给属性添加一个静态数据 -->
<!-- <div title="测试信息5">我是 div</div> -->
<!-- 给属性添加一个动态的数据,{{}} 不能用在属性值上 -->
<!-- <div title="{{ msg }}">我也是div</div> -->
<!-- 使用v-bind -->
<!-- <div v-bind:title="msg">我也是div</div> -->
<!-- 因为 v-bind 经常使用 语法糖 简写 -->
<!-- <div :title="msg">我也是div</div> -->
<!-- 静态 -->
<!-- <img src="./guisun.png" alt="" /> -->
<!-- 动态 -->
<!-- 第一步 : 属性前面加一个: -->
<!-- 第二步 : 属性值, 用data里的数据 -->
<!--
src='src':把 src 这个 字符串赋值 src 属性
:src='src':把 src对应值=./guisun.png 赋值给 src属性
-->
<img :src="src" alt="" /> <!-- 不要漏掉: -->
</div>
<script src="./vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
msg: '哈哈',
src: './guisun.png'
}
})
</script>
</body>
</html>
6.3.1 v-bind 和 v-model 的区别
// v-model : 数据双向绑定 表单元素上
// : : 动态绑定数据(单向) 任意元素动态读取属性
容易出错点 :
<!-- v-model 数据双向绑定 -->
<!--场景 : 表单元素中 -->
<input type="checkbox" v-model="isChecked1" /> <br />
<!-- v-bind 数据动态绑定 (单向) -->
<!--场景 : 主要用在属性中 -->
<input type="checkbox" :checked="isChecked2" />*
6.4 操作样式
1.操作样式
<!-- 1. 静态类名 -->
<h1 class="red">哈哈</h1>
<!-- 2. 动态类名 -->
<h1 :class="cls">哈哈</h1>
<!-- 3. 最常用 -->
<!-- :class 里的值是一个对象
键 : 类名 (可能会要,也可以不要)
值 : 布尔值, true/false 确定类要不要
-->
<h1 :class="{ red:isRed , fz:isFZ}">哈哈</h1>
<!-- 4. style -->
<h1 :style="{ color : 'red', fontSize : fz + 'px' }">哈哈</h1>
2.其他操作
<!-- 1 -->
<!-- 重点 -->
<div :class="{ active: true }"></div>
===>
<div class="active"></div>
<!-- 2 -->
<div :class="['active', 'text-danger']"></div>
===>
<div class="active text-danger"></div>
<!-- 3 -->
<div :class="[{ active: true }, errorClass]"></div>
===>
<div class="active text-danger"></div>
--- style ---
<!-- 1 -->
<h1 :style="{ color : 'red', fontSize : fz + 'px' }">哈哈</h1>
<!-- fz : 80 -->
<!-- 2 将多个 样式对象 应用到一个元素上-->
<!-- baseStyles 和 overridingStyles 都是对象 -->
<!-- 如果有相同的样式,以后面的样式为准 -->
<div :style="[baseStyles, overridingStyles]"></div>
12-操作样式.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
<style>
.red {
color: red;
}
.fz {
font-size: 50px;
}
</style>
</head>
<body>
<div id="app">
<!-- 1. 静态添加一个类 -->
<!-- <h1 class="red">我是h1</h1> -->
<!-- 2. 动态加 -->
<!-- <h1 :class='dataRed'>我也是h1</h1> -->
<!-- 3. vue推荐我们使用这种 最最常用 -->
<!--
键 : 类名
值 : 布尔值 true/false
-->
<!-- <h1 :class='{ red : isRed,fz : isFz }'>我也是h1了</h1> -->
<!-- 4. 行内样式 -->
<!--
键 : 样式属性
值 : 属性值
-->
<h1 :style='{ color:"blue", bfontSize: fz }'>我肯定也是h1了</h1>
</div>
<script src="./vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
dataRed: 'red',
isRed: true,
isFz: true,
fz: '50px'
}
})
</script>
</body>
</html>
6.5 v-on 指令
注册事件/绑定事件
-
v-on:click 绑定了一个单击事件
:后面是事件名称
<button v-on:click="fn">按钮</button>
-
简写 : @click='fn'
<button @click='fn'>按钮</button>
-
函数写在
methods
里面
fn : function(){ ... }
fn() { ... }
- 函数里面的 this 指的就是 vm 实例
> 在函数里面操作数据
- 获取数据 this.msg
- 修改数据 this.msg = 'XXX'
- 传参
5.1 正常传参
@click='fn(123)'
5.2 事件对象 $event
<!-- 4.1 绑定事件对象的时候, 没有添加小括号,此时,直接在方法中,通过参数 e 就可以获取到事件对象 -->
<!-- 4.2 如果添加小括号,就拿不到事件对象了,vue留了一个$event -->
<button @click="fn1($event,123)">我是按钮</button>
<!-- 实参顺序不重要,形参会和实参对应 -->
<button @click='fn(222, $event)'>我是按钮</button>
13-指令4-v-on(重点).html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<!--
v-on 注册/绑定事件
1. v-on:事件='事件函数'
2. 语法糖 @事件='事件函数'
3. 事件函数写在 methods
-->
<div id="app">
<!-- v-on:事件='事件函数' -->
<!-- <button v-on:click='click1'>我是按钮1</button> -->
<!-- v-on 的语法糖 -->
<button @click='click1'>我是按钮2</button>
</div>
<script src="./vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {},
//绑定事件的事件函数 写在 methods (方法)
methods: {
click1() {
console.log('点击了');
}
},
})
</script>
</body>
</html>
14-事件中的this.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app">
<h1>{{ msg }}</h1>
<button @click='fn'>我是按钮</button>
</div>
<script src="./vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
msg: '信息测试'
},
methods: {
fn() {
// 事件中的this 就是 vm
console.log('点击了啊', this === vm); // 点击了啊 true
this.msg = '666';
console.log(this.msg); // 666
this.fn1() // // 我是 其他函数
this.fn2() // 补充的代码
// 获取数据
// 1. 标签里获取数据: {{ msg }}
// 2. js里获取 数据: this.msg, 设置数据:this.msg='XXX'
},
fn1() {
console.log('我是 其他函数');
},
// 补充的代码
fn2: () => {
console.log('调用了fn1');
console.log(this); // Window,这里的箭头函数指向的是Window
}
},
})
</script>
</body>
</html>
16-事件对象.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<!--
获取 事件对象
1. 不传参 , 直接 在事件函数 里接收一个形参即可 @click='fn' fn(e){ }
2. 传参, vue预留了一个关键字 $event
@click='fn($event, 123)' fn(e,num){}
-->
<div id="app">
<button @click='fn($event,123)'>我是按钮</button>
</div>
<script src="./vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
},
methods: {
fn(e,num){
console.log('点击了',e,num);
}
},
})
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app">
<!-- 实参顺序不重要,形参会和实参对应 -->
<button @click='fn(222, $event)'>我是按钮</button>
</div>
<script src="./vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
},
methods: {
fn(num, e) {
console.log('点击了', num, e); // 点击了 222 MouseEvent {...}
}
},
})
</script>
</body>
</html>
6.6 v-for
- v-for 指令: 遍历数据,为数据中的每一项生成一个指令所在的标签
- 代码
<!-- 需求1 : 最常用 遍历数组 -->
<!-- 作用 : 遍历 list1 数据, 为数据中的每一项生成一个li标签 -->
<!-- item 数组里的每一项元素 -->
<ul>
<li v-for="(item,index) in list1">{{ item }} - {{ index }}</li>
</ul>
<!-- 需求2 : 遍历元素是对象的数组 -->
<ul>
<li v-for="item in list2">{{ item.name }} - id:{{ item.id }}</li>
</ul>
<!-- 需求3 : 遍历对象 -->
<ul>
<li v-for="(item,key) in obj">{{ item }}-{{key}}</li>
</ul>
<!-- 需求4 : 想要生成10个h1,item 从1开始 -->
<h1 v-for="item in 10">我是h1 {{ item }}</h1>
- 重点是遍历数组,其他的了解即可
17-指令5-v-for(重要).html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<!--
v-for 遍历数据(数组), 创建出来对应的(指令所在的)标签
-->
<div id="app">
<ul>
<!-- item 就是 数组元素, index 就是数组 元素对应的索引 -->
<!-- <li v-for='(item,index) in list1' >{{ item }} {{ index }}</li> -->
<!-- 常用的 -->
<!-- <li v-for='item in list2'>{{ item.name }} {{ item.id }}</li> -->
<!-- 遍历对象 -->
<!-- <li v-for='(value,key) in obj'>{{ value }} {{ key }}</li> -->
<!-- 遍历次数 -->
<!-- <li v-for='i in 100'>{{ i }}</li> -->
<li v-for='i in 100'>{{ i - 1 }}</li>
</ul>
</div>
<script src="./vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
list1: ['张三', '李四', '王五'],
list2: [{
id: 1,
name: '马哥'
}, {
id: 2,
name: '傻春'
}, {
id: 3,
name: '浪涛'
}],
obj: {
// key value
name: '傻春',
sex: '不一定'
}
}
})
</script>
</body>
</html>
6.7 v-pre
18-其他指令-v-pre.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<!--
v-pre :不解析
-->
<div id="app">
<h1>{{ msg }}</h1>
<h1 v-pre>{{ msg }}</h1>
<h1>{{ msg }}</h1>
</div>
<script src="./vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
msg: '测试'
}
})
</script>
</body>
</html>
6.8 v-once指令
19-其他指令-v-once.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<!--
v-once : 一旦解析了,不管数据怎么发生改变,都不会再解析 => 只解析一次
-->
<div id="app">
<h1>{{ msg }}</h1>
<h1 v-once>{{ msg }}</h1>
</div>
<script src="./vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
msg: 100
}
})
</script>
</body>
</html>
6.9 v-cloak指令
经测试,必须用属性选择器,否则无效。比如可以使用[v-cloak]、h1[v-cloak],但是只使用标签选择器h1 无效。
20-其他指令-v-cloak.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<!--
-使用{{}} 的时候,偶尔会 出现一个闪烁的过程
{{ num }} => 100
- 使用 v-cloak 指令
- 三步 : 隐藏的工作原理
- 第一步 : 给要遮盖的元素, 添加这个指令
- 第二步 : 根据属性选择器, 找到要遮盖的元素,设 置 display:none
- 第三步 : 当数据解析完毕后, vue会自动删除 v-cloak指令
-->
<div id="app">
<h1 v-cloak>{{ num }}</h1>
<h1>{{ num }}</h1>
</div>
<script src="./vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
num: 100
}
})
</script>
</body>
</html>
七、TODOMVC
一 : 准备工作
-
演示效果 :
-
当前任务:敲代码、视频、游戏
-
git clone https://github.com/tastejs/todomvc-app-template.git
-
安装依赖包 :
npm i