vue的filters还没使用过?原来它这么常用!

218 阅读4分钟
过滤器是什么?

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

1. 通过案例理解过滤器

示例: 对于数字价格处理

1.1 结构层中处理价格数字
    <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: 9999,
                priceTwo: 19999,
                priceThree: 29999,
            }
        })
    </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: 9999,
            priceTwo: 19999,
            priceThree: 29999,
        },
        methods:{
            priceHandle(price){
               // 可以写相应的逻辑代码
               ......
               return price
            }
        }
    })
</script>

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

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

##### 1.3 使用filters 过滤器处理数据

注意过滤器的方法定义在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: 9999,
                priceTwo: 19999,
                priceThree: 29999,
            },
            filters:{
                formatPrice(price){
                   // 可以写相应的逻辑代码
                       ......
                       return price
                }
            }
        })
    </script>

其实这个时候,我们甚至连后面的 都可以处理到过滤器中,直接把去掉后在filters的return的参数后面拼接上就可以了。

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: 9999,
            priceTwo: 19999,
            priceThree: 29999,
        },
        filters:{
            formatPrice(price,symbol){
                return symbol+price
            }
        }
    })

</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: 9999,
            priceTwo: 19999,
            priceThree: 29999,
        },
        filters:{
            roundPrice(price){
                return Math.round(price);
            },
            formatPrice(price,symbol){
                return symbol+price
            }
        }
    })

</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: 9999,
            priceTwo: 19999,
            priceThree: 29999,
        },
        filters:{
            roundPrice(price){
                return Math.round(price);
            },
            formatPrice(price,symbol){
                return symbol+price
            }
        }
    })

</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: 9999,
            priceTwo: 19999,
            priceThree: 29999,
        },
        filters:{
            roundPrice(price){
                return Math.round(price);
            },
            formatPrice(price,symbol){
                return symbol+price
            }
        }
    })

    const vm2 = new Vue({
        el:"#example",
        data:{
            price:8888
        }
    })
</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
    })

    const vm = new Vue({
        el: "#app",
        data: {
            priceOne: 9999,
            priceTwo: 19999,
            priceThree: 29999,
        },
        filters:{
            roundPrice(price){
                return Math.round(price);
            }
        }
    })

    const vm2 = new Vue({
        el:"#example",
        data:{
            price:8888
        }
    })
</script>

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

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

6. 过滤器注意事项

6.1 过滤器中的this

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

6.2 过滤器使用的地方

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

好啦 今天这篇文章就算是讲完啦,感谢观看!!