link2055 link2056 link2057 link2058 link2059 link2060 link2061 link2062 link2063 link2064 link2065 link2066 link2067 link2068 link2069 link2070 link2071 link2072 link2073 link2074 link2075 link2076 link2077 link2078 link2079 link2080 link2081 link2082 link2083 link2084 link2085 link2086 link2087 link2088 link2089 link2090 link2091 link2092 link2093 link2094 link2095 link2096 link2097 link2098 link2099 link2100 link2101 link2102 link2103 link2104 link2105 link2106 link2107 link2108 link2109 link2110 link2111 link2112 link2113 link2114 link2115 link2116 link2117 link2118 link2119 link2120 link2121 link2122 link2123 link2124 link2125 link2126 link2127 link2128 link2129 link2130 link2131 link2132 link2133 link2134 link2135 link2136 link2137 link2138 link2139 link2140 link2141 link2142 link2143 link2144 link2145 link2146 link2147 link2148 link2149 link2150 link2151 link2152 link2153 link2154 link2155 link2156 link2157 link2158 link2159 link2160 link2161 link2162 link2163 link2164 link2165 link2166 link2167 link2168 link2169 link2170 link2171 link2172 link2173 link2174 link2175 link2176 link2177 link2178 link2179 link2180 link2181 link2182 link2183 link2184 link2185 link2186 link2187 link2188 link2189 link2190 link2191

[Vue.js] How to replace component when v-bind is already used and it's inside loop

The problem I’m encountering is like this.

<div v-for=”(obj, index) in objects”>
<button @click=”changeComponent(index, ‘A’)>Change to A</button>
<button @click=”changeComponent(index, ‘B’)>Change to B</button>
<ComponentA v-bind:obj=”obj” />
</div>

components: {
ComponentA,
ComponentB,
}
data() {
return {
objects: [
{ name: ‘A’ }
]
}
},
methods: {
changeName(index, name) {
this.objects[index].name = name
}
}

What to do is to replace component depending on the obj’s name.
However there are some problems. First I thought I could use v-bind:is but I already used v-bind to pass value to child component. Second even if I can use v-bind:is I still don’t know how to access to its index in computed method. Is there other good way to do it? How can I solve this problem?

Solution :

You need to use :is to set the component. You can also bind props with this. Something like this should work

<div v-for=”(obj, index) in objects”>
<button @click=”changeComponent(index, ‘A’)>Change to A</button>
<button @click=”changeComponent(index, ‘B’)>Change to B</button>
<component :is=”objToComponent[obj.name]“ v-bind:obj=”obj” />
</div>

components: {
ComponentA,
ComponentB,
}
data() {
return {
objects: [
{ name: ‘A’ }
],
objToComponent: {
‘A’: ‘ComponentA’,
‘B’: ‘ComponentB’
}
}
},
methods: {
changeName(index, name) {
this.objects[index].name = name
}
}

The main changes are:

added an object that maps names to component names, so vue.js know what you want to render
used :is so you are able to change the component based on obj.name

Solution 2:

Well, to do so, you can use :is for making the dynamic component.

Used for dynamic components and to work around limitations of in-DOM templates.

Here is the working JsFiddle

Here is the official docs

Hope this helps

[Vue.js] Content size - Vuetify

I’m trying that the lower right component will fill all its space,
I’ve placed a div element but for some reason, it won’t fill out the whole width
it to fill everything from the sidebar to the end (also full height).
I don’t want to use CSS positioning for this.
I tried width: 100% but it doesn’t work

code:

<template>
<div>
<v-navigation-drawer v-model=”drawer” clipped fixed app>
<v-list dense>
<v-list-tile class=”mt-3” @click>
<v-list-tile-action>
<v-icon color=”darken-1”>add_circle_outline</v-icon>
</v-list-tile-action>
<v-list-tile-title>Subscribe</v-list-tile-title>
</v-list-tile>
<v-list-tile disabled @click>
<v-list-tile-action>
<v-icon>dashboard</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>Dashboard</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
<v-list-tile disabled @click>
<v-list-tile-action>
<v-icon>settings</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>Settings</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
</v-list>
</v-navigation-drawer>
<v-toolbar app fixed clipped-left>
<v-toolbar-side-icon @click.stop=”drawer = !drawer”></v-toolbar-side-icon>
<v-toolbar-title>Application</v-toolbar-title>
</v-toolbar>
<div class=”editor” style=”border: 1px solid red; width: 100%;”>
<v-flex xs12 sm6 md3>
<v-text-field
readonly
label=”Regular”
placeholder=”Placeholder”
\></v-text-field>
</v-flex>

</div>
<v-footer app fixed>
<span>© 2017</span>
</v-footer>
</div>
</template>

<script>
export default {
data: () => ({
drawer: null
}),
props: {
source: String
}
};
</script>

Solution :

You are missing the v-content. You need to replace your

<div class=”editor” style=”border: 1px solid red; width: 100%;”>
<v-flex xs12 sm6 md3>
<v-text-field
readonly
label=”Regular”
placeholder=”Placeholder”
\></v-text-field>
</v-flex>

</div>

with:

<v-content>
<v-container fluid style=”border: 1px solid red;”>
<v-text-field
readonly
label=”Regular”
placeholder=”Placeholder”
\></v-text-field>
</v-container>
</v-content>

Here is a Codepen.
You can read more about it Here.

And as you add more elements to the v-container it will expand in height.

If you add fill-height to v-container, it will take the whole height.

[Vue.js] How to access a vue component method from another app?

there is this code that works fine in pure html/javascript, but not in vuejs. there is this function named myMethod().
When debugging in the javascript console,I can access it like this: myMethod(“toto”). But in vuejs it is only accessible like this: $vm0.myMethod(“toto”).

I absolutely need it to be accessible like this: myMethod(“toto”).

Is that even possible in vue?

Thanks in advance.

Solution :

For non-parent-child relation, then this is the same as this one. Call one method, apparently any method of a component from any other component. Just add a $on function to the $root instance and call form any other component accessing the $root and calling $emit function.

On First component

….
mounted() {
this.$root.$on(‘component1’, () => {
// the code goes here
this.c1method()
}
}

and in the second component call the $emit function in $root


c2method: function(){
this.$root.$emit(‘component1’) //like this
},

It acts more like a socket. Reference here

https://stackoverflow.com/a/50343039/6090215

[Vue.js] How to customize Webpack error overlay output message?

to customize the error overlay output message so that it won’t show any paths to loaders, like in the image:

So how can I get rid of the line similar to the above from the overlay output?

Solution :

So I’ve done some reverse engineering work and found out that it’s webpack-dev-server itself which is displaying it and it cannot be edited by any setting/option. So I had to do some dirty hack which simply extends overlay’s showMessage() method and removes fist two lines (which contain paths to loaders). My dirty workaround looks like this:

const overlay = require(‘webpack-dev-server/client/overlay’);
const show = overlay.showMessage;
overlay.showMessage = function (messages) {

const newMessages = messages.map(
msg => msg
.split(‘\n’)
.slice(2)
.join(‘\n’)
);

show(newMessages);
};

[Vue.js] How can I use vue-logger in the vuex store?

I cannot get vue-logger to work in my Vuex store file(s)

I would like to use vue-logger in my Vuex store file (and modules). However, I keep getting the error: “TypeError: Cannot read property ‘info’ of undefined” when I execute a statement like “Vue.log.info(….)”.

I had a similar problem with using “this.$http.get” in the store file, but that works now by using the “Vue.http.get” (as explained in this StackOverflow Answer).
However, “this.$log.info” does not work (for reasons obvious to me now, as in the store when outside of the vue.js instance), but neither does “Vue.log.info”.

How can I use vue-logger in the store?

Solution :

Try to use Vue.$log.info.

Notice the extra $ before log.

[Vue.js] How to bind events on raw (imported) html via code?Edit

I’m importing a html containing SVG code and render it via v-html directive, but I need to bind click events to the a-html tags from that file which aren’t part of my template.

How do I get all the a-tag from that imported file?
And how do I bind events to these elements whitout using v-on directive?

The template

<v-flex mt-2 px-0 xs6
ref=”map_svg”
v-html=”mapHTML”>
</v-flex>

Snippet of the imported file

<svg>
<g>
<g>
<a target=”_blank” xlink:href=”url to a subsite” >
<!– content path which shows a circle –>
</a>
</g>
<g>
<a target=”_blank” xlink:href=”url to a differnt subsite” >
<!– content path which shows a circle –>
</a>
</g>

<!– many more elements like shown on the top –>
</g>
</svg>

I would need to bind an click event to these a-tags and remove or overwrite the xlink:href attribute so the click won’t open a different tab in the browser.

Edit

I ended up doing it like this:

mounted() {

const that = this;
const links = this.$el.querySelectorAll(‘#map_svg svg > g > g > a’);

links.forEach(el => {
const url = el.getAttribute(‘xlink:href’);
if (url) {
// el.addEventListener(‘click’, that.stationClick(url));
el.onclick = function (){
that.stationClick(url);
}
el.removeAttribute(‘xlink:href’);
}
el.removeAttribute(‘target’);
});
},

Solution :

You can bind click events on those elements after you have loaded the svg:

export default {
name: “App”,
data() {
return {
mapHTML: null
};
},
methods: {
async loadSvg() {
// Here, you load the svg
this.mapHTML = `
<a href=”https://google.fr" _target=”blank”>Google</a>
`;

// You need to use $nextTick in order to wait for the DOM to be refreshed
this.$nextTick(() => {
this.bindClicks() // You bind click events here
})

},
bindClicks () {
// You search for all the a tags in the svg_container
this.$refs.map_svg.querySelectorAll(‘a’).forEach(el => {
el.removeAttribute(‘_target’) // You remove the _target attribute
el.addEventListener(‘click’, this.handleClick) // You bind an event listener to the element
})
},
handleClick (e) {
// You handle the click like you would normally do
e.preventDefault()
}
}
};

Solution 2:

You can use the ref you set and plain JS to bind to the tags.

this.$refs.map_svg.querySelectorAll(‘a’).forEach(item => item.addEventListener(‘click’, this.callback) )

[Vue.js] Emitting functions up to parent to refresh props?

when struggling a bit for a decent way of handling passing data down when using frameworks like React and Vue. For a vue.js project I’m working on, I’ve been using this approach and want to make sure it makes sense.

Right now, there is my parent make a “Master” API call to get the whole Customer object. I pass Customer as a prop to the child component. The child component uses the value of Customer.address to prefill an input field. If that field is updated, the child makes an api call to post the new data, then I emit a function back up to the parent to call the “Master” function and get a new copy of the Customer object so that the props it passes down are refreshed. Does this make sense?

Parent.vue

<template>

<Child
:customer = “this.customer”
@handleGetCustomerData = “getCustomerData”
\>

</Child>

</template>

<script>

export default {

data() {
customer = {}
}
mounted() {
this.getCustomerData()
},
methods: {

getCustomerData: function() {
axios
.get(‘/api/customer’)
.then(response => {
this.customer = response
};
}
}
}

</script>

Child.vue

<template>

<div>
<input :value=”customer.address” ref=”address”>
<button
v-on:click=”updateAddress()”>
Update Address
</button>

</div>

</template>

<script>
export default {

props: {
customer: {type: Object}
},

methods: {

updateAddress() {
axios.post(‘/api/address’, {
address: this.$refs.address.value
})
.then(response => {
this.handleGetCustomerData()
});

handleGetCustomerData() {
this.$emit(‘handleGetCustomerData’)
}

}
}

</script>

Solution :

It makes sense, of course. We use props to communicate parent -> child and events to communicate child -> parent.

You’re doing it correctly but you could get some problems and complex debugging calling API inside the child component. I would just $emit some “updateAddress” passing this.$refs.address.value as param and calling API inside parent component.

Doing it, you can centralize API callings and refreshs, updating childs’ data always via props.

Hope it helps! Here is a great article about it.

Solution 2:

I don’t know vue.js but in React I would not let the child handle the API requests at all. The logic should be in one place (in parent) and then the flow would look something like that:

(Parent) Get the object and pass as a prop
(Child) When you update the field, the child runs a callback from a parent
(Parent) Executes the api request and then get’s the updated object and updates the props

[Vue.js] How to trigger the Enter key press event on URL hash modification?

Sandbox here.

there is links organized inside <li> elements. On a click event, I change the URL of the page to the corresponding <div> id element in the page.

Now, so when looking for a way to trigger the enter press event in makeIt() so that I get a scroll to the related <div> element.

Here is my code:

<template>
<div>
<div style=”margin-top: 50px;”></div>
<div style=”margin-bottom: 50px;”>
<ul>
<li
v-for=”i in 3”
:key=”i”
@click=”makeIt(i)”
\>
Link{ i }
</li>
</ul>
</div>
<div
v-for=”i in 3”
:id=”i”
:class=”`div${i}`“
\>
Div { i }
</div>
</div>
</template>

<script>

export default {
methods: {
makeIt(hashbang) {
this.$router.push(`#${hashbang}`)
}
}
}
</script>

<style>
.div1 {
background-color: red;
height: 600px;
}

.div2 {
background-color: blue;
height: 500px;
}

.div3 {
background-color: yellow;
height: 500px;
}
</style>

How to do achieve this goal?

Solution :

You can pass $event object from the template and modify the makeIt function as;

HTML:

@click=”makeIt(i, $event)”

JS:

makeIt(hashbang, event) {
if (event.keyCode === 13) {
//do something
}
this.$router.push(`#${hashbang}`)
}

Solution 2:

I’m not completely sure that triggering the Enter keypress is the right thing to do in order to scroll down to the desired section.

You might consider handling the scroll with VueScrollTo (you can find it here). Then it would be as easy as calling VueScrollTo.scrollTo() from within the makeIt method.

makeIt(hashbang) {
this.$router.push(`#${hashbang}`);
VueScrollTo.scrollTo(`.section-${hashbang}`, 500);
}

Here’s a working example of how I would do it: jsfiddle.

Then you might still want to push the index to the route, in order to get to the selected section when browsing to the exact URL.

[Vue.js] change class dinamically to the pass of a videotime

i need to change the class of some span to the pass of the time of a video. i create the span tags from an array with the v-for, inside the array there is the start time and stop time of the text, so to change the class of the single text checking the interval and the actual video time. i tried this code:

```

<span :class=”{‘selected’:(item.id===currentIndex)}” v-for=”item in Array”>
{item.text}
</span>

data(){
return{
Array: [{
id: 0,
start_time: 0,
end_time: 1,
text: “Hello”
}, {
id: 1,
start_time: 1,
end_time: 2,
text: “guys.”
}, {
id: 2,
start_time: 2,
end_time: 3,
text: “In this lesson”
}, …]
},
currentIndex:’’,
}

setInterval(myTimer, 500);

function myTimer() {
for (let i in array) {
if (Math.round(_myplayer.currentTime()) != 0) {
if (array[i].start_time < Math.round(_myplayer.currentTime()) && Math.round(_myplayer.currentTime()) <= array[i].end_time) {
this.currentIndex=i;
}
}
}
}
```

these are the main pieces of my code, the main problem is to link the currentIndex to the id of the span. it’s a kind of ted transcript text highlight
sorry for my english, thank you

Solution :

Try to put set interval into ‘created’ life cycle hook like :

created: function () {
setInterval(myTimer, 500);
}

Or better use v-model to watch the id

[Vue.js] vue router next() function don't work in Promise in router.beforeEach

there is the following code:

router.beforeEach((to, from, next) => {
if (to.name !== from.name) {
store
.dispatch(“fetchCurrentUser”)
.then(() => {
console.log(‘then’);
// do something
next();
})
.catch(() => {
console.log(‘catch’);
router.push(“/login”);
next();
});
} else {
next();
}
// next();
});

I’m trying to get the current user, and if this succeeds, then do something with this data, and if the request is not successful, then redirect the user to the login page. But next () calls do not work, I get the “then” or “catch” in the console, but the redirect does not occur and an infinite loop begins. But if I take next () from condition (commented row) the redirect works fine.

Solution :

The promise resolves after the function ends.

This means that the commented next happens regardless of the result of the promise result. Then the promise resolves and you call another next.

The bottom line is that you don’t need the commented next and should just cover the promise resolve.

Solution 2:

To redirect you should use next(‘/‘) or next({ path: ‘/‘ }).

From the documentation:

next: Function: this function must be called to resolve the hook. The
action depends on the arguments provided to next:

next(): move on to the next hook in the pipeline. If no hooks are
left, the navigation is confirmed.

next(false): abort the current navigation. If the browser URL was
changed (either manually by the user or via back button), it will be
reset to that of the from route.

next(‘/‘) or next({ path: ‘/‘ }): redirect to a different location.
The current navigation will be aborted and a new one will be started.
You can pass any location object to next, which allows you to specify
options like replace: true, name: ‘home’ and any option used in
router-link’s to prop or router.push