How to use Vue method as image source? - image

in Vue I am trying to use the result from a method as the source for an image:
HTML:
<img :src="getEnergyIcon(type)">
JS:
data() {
return {
energyTypeMap: new Map([
['colorless','#/assets/images/energy-icons/20px-Colorless-attack.png'],
['darkness','#/assets/images/energy-icons/20px-Darkness-attack.png'],
['dragon','#/assets/images/energy-icons/20px-Dragon-attack.png'],
['fairy','#/assets/images/energy-icons/20px-Fairy-attack.png'],
['fighting','#/assets/images/energy-icons/20px-Fighting-attack.png'],
['fire','#/assets/images/energy-icons/20px-Fire-attack.png'],
['grass','#/assets/images/energy-icons/20px-Grass-attack.png'],
['lightning','#/assets/images/energy-icons/20px-Lightning-attack.png'],
['metal','#/assets/images/energy-icons/20px-Metal-attack.png'],
['psychic','#/assets/images/energy-icons/20px-Psychic-attack.png'],
['water','#/assets/images/energy-icons/20px-Water-attack.png'],
])
}
},
And:
methods: {
getEnergyIcon(type){
return this.energyTypeMap.get(type.toLowerCase());
}
},
The method returns the correct path, but the image doesn't use that path as the source:
I want the result to be the same as the hardcoded result, but I want to achieve this by using the method, because I am going to use dynamic data that gives me one of the 11 types, I cannot use hardcoded paths.
I have been Googling around to find a solution but I can't find a solution that uses a direct method as a source for the image. How do I do this?
Thanks in advance.

Found this topic:
How to reference static assets within vue javascript
That mentioned the following:
In a Vue regular setup, /assets is not served.
The images become src="..." strings, instead.
And required me to use:
require();
Which I did like this:
data() {
return {
card: {},
energyTypeMap: new Map([
['colorless',require('#/assets/images/energy-icons/20px-Colorless-attack.png')],
['darkness',require('#/assets/images/energy-icons/20px-Darkness-attack.png')],
['dragon',require('#/assets/images/energy-icons/20px-Dragon-attack.png')],
['fairy',require('#/assets/images/energy-icons/20px-Fairy-attack.png')],
['fighting',require('#/assets/images/energy-icons/20px-Fighting-attack.png')],
['fire',require('#/assets/images/energy-icons/20px-Fire-attack.png')],
['grass',require('#/assets/images/energy-icons/20px-Grass-attack.png')],
['lightning',require('#/assets/images/energy-icons/20px-Lightning-attack.png')],
['metal',require('#/assets/images/energy-icons/20px-Metal-attack.png')],
['psychic',require('#/assets/images/energy-icons/20px-Psychic-attack.png')],
['water',require('#/assets/images/energy-icons/20px-Water-attack.png')],
])
}
},
It has solved my problem.

Related

Vue2 + laravel6 - Component implementation

I just started using Vue2 with Laravel6 and got stuck when trying to understand how to use component method.
As I am totally new for Vue, I am using the official tutorial of Vue as a reference. What I learned from here(https://v2.vuejs.org/v2/guide/components.html) about Vue component instantiation is we give options to a component.(e.g. we give 'template:' options for HTML part.)
When I look at laravel6 codes of resouces/js/app.js, it looks something like this:
Vue.component('example-component', require('./components/ExampleComponent.vue').default);
I looked at js/components/ExampleComponent.vue expecting to see some options declared there. However, there's no option in the ExampleComponent.vue file. Instead, I see <template></template> tag. Apparently, the <template></template> tag seems to work as 'template:' option.
I have two questions regarding above:
Does <template></template> tag have the same meaning as 'template:' option?
If question 1 is yes, are other options also replacable with corresponding tags? (e.g. Can I use <props></props> tag for 'props:' option? or <data></data> tag for 'data:' option?
Thanks in advance!
In Vue world, there are two popular types of defining a component
First Type
in this type, you add all of your HTML inside the template property
and the props add as attribute inside the component object to
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})
Second Type
in this type you add your component logic in a separate file ends with .vue
for example in laravel there is an ExampleComponent.vue file you will find on
it just template tag just as a wrapper for your component content and your logic you can write it as it mentions below.
<template>
// some content here
</template>
<script>
export default {
props: [],
methods: {
},
data(){
return {
}
}
}
</script>
Finally
there is no tag called props or data
for more info read this article

how to pass laravel trans strings to vue component

In the event that you are developing your software using the Laravel framework and need to use the Vue library, you will face some obstacles, including how to access the files translation system provided by Laravel .
like how to access trans('home.var')
Add Language file like this
<messagings v-bind:language="{{ json_encode(trans('messages')) }}"></messagings>
then in vue component print like this
<h4>{{ this.language.messaging }}</h4>
1: pass trans as prop in blade normally just you need to encoding with json used json_encode() method :
<component :trans="{{json_encode(trans('home'))}}"></component>
2: in vue component page you need to decode json data first and set the translation data in some var :
export default {
props:['trans'],
data () {
return {
translation:[],
};
},
created(){
this.setTranslation()
},
methods:{
setTranslation(){
let decoded_trans = JSON.parse(this.trans);
this.transaction = decoded_trans;
}
}
3: Now you can access laravel trans normaly just be careful because vue will not detect if you call last node or first.
<template>
<div>
<h2>{{translation.header.login}}</h2> // this line in laravel mean : trans('home.header.login')
</div>
<template>
Finally I recently started learning vue , so this method may have some flaws, but We all strive to benefit :)

How to pass javascript variable from laravel controller to vuejs component

I'm trying to build a page on Laravel 5.4 which contains few data which needs to be manipulated and then sent across the views. My view contains components of the vuejs v2.0. I want those data to be implemented in the components. I tried using the laracasts PHP Vars to JS transformer but unable to get it. I followed the steps by placing "laracasts/utilities": "~2.0" in my composer.json then I added the serviceprovider as mentioned in the documentation, I published the vendor and added the following in config/javascript.php,
'bind_js_vars_to_this_view' => 'Nitseditor.show',
I'm having a dynamic views folder which is currently inside my Nitseditor\home\resources\views Now in my controller I'm having following codes:
public function show()
{
JavaScript::put([
'foo' => 'bar',
'age' => 29
]);
return view(Nitseditor.show);
}
Now first of all it was throwing an error as I see that it was including use MongoDB\BSON\Javascript; then I removed and tried using use JavaScript
Now in the app.js file which is present in my asset folder, I'm including each components and trying to do console.log(foo); but its throwing an error foo not defined.
There are a few ways to do this depending on what you are trying to achieve and how your project is set up. The simplest way is to make a request to your controller from inside your component that returns json. Laravel 5.4 comes with axios so you can use that:
methods: {
getData(){
axios.get('/controller/route')
.then(response => {
// set your variables from the response
this.myData = response.data;
})
.catch(error => {
console.log(error);
});
},
data(){
return {
myData: {}
}
}
If you need child components to access the data then you would need to put that in the parent and pass myData" using props.
You could also create a directive and pass your variable down directly from your blade template:
Vue.directive('init', {
bind: function(el, binding, vnode) {
vnode.context[binding.arg] = binding.value;
}
});
Then you would just need to do:
<div v-init:vars="{foo: 'foo', age: 29}"></div>
And pass vars as props to any component that needs them:
Here's the JSFiddle: https://jsfiddle.net/3e05qwLh/
If you have multiple descendants that rely on your variables you will probably want to look at using vuex.
Dunno if it helps but I use this method for passing variables to javascript:
// in master layout (head section)
<meta name="foo" content="{{ $foo }}">
// in javascript (included or in the template)
foo = $('meta[name=foo]').attr('content');
If you have javascript in the blade template you can use directly this method:
foo = "{{ $foo }}";

Jquery Ajax autocomplete: action of a controller not available

I was trying to create an autocomplete field using jquery and ajax. I tried the code below but it gives me an error that the action of the controller is not available. Here is the code in my exeternal .js file:
$(function () {
$("#inputfield").autocomplete({
source: '<g:createLink controller="fruit" action="findFruit">'
});
});
And this is the code from my Fruit controller:
def findFruit = {
def fruitsearch= Fruit.withCriteria {
ilike 'fruit', params.term + '%'
}
render (fruitsearch?.'fruit' as JSON)
}
I used firebug to see whats going on, and when I tried an input on the texfield, it says that the action findFruit is not available.
Am I missing something? Or is their something wrong on the code? Thanks
Since your js code is evaluated from an external js file you should try using pure js code instead of grails tags (coz they won't work)
Try using relative path like:
$( "#inputfield" ).autocomplete({
source: '/app-name/controller/action'
});
see if this works.

MVC3 routes interfering with JS paths

I have the following route defined:
routes.MapRoute(name: "StateResults", url: "{state}/{searchTerm}", defaults: new { controller = "Results", action = "SearchState" });
In one of my shared chtml files I have the following defined:
<script src="#Url.Content("Scripts/jquery-1.5.1.js")" type="text/javascript"></script>
I understand why the JS is not getting loaded, but how do I get around this? I get around this?
Thanks.
You can ignore routes for JS
IgnoreRoute("{file}.js");
As an alternative method you can use the constraint parameter to avoid files ending with js
routes.MapRoute("StateResults", "{state}/{searchTerm}",
new { controller = "Results", action = "SearchState" },
new { searchTerm = #".*?([^js])$" }); // regex not tested
RouteCollectionExtensions.MapRoute Method (RouteCollection, String, String, Object, Object) from MSDN
constraints
Type: System.Object
A set of expressions that specify values for the url parameter.
you need to set up the routes that it ignores .js files.
a good description is found here:
http://weblogs.asp.net/rashid/archive/2009/04/03/asp-net-mvc-best-practices-part-2.aspx
something like this will do the trick:
routes.IgnoreRoute("{file}.js");

Resources