Anything you can do with a filter you can do with a computed. In Vue 2.0, there won't be filters, so you'll need to use computeds instead.
Fetching data asynchronously into a computed is a somewhat messy problem, which is why there is the vue-async-computed plugin. The difficulty is that the computed has to return a value synchronously, when it hasn't finished fetching data.
The solution is to have the computed depend on a cache of fetched data. If the needed value isn't in the cache, the computed kicks off the async process to fetch it and returns some placeholder value. When the process adds a value to the cache, the computed should notice the change in the cache and return the complete value.
In the demo below, I had to make an auxiliary variable, trigger
, which I reference in the computed just so I know there's been an update. The fetch process increments trigger
, which triggers the computed to re-evaluate. The computed doesn't notice when values are added to or updated in decodedIds
. There may be a better way to deal with that. (Using async computed should make it a non-issue.)
vm = new Vue({
el: 'body',
data: {
messages: [
'Thank you @id-3124324!'
],
decodedIds: {},
trigger: 0
},
computed: {
decodedMessages: function() {
return this.messages.map((m) => this.decode(m, this.trigger));
}
},
methods: {
decode: function(msg) {
var re = /@(id\-\d+)/g;
var matches = msg.match(re);
for (const i in matches) {
const p1 = matches[i].substr(1);
if (!(p1 in this.decodedIds)) {
// Indicate name is loading
this.decodedIds[p1] = '(...)';
// Mock up fetching data
setTimeout(() => {
this.decodedIds[p1] = 'some name';
++this.trigger;
}, 500);
}
}
return msg.replace(re, (m, p1) => this.decodedIds[p1]);
}
}
});
setTimeout(() => {
vm.messages.push('Added @id-12345 and @id-54321.');
}, 1500);
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js"></script>
<div v-for="message in decodedMessages">
{{message}}
</div>