Migrating from Filters in Vue 3

Migrating from Filters in Vue 3

I've been holding off on learning (and playing) with Vue 3 until it's gotten closer to release, but with Vue 3 in RC it feels like an appropriate time to start digging into it. The docs are in a pretty good state and there is a really well done migration guide that clearly defines the changes and how to update your code.

One of the changes that I'm not a fan of is the removal of filters. Filters provide a way to format text in your display and were one of my favorite Vue.js features. (To be fair, I've got more than one "favorite" Vue feature. ;) In case you haven't seen this feature yet, let's look at a quick example.

First, I set up an application with data:

Vue.config.productionTip = false;
Vue.config.devtools = false;

const app = new Vue({
  el:'#app', 
  data: {
    bio: 'This is a very long line of text that will go on and on and not really be helpful to anyone reading it outside of possibly boring them inti some stupified zombie-like trance which may be desirable in these trying times.'
  }
})

In my DOM, I want to display the bio, but I want to limit the size of it. I can add this to my Vue application:

filters: {
	trim(s) {
		if(s.length < 50) return s;
		return s.substring(0,50-3) + '...';
	}
}

Which then allows this syntax in my DOM:

<div id="app" v-cloak>
 My Bio: {{ bio | trim }}
</div>

Now maybe it's my experience with HTML template languages, but that pipe syntax looks completely natural to me. Here's a complete CodePen of this in play:

See the Pen Filter 1 by Raymond Camden (@cfjedimaster) on CodePen.

Filters also support optional arguments allowing for syntax like so:

<div id="app" v-cloak>
  My Bio: {{ bio | trim(10) }}
</div>

The filter has to be updated of course:

trim(s,len) {
	if(!len) len = 50;
	if(s.length < len) return s;
	return s.substring(0,len-3) + '...';
}

Here's another CodePen for you to play with:

See the Pen Filter 2 by Raymond Camden (@cfjedimaster) on CodePen.

So as I said - I dig this! But it's being removed from Vue 3. Why? The migration guide says this:

While this seems like a convenience, it requires a custom syntax that breaks the assumption of expressions inside of curly braces being "just JavaScript," which has both learning and implementation costs.

This makes sense. I don't like filters going away as a feature, but I can see the logic in this decision. To keep using this logic in a Vue 3 application, you can simply move the filter to a method. Here's how it looks in a Vue 3 application:

const app = {
	data() {
		return {
			bio: 'This is a very long line of text that will go on and on and not really be helpful to anyone reading it outside of possibly boring them inti some stupified zombie-like trance which may be desirable in these trying times.'
		}
	},
	methods: {
		trim(s,len) {
			if(!len) len = 50;
			if(s.length < len) return s;
			return s.substring(0,len-3) + '...';
		}
	}
};

Vue.createApp(app).mount('#app')

You have to change the DOM of course:

<div id="app" v-cloak>
  My Bio: {{ trim(bio) }}
</div>

And here's an example with a custom length:

<div id="app" v-cloak>
  My Bio: {{ trim(bio, 12) }}
</div>

The end result is the same of course. You can see it here:

See the Pen non filter filter by Raymond Camden (@cfjedimaster) on CodePen.

What happens if you forget and use the pipe operator? Vue 3 treats it as a bitwise OR operator leading to unexpected results.

This isn't the only way to move from filters of course. If you knew for a fact that you were always displaying the bio value in a trimmed fashion, you could trim it when the value is retrieved. In my example the value is hard coded, but typically it would be dynamic. Of course, having the original value lets you do things like displaying it in a trimmed fashion and letting the user click to expand.

Be sure to check the Vue 3 migration guide on Filters for more examples and I'll be blogging more about Vue 3 as I start playing with it more.

Photo by Nathan Dumlao on Unsplash

Raymond Camden's Picture

About Raymond Camden

Raymond is a developer advocate. He focuses on JavaScript, serverless and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Comments