Vue学习计划-Vue2--Vue核心(六)过滤器和自定义指令
  OxxiMvcEANtK 2023年12月11日 13 0

1. 过滤器

  1. 定义:对要显示的数据进行特定格式转换再显示(适用于一些简单逻辑的处理)
  2. 语法:
    1. 注册过滤器:Vue.filter(name, callback)new Vue{filters:{}}
    2. 使用过滤器:{{ xx | 过滤器名 }}v-bind:属性 = "xxx | 过滤器名"
  3. 备注:
    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>Document</title>
	    <script src="./vue.js"></script>
	</head>
	<body>
	    <div id="app">
	        <!-- 计算属性 -->
	        <h3>计算属性:</h3>
	        <p>{{ nameUpper }}</p>
	        <hr>
	        <h3>过滤器:</h3>
	        <!-- 过滤器 -->
	        <p>{{ name | nameSliceFilter | nameUpperFilter }}</p>
	        <p>{{ name | nameUpperFilter }}</p>
	        <hr>
	        <!-- 过滤器传参数 -->
	        <!-- <p>{{ longName | nameSliceFilter2(9, '测试传值') }}</p> -->
	        <p>{{ longName | nameSliceFilter2(9) }}</p>
	        <p>{{ longName | nameSliceFilter2() }}</p>
	        <hr>
	        <!-- 属性过滤器 -->
	        <p :name="name | nameSliceFilter | nameUpperFilter">属性过滤器文本</p>
	    </div>
	    <script>
	        const vm = new Vue({
	            el: '#app',
	            data:{
	               name: 'abcdefg',
	               longName: 'abcdefghigklmn'
	            },
	            // 计算属性
	            computed:{
	                nameSlice(){
	                    return this.name.slice(0,3)
	                },
	                nameUpper(){
	                    return this.nameSlice.toUpperCase()
	                }
	            },
	            // 过滤器
	            filters:{
	                nameSliceFilter(val){
	                    // console.log(val);
	                    return val.slice(0,3)
	                },
	                nameUpperFilter(val){
	                    return val.toUpperCase()
	                },
	                // 过滤器传值
	                // 可以传值,传多少个参数,就接收多少参数,但是第一个参数永远是原本数据
	                // nameSliceFilter2(val,length, text){
	                //     console.log(val, length,text);
	                // }
	                // nameSliceFilter2(val, length){
	                nameSliceFilter2(val, length = 3){
	                    console.log(val, length);
	                    return val.slice(0, length)
	                }
	            }
	        })
	    </script>
	</body>
	</html>

示例:(全局过滤器)

	<!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="./vue.js"></script>
	</head>
	<body>
	    <div id="app">
	        <p>{{ name | nameSliceFilter }}</p>
	        <p>{{ longName | nameUpperFilter }}</p>
	    </div>
	    <div id="root">
	        <p>{{ rootName | nameSliceFilter }}</p>
	    </div>
	    <script>
	        // 必须要把全局筛选器提前配置好
	        Vue.filter('nameSliceFilter',(val)=>{
	            return val.slice(0,3) 
	        })
	        // app 实例挂载
	        new Vue({
	            el: '#app',
	            data:{
	                name: 'abcdefg',
	                longName: 'abcdefghigklmn'
	            },
	             // 过滤器
	             filters:{
	                // vue实例内的筛选器优先级更高
	                // nameSliceFilter(val){
	                //     return val.slice(0,4)
	                // },
	                nameUpperFilter(val){
	                    return val.toUpperCase()
	                }
	            }
	        })
	        // root实例挂载
	        new Vue({
	            el: '#root',
	            data:{
	                rootName: '这是rootName的值'
	            },
	        })
	    </script>
	</body>
	</html>

2. 内置指令

  1. v-bind, v-on,v-show...

  2. v-text指令:

    1. 作用:向其所在的节点中渲染文本内容
    2. 与差值语法的区别:v-text会替换掉节点中的内容,{{ xx }} 不会

    示例:

    <body>
      <div id="app">
        <!-- 通常 {{ }} 表较多, 更灵活 -->
        <p>{{ name }}</p>
        <p v-text="name"></p>
        <hr>
        <p>你好, {{ name }}</p>
        <p v-text="name">你好,</p>
        <hr>
        <p>{{ str }}</p>
        <p v-text="str"></p>
      </div>
      <script>
        new Vue({
          el: "#app",
          data:{
            name: "小红",
            str: '<h3>这是个标题</h3>'
          }
        })
      </script>
    </body>
    
  3. v-html指令:

    1. 作用:向指定节点中渲染包含html结构的内容
    2. 与插值语法的区别:
      1. v-html会替换掉节点中所有的内容,{{ xx }}不会
      2. v-html可以识别html结构
    3. 严重注意:v-html有安全问题:
      1. 在网站上动态渲染任意HTML是非常危险的,容易收到XSS攻击
      2. 一定要在可信的内容上使用v-html,永不要在用户提交的内容上

    示例:

        <body>
    	  <div id="app">
    	    <p>{{ str }}</p>
    	    <p v-text="str"></p>
    	    <p v-html="str"></p>
    	  </div>
    	  <script>
    	    new Vue({
    	      el: "#app",
    	      data:{
    	        str: '<h3>这是个标题</h3>'
    	      }
    	    })
    	  </script>
    	</body>
    
  4. v-cloak指令(没有值):

    1. 本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性
    2. 使用css配合v-cloak可以解决网速慢时页面展示出 {{ xx }} 的问题
	<!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="./vue.js"></script>
	  <style>
	    [v-cloak]{
	      display: none;
	    }
	  </style>
	</head>
	<body>
	  <div id="app">
	    <p v-cloak>{{ name }}</p>
	  </div>
	  <script>
	   const vm = new Vue({
	      // el: "#app",
	      data:{
	        name: '小红'
	      }
	    })
	    setTimeout(() => {
	      vm.$mount("#app")
	    }, 5000);
	  </script>
	</body>
	</html>
  1. v-once指令:

    1. v-once所在的节点初次动态渲染后,就视为静态内容了
    2. 以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能

    示例:

    <body>
      <div id="app">
        <!-- 需求: 显示初始值,也显示修改后的值 -->
        <p v-once>初始的n值是:{{ n }}</p>
        <p>当前的n值是:{{ n }}</p>
        <button @click="n++">添加</button>
      </div>
      <script>
       new Vue({
          el: "#app",
          data:{
            n: 8
          }
        })
      </script>
    </body>
    
  2. v-pre指令:

    1. 跳过其所在节点的编译过程
    2. 可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译

    示例:

    <body>
      <div id="app">
        <p v-pre>当前的n值是:</p>
        <p>{{ n }}</p>
        <button @click="n++" >添加</button>
      </div>
      <script>
       new Vue({
          el: "#app",
          data:{
            n: 8
          }
        })
      </script>
    </body>
    
  3. Vue模板语法有2大类:

    1. 插值语法:
      • 功能: 用于解析标签体内容
      • 写法: {{ xx }}, xx是js表达式,且可以直接读取到data中的所有属性
    2. 指令语法:
      • 功能:用于解析标签(包括:标签属性,标签体内容,绑定事件..)
      • 举例:v-bind:href= 'xxx' 或简写 :href= 'xxx' xxx同样要写表达式,且可以直接读取到data中的属性
      • 备注:Vue中有很多的指令,且形式都是:v-???,此处我们只拿v-bind举个例子

3. 自定义指令:

  1. 本质:是一个函数,不靠返回值获取值,靠操作收到的参数去获取值
  2. 作用: 操作DOM元素: 例如v-bind,v-show,v-if等都是对DOM元素进行操作
  3. 两种方式:
    1. 函数式:写法简单,不能操作一些细节
    directives:{
        // big函数何时会被调用?
        //  1. 指令与元素成功绑定时,(初始时)
        //  2. 指令所在的模板被重新解析时
        big(element, binding){
          // element:指令所绑定的元素,可以用来直接操作 DOM
          // binding:一个对象,包含很多属性
          //    value: 指令的绑定值
          //    name: 指令名,不包括 v- 前缀
          //    expression:字符串形式的指令表达式
    
          console.log(element, binding);
          element.innerHTML = binding.value * 10
        }
    }
    
    1. 对象式: 详细的表明执行到某一特定时期,调用特定函数
     directives:{
        fbind:{
          //  指令与元素成功绑定时,(初始时)
          bind(element, binding){
            // console.log('1',element, binding);
            element.value = binding.value
          },
          // 指令所在的元素被插入页面时
          inserted(element, binding){
            // console.log(2,element, binding);
            element.focus()
          },
          // 指令所在的模板被重新解析时
          update(element, binding){
            // console.log(3,element, binding)
            element.value = binding.value
          }
        }
      }
    
    1. 定义语法:
      1. 局部指令:
      new Vue({
      directives:{指令名: 配置对象}
      })
      或
      new Vue({
      directives:{指令名: 回调函数}
      })
      
      1. 全局指令:
      Vue.directive(指令名, 配置对象)
      或
      Vue.directive(指令名, 回调函数)
      
  4. 配置对象中常用的3个回调:
    1. bind: 指令与元素成功绑定时调用
    2. inserted: 指令所在元素被插入页面时调用
    3. update: 指令所在模板结构被重新解析时调用
  5. 备注:
    1. 指令定义时不加v-, 但使用时要加v-
    2. 指令中的this指向的是window
    3. 指令名如果是多个单词,要使用kebab-case命名方式,不要用camelCase命名

示例:(局部指令--对象式)

<!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="./vue.js"></script>
  </head>
  <body>
    <!-- 需求1:写一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍 -->
    <!-- 需求2:写一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素自动获取焦点 -->
    <div id="app">
      <button @click="n++">操作</button>
      <hr>
      <input type="text" v-fbind="n"/>
    </div>
    <script>
      const vm = new Vue({
        el: '#app',
        data:{
          n: 1
        },
        directives:{
          // 函数式:
          // big函数何时会被调用?
          //  1. 指令与元素成功绑定时,(初始时)
          //  2. 指令所在的模板被重新解析时
          // fbind(element, binding){
          //    element.value = binding.value
          //    element.focus()
          // }
          // 对象式:
          fbind:{
            //  指令与元素成功绑定时,(初始时)
            bind(element, binding){
              // console.log('1',element, binding);
              element.value = binding.value
            },
            // 指令所在的元素被插入页面时
            inserted(element, binding){
              // console.log(2,element, binding);
              element.focus()
            },
            // 指令所在的模板被重新解析时
            update(element, binding){
              // console.log(3,element, binding)
              element.value = binding.value
            }
          }
        }
      })
    </script>
  </body>
  </html>

示例:(局部指令--函数式)

<!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="./vue.js"></script>
  </head>
  <body>
    <!-- 需求1:写一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍 -->
    <!-- 需求2:写一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素自动获取焦点 -->
    <div id="app">
      <p>{{ name }}</p>
      <h3>当前的n值是:<span v-text="n"></span></h3>
      <h3>放大10倍后的n值是:<span v-big="n"></span></h3>
      <button @click="n++">操作</button>
    </div>
    <script>
      const vm = new Vue({
        el: '#app',
        data:{
          name: '小红',
          n: 1
        },
        directives:{
          // big函数何时会被调用?
          // 1. 指令与元素成功绑定时,(初始时)
          // 2. 指令所在的模板被重新解析时
          big(element, binding){
            // console.log(element, binding);
            console.log('big');
            element.innerHTML = binding.value * 10
          }
        }
      })
    </script>
  </body>
  </html>

示例:(全局指令)

<!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="./vue.js"></script>
  </head>
  <body>
    <div id="app">
      <h3>当前的n值是:<span v-text="n"></span></h3>
      <!-- <h3>放大10倍后的n值是:<span v-big-number="n"></span></h3> -->
      <h3>放大10倍后的n值是:<span v-big="n"></span></h3>
      <button @click="n++">操作</button>
    </div>
    <hr>
    <div id="root">
      <h3>当前的n值是:<span v-text="n"></span></h3>
      <h3>放大10倍后的n值是:<span v-big="n"></span></h3>
      <button @click="n++">操作</button>
    </div>
    <script>
      Vue.directive('big',(element, binding)=>{
        element.innerHTML = binding.value * 20
      })
      new Vue({
        el: '#app',
        data:{
          n: 1
        },
        directives:{
          // 多个单词的话,推荐使用kebab-case命名
          // 'big-number'(element, binding){
          //   // console.log(element, binding);
          //   console.log('big', this) // this指向window
          //   element.innerHTML = binding.value * 30
          // },
          // 优先级更高
          big(element, binding){
            // console.log(element, binding);
            console.log('big', this) // this指向window
            element.innerHTML = binding.value * 10
          }
        }
      })
      new Vue({
        el: '#root',
        data:{
          n: 1
        },
      })
    </script>
  </body>
  </html>
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年12月11日 0

暂无评论

推荐阅读
  JZjRRktyDDvK   19天前   37   0   0 Vue
  onf2Mh1AWJAW   4天前   12   0   0 Vue
OxxiMvcEANtK