美文网首页Vue系列
第十四节:Vue选项:filters过滤器

第十四节:Vue选项:filters过滤器

作者: 曹老师 | 来源:发表于2022-06-11 01:54 被阅读0次
    过滤器是什么?

    过滤器是一种在模板中处理数据的便捷方式, 会经常在其他模板语言中见到, 他们特别适合对字符串和数字进行简单的显示变化.

    1. 通过案例理解过滤器

    示例: 对于数字价格处理

    1.1 Mastache语法中处理价格数字
    <div id="app">
        <!-- 正常处理 -->
        <p>苹果价格:{{ (priceOne/100).toFixed(2) }} 元/斤</p>
        <p>梨子价格:{{ (priceTwo/100).toFixed(2) }} 元/斤</p>
        <p>香蕉价格:{{ (priceThree/100).toFixed(2) }} 元/斤</p>
    
    </div>
    
    <script>   
    
        const vm = new Vue({
            el: "#app",
            data: {
                priceOne: 2312,
                priceTwo: 1825,
                priceThree: 1634,
            }
        })
    </script>
    
    

    我们就会发现一件事情, 同样的逻辑我们要处理三次,这种处理方案,页面需要使用到多少次价格,我们就需要处理多少次相同的逻辑

    我们在回顾到目前为止我们所学的知识, 有什么方方案可以很好的将逻辑抽离出来吗, 计算属性和侦听器显然不合适,因为都需要检测依赖数据的变化, 有多少数据就需要多少的计算属性,和多少的侦听器, 反而不美

    想来想去,定义一个方法通过接受不同的参数来处理我们的相同的逻辑,每次只要调用这个方法就可以了,挺不错的, 尝试一下

    1.2 方法处理相同逻辑
    <div id="app">
        <!--  使用方法处理价格 -->
        <p>苹果价格:{{ priceHandle(priceOne)}} 元/斤</p>
        <p>梨子价格:{{ priceHandle(priceTwo)}} 元/斤</p>
        <p>香蕉价格:{{ priceHandle(priceThree)}} 元/斤</p>
    
    </div>
    
    <script>   
    
        const vm = new Vue({
            el: "#app",
            data: {
                priceOne: 2312,
                priceTwo: 1825,
                priceThree: 1634,
            },
            methods:{
                priceHandle(price){
                    return (price/100).toFixed(2)
                }
            }
        })
    </script>
    
    

    方法也有不美之处,就是寓意化不够明确,所有的事情都需要定义方法来处理, 那么方法的耦合性就会很高

    所以对于数据的先期处理, vue给我们提供了过滤器 filters

    1.3 使用filters 过滤器处理数据

    注意过滤器的方法定义在filters属性中

    <div id="app">
        <!-- 过滤器 filter -->
        <p>苹果价格:{{ priceOne | formatPrice}} 元/斤</p>
        <p>梨子价格:{{ priceTwo | formatPrice }} 元/斤</p>
        <p>香蕉价格:{{ priceThree | formatPrice }} 元/斤</p>
    
    </div>
    
    <script>   
    
        const vm = new Vue({
            el: "#app",
            data: {
                priceOne: 2312,
                priceTwo: 1825,
                priceThree: 1634,
            },
            filters:{
                formatPrice(price){
                    return (price/100).toFixed(2)
                }
            }
        })
    </script>
    
    

    其实这个时候,我们甚至连后面的元/斤 都可以处理到过滤器中

    <div id="app">
        <!-- 过滤器 filter -->
        <p>苹果价格:{{ priceOne | formatPrice}} </p>
        <p>梨子价格:{{ priceTwo | formatPrice }} </p>
        <p>香蕉价格:{{ priceThree | formatPrice }} </p>
    
    </div>
    
    <script>   
    
        const vm = new Vue({
            el: "#app",
            data: {
                priceOne: 2312,
                priceTwo: 1825,
                priceThree: 1634,
            },
            filters:{
                formatPrice(price){
                    return "¥"+(price/100).toFixed(2) +'元/斤'
                }
            }
        })
    
    </script>
    
    

    这样的好处很多, 代码重复更少, 可读性更强, 同时呢,维护性也更好, 如果要更改逻辑,只需要修改一次,而不是每个使用的地方都修改

    2. 过滤器传参

    通过案例,我们也了解了, 过滤器在使用时会将|前面的内容作为过滤器函数的第一个参数,如果过滤器只需要这一个参数时, 过滤器本身不需要加括号

    如果过滤器需要其他参数来动态改变逻辑怎么办,

    这个时候过滤器在使用的时候就可以加括号执行,并传入相应的参数,输入的参数会作为第二个参数传递给过滤器

    例如:

    <div id="app">
        <!-- 过滤器传参 -->
        <p>苹果价格:{{ priceOne | formatPrice("¥")}} </p>
        <p>梨子价格:{{ priceTwo | formatPrice("$") }} </p>
        <p>香蕉价格:{{ priceThree | formatPrice("$") }} </p>
    
    </div>
    
    <script>   
    
        const vm = new Vue({
            el: "#app",
            data: {
                priceOne: 2312,
                priceTwo: 1825,
                priceThree: 1634,
            },
            filters:{
                formatPrice(price,symbol){
                    return symbol+(price/100).toFixed(2) +'元/斤'
                }
            }
        })
    
    </script>
    
    

    这样我们就可以通过传参的方式来动态的改变过滤逻辑

    3. 链式调用过滤器

    过滤器还可以通过链式调用的方式在一个表达式中使用多个过滤器.

    比如我们给刚才的案例添加一个四舍五入到整数的过滤器

    <div id="app">
        <!-- 链式调用过滤器 -->
        <p>
            苹果价格:{{ priceOne | roundPrice | formatPrice("¥")}} 
        </p>
        <p>
            梨子价格:{{ priceTwo | roundPrice | formatPrice("$") }} 
        </p>
        <p>
            香蕉价格:{{ priceThree | roundPrice  | formatPrice("$") }} 
        </p>
    
    </div>
    
    <script>   
    
        const vm = new Vue({
            el: "#app",
            data: {
                priceOne: 2312,
                priceTwo: 1825,
                priceThree: 1634,
            },
            filters:{
                roundPrice(price){
                    return Math.round(price/100);
                },
                formatPrice(price,symbol){
                    return symbol+price.toFixed(2) +'元/斤'
                }
            }
        })
    
    </script>
    
    

    这里首先会调用roundPrice 过来器, 会将价格传入到这个过滤器中处理, 然后在将处理后的结果传给第二个过滤器处理,最后输出到页面上

    4. 属性使用过滤器

    除了在插值,还可以在v-bind中使用过滤器,因为使用了v-bind动态绑定的属性,属性值已经不再是一个字符串,而是一个表达式了

    <div id="app">
        <!-- 动态绑定的属性使用过滤器 -->
    
        <input type="text" :value="priceOne | roundPrice | formatPrice('¥')">
    </div>
    
    <script>   
    
        const vm = new Vue({
            el: "#app",
            data: {
                priceOne: 2312,
                priceTwo: 1825,
                priceThree: 1634,
            },
            filters:{
                roundPrice(price){
                    return Math.round(price/100);
                },
                formatPrice(price,symbol){
                    return symbol+price.toFixed(2) +'元/斤'
                }
            }
        })
    
    </script>
    
    

    5. 还可以通过Vue构造函数注册全局过滤器

    也就是说现在的过滤器是一个组件级的过滤器

    如果我重新new 一个Vue实例, 这个过滤器将不能再另一个实例上使用

    例如

    <div id="app">
    
        <p>苹果价格:{{ priceOne | roundPrice | formatPrice("¥")}} </p>
        <p>梨子价格:{{ priceTwo | roundPrice | formatPrice("$") }} </p>
        <p>香蕉价格:{{ priceThree | roundPrice  | formatPrice("$") }} </p>
    </div>
    
    <div id="example">
        <!-- 在第二个vue实例上不能使用第一个实例的过滤器, -->
        {{ price | roundPrice }}
    </div>
    
    <script>   
    
        const vm = new Vue({
            el: "#app",
            data: {
                priceOne: 2312,
                priceTwo: 1825,
                priceThree: 1634,
            },
            filters:{
                roundPrice(price){
                    return Math.round(price/100);
                },
                formatPrice(price,symbol){
                    return symbol+price.toFixed(2) +'元/斤'
                }
            }
        })
    
        const vm2 = new Vue({
            el:"#example",
            data:{
                price:6123
            }
        })
    </script>
    
    

    如果我们在第二个vue实例上使用过滤器就会报错,

    所以我们可以注册全局过滤器,所有的组件都能使用

    <div id="app">
    
        <p>
            苹果价格:{{ priceOne | roundPrice | formatPrice("¥")}} 
        </p>
        <p>
            梨子价格:{{ priceTwo | roundPrice | formatPrice("$") }} 
        </p>
        <p>
            香蕉价格:{{ priceThree | roundPrice  | formatPrice("$") }} 
        </p>
    </div>
    
    <div id="example">
        {{ price | formatPrice("$") }}
    </div>
    
    <script>   
        // 注册全局过滤器
        Vue.filter("formatPrice",function(price,symbol){
            return symbol+price.toFixed(2) +'元/斤'
        })
    
        const vm = new Vue({
            el: "#app",
            data: {
                priceOne: 2312,
                priceTwo: 1825,
                priceThree: 1634,
            },
            filters:{
                roundPrice(price){
                    return Math.round(price/100);
                }
            }
        })
    
        const vm2 = new Vue({
            el:"#example",
            data:{
                price:6123
            }
        })
    </script>
    
    

    注册的全局过滤器,就可以在vue任何地方都可以使用

    这种方式适合整个应用都会用到的过滤器,

    6. 过滤器注意事项

    6.1 过滤器中的this

    过滤器是唯一不能使用this来访问数据或者其他方法的地方,这一点是故意设计成这样的, 因为过滤器应该是一个纯函数, 也就是对于同样的输入每次都返回同样的输出,而不涉及任何外部数据, 如果想访问外部数据可以通过参数传递.

    6.2 过滤器使用的地方

    另一件注意事项就是过滤器只能在插值和v-bind指令中使用过滤器,但是在Vue1 中,可以在任何可以使用表达式的地方使用过滤器

    相关文章

      网友评论

        本文标题:第十四节:Vue选项:filters过滤器

        本文链接:https://www.haomeiwen.com/subject/hwjvmrtx.html