Software
VueJS - manipulate DOM after computed
I'm getting posts and comments from an API, using Vuex. Right now, I have:
mounted () { this.$store.dispatch('getComments', this.post); }, computed: { comments () { return this.$store.getters.orderedComments; },The comments body is a string that contains HTML tags. I need to strip out the href attribute from a tags of a given class.
cleanUnwantedLinks () { const link = document.getElementsByClassName('link-class')[0]; link.removeAttribute('href'); }I'm not sure how to call cleanUnwantedLinks. It should be called just after the component is mounted (when I have the comments already). Is there a way to do it?
Is it possible to Import file in JS file using URL
I have little older version of vue.js ("vue": "^2.2.2") defined in package.json
Which I access in my JS like this:
import Vue from 'vue'But, I like to quickly test if things are working fine with newer version of vue.js.
import Vue from '//unpkg.com/vue@2.4.1'If not possible, any better ways?
How to handle anchors (bookmarks) with Vue Router?
I'm looking for a smart way to handle in-page anchors with Vue Router. Consider the following:
<router-link to="#app">Apply Now</router-link> <!-- some HTML markup in between... --> <div id="app">...</div>The "scroll to anchor" behavior described in the docs works fine except:
- When you click on the anchor, it brings you down to the div id="app". Now scroll away from the div back to the anchor and try clicking it again -- this time you will not jump down to the div. In fact, the anchor will retain the class router-link-active and the URL will still contain the hash /#app;
- With the steps above, if you refresh the page (the URL will still contain the hash) and click on the anchor, nothing will happen either.
This is very unfortunate from the UX perspective because a potential customer has to manually scroll all the way down to reach the application section.
I was wondering if Vue Router covers this situation. For reference, here's my router:
export default new VueRouter({ routes, mode: 'history', scrollBehavior(to, from, savedPosition) { if (to.hash) { return { selector: to.hash } } else if (savedPosition) { return savedPosition; } else { return { x: 0, y: 0 } } } })Show Apollo mutation error to user in Vue.js?
I am using Vue.js with Vue-Apollo and initiating a User mutation to sign in a user. I am using the graph.cool service.
I have a request pipeline function setup to catch some errors, like an invalid email.
When the request is made with bad / invalid input, my error catch() fires (as expected) and in the network tab I can see the JSON for the custom errors messages. But how do I access these errors / response from within the catch if an error is triggered from graph.cool?
Example:
signin () { const email = this.email const password = this.password this.$apollo.mutate({ mutation: signinMutation, variables: { email, password } }) .then((data) => { // This never fires on an error, so I can't // show the user the errors in the network repsonse. console.log(data) }) .catch((error) => { // Error in this part fires in the console // but I'm unable to show the JSON response // errors because the 'then()' above doesn't execute. console.error(error) }) }I get the following error for an unrecognised user:
Error: GraphQL error: No user found with that information at new ApolloError (eval at (app.js:956), :34:28) at eval (eval at (app.js:1353), :139:33) at
Any idea how to show the errors in the response from within the catch()?
I can literally see the errors I want to show to the user in the response on the network tab here:
...but I can't figure out how to do it.
Any help much appreciated! Thank you.
Aframe a-sky rotation not updating
I need you help! I have integrated aframe into my Vue js project and I need the rotation data from the a-sky element in this particular situation. As I move the a-sky in the browser, the rotation data does not update, even if I check it in the aframe inspector.
<a-scene embedded> <a-entity camera look-controls="reverseMouseDrag: true" position="0 1 3" ></a-entity> <a-text font="roboto" width="30" align="center" color="#ccc" opacity="1" value="North" position="0 -3 -4"></a-text> <a-text font="roboto" width="30" align="center" color="#ccc" opacity="1" value="South" position="0 -3 10" rotation="0 -180 0"></a-text> <a-text font="roboto" width="30" align="center" color="#ccc" opacity="1" value="East" position="8 -3 3" rotation="0 -90 0"></a-text> <a-text font="roboto" width="30" align="center" color="#ccc" opacity="1" value="West" position="-7 -3 3" rotation="0 -270 0"></a-text> <a-sky id="sky" :src="getPanoImage" rotation="0 -130 0" :phi-start="getPhi"></a-sky>I have my created() hook set up for listening to changes, but since there is no change, the listener does not fire.
created() { document.querySelector('#sky').addEventListener('componentchanged', function (evt) { if (evt.detail.name === 'rotation') { console.log('Camera rotation went from', evt.detail.oldData, 'to', evt.detail.newData); } });},
Any suggestions are appreciated.
v-for causing actions to be applied to all divs
Previously I asked a question about removing a custom truncate filter in Vue. Please see the question here:
Removing a Vue custom filter on mouseover
However, I neglected to mention that I am using a v-for loop and when I hover over one div, I am noticing that all the divs in the loop are having the same action applied to them. I'm not sure how to target only the div that is being hovered over. Here is my template:
<div id="tiles"> <button class="tile" v-for="(word, index) in shuffled" @click="clickWord(word, index)" :title="word.english"> <div class="pinyin">{{ word.pinyin }}</div> <div class="eng" @mouseover="showAll = true" @mouseout="showAll = false"> <div v-if="showAll">{{ word.english }}</div> <div v-else>{{ word.english | truncate }}</div> </div> </button> </div>And the data being returned:
data(){ return { currentIndex: 0, roundClear: false, clickedWord: '', matchFirstTry: true, showAll: false, } },If you know Vue, I would be grateful for advice. Thanks!
using vue.set in vuex is not updating the state
im trying to add a object into a nested array, and its not working, but iv used this for other states and it works fine.
Has it got something todo with it begin a nested array?
this is the code im using
Vue.set(state.sections[getCurrentSection(state).index].rows[getCurrentRow(state).index].columns[getCurrentColumn(state).index].elements, 0, element)this is the element object
var element = { id: id, style: { backgroundColor: { value: 'rgba(255,255,255,1)', }, }, }what am i doing wrong?
Need the same functionality as a computed property, but I need to be able to update the data after initial change
I have a situation where I need to update data when it detects changes to a state. The user needs to be able to make further changes this info within a textarea. Using computed properties pulls in the data exactly how I want, but any changes made by the user after this are overridden because the computed property keeps changing this data back to it's initial values. What would be the best way to pull in data initially upon a state change but then allow for editing after that point?
Thanks!
Removing a Vue custom filter on mouseover
I would like to remove a truncate filter on mouseover using VueJS 2. Here is my filter in the template:
<div class="eng" @mouseover="showAll">{{ word.english | truncate }}</div>And here is the filter itself:
filters: { truncate: function(value) { let length = 50; if (value.length <= length) { return value; } else { return value.substring(0, length) + '...'; } } },Is there a way to remove the filter on the mouseover event so that the div is not truncated anymore? Thanks!
@/components/<routeName>View
I refer to the code below from electron vue. the @ symbol means this. or window from Does the '@' symbol have special meaning in Javascript, Coffeescript or Jquery? Is it the same??
{ path: '<routePath>', name: '<routeName>', component: require('@/components/<routeName>View') }Multiple filters applied to array of objects
In one of Vue my components I have code that looks like this
<li class="comment" v-for="comment in comments"> ... </li>And my computed method
computed: { comments() { // All filter UI elements are associated with a filter method // and when the user interacts with an element of the UI, filtersToApply gets populated with // the associated method. Not too important right now, // it just checks whether user interacted with the UI or not, so it could essentially be a boolean. But I plan to make use of the functionality at a later time. const filtersToApply = this.filtersToApply(); // if user hasn't interacted with the filter UI, just return the comments // else, apply filter(s) to comments if (filtersToApply.length === 0) { return this.$store.getters.comments; } else { return this.applyFilters(this.$store.getters.comments); } }Ultimately, I want to do something like this:
// Apply the filters to the comments, one by one applyFilters(comment) { return this.filterByX() .then(this.filterByY) .then(this.filterByZ) .... }where the filter methods look like
filterByX(comments) { return new Promise((resolve, reject) => { ....... resolve(comments) }) }How could I make this work? And is it a good pattern?
v-select doesn't recognize label prop
I'm working on a VueJs file and try to use <v-select> so what I'm doing is that :
<v-select :options="divisions" label="text" ></v-select>and my divisions is an array of object conatining id and text but when i'm going on my page I have <% getOptionLabel(option) %> instead of the text value for each one of my divisions value
Vue won't recognize recursive component
I'm trying to list the comments (Comment.vue) of a topic (TopicDetail.vue). My two components looks like this:
The Comment Component<template> <div> <li> {{ commentDetails.by.name }} <p> {{ commentDetails.content }} </p> </li> </div> </template> <script> export default { name: 'comment', props: { comment: Object }, data() { return { commentDetails: [] } }, methods: { fetchComment: function() { this.$http.get('http://localhost:1337/comments/' + comment.id).then(response => { this.commentDetails = response.body; }) } }, mounted() { this.fetchComment(); } } </script> <style type="text/css" media="screen"> </style>
And for my TopicDetail component:<!-- Topic Detailed view --> <template> <ul class="collection with-header"> <comment v-for="(comment,key) in comments" :comment="comment" :key="comment.id" ></comment> </ul> </template> <script> import Comment from './Comment.vue' export default { name: 'topic-detail', data() { return { loading: true, topic: [], comments: [] } }, component: { Comment }, methods: { fetchTopic: function() { this.$http.get('http://localhost:1337/News/' + this.$route.params.id).then(response => { this.topic = response.body; this.comments = response.body['comments']; this.loading = false; }); } }, created() { this.loading = true; this.fetchTopic() }, watch: { '$route': 'fetchTopic' } } </script> <style type="text/css" media="screen"> </style>
Accesing the TopicDetail component give me this error:
Can anyone help me figure it out what's wrong? knowing that the name of the Comment component is present and set to 'comment'..
v-bind in nested component for radio input is breaking
The problem is I cannot click nested radio button but able to click top level radio buttons.
I have this component imported in parent view:
<app-group-radio-item v-for="groupsNested in groupsDataNested" :key="groupsNested.group_id" :groups="groupsNested" :groupInputtedData="groupInputtedData"> </app-group-radio-item> <script> import AppGroupRadioItem from "./GroupRadioItem"; export default { name: 'addGroup', components: {AppGroupRadioItem}, props: { groupsDataNested: Array, }, data(){ return { groupInputtedData: { group_name: '', group_type_id: '', group_parent_id: '' } } } } </script>The Nested component that I am importing:
<template> <div class="list-group list-group-flush"> <div class="list-group-item"> <div class="form-group"> <label class="custom-control custom-radio"> <input type="radio" class="custom-control-input" :value="groups.group_id" v-model="groupInputtedData.group_parent_id"> <span class="custom-control-indicator"></span> <span class="custom-control-description">{{groups.group_name}}</span> </label> </div> </div> <div class="collapse nested-items" :id="'collapseExample' + groups.group_id + 'radio'" v-if="hasChildren"> <app-group-radio-item v-for="groupsNested in groups.groups" :key="groupsNested.group_id" :groups="groupsNested" :groupInputtedData="groupInputtedData"> </app-group-radio-item> </div> </div> </template> <script> export default { name: 'appGroupRadioItem', data: function () {}, props: { groups: Object, groupInputtedData: Object } } </script>Thanks in advance.
How can I make Vuex 'invisible' in VueJS DevTools
There is a config option for vuejs to turn off inspection for the components. This is accessed through
Vue.config.devtools = falseWhen you set that code before initializing Vue, the user (or you) will not be able to inspect the components and you will get the following message vue devtools disabled
I am looking for a similar config for vuex because even with the Vue Js devtools turned off, I can still see the store including mutations and the ability to undo them which is something I don't want.
Is there a way to turn off vuex store inspection?
Reusable component access child method in parent slot
Say I have a component Reusable with a method onClick that sets a data prop. I want this component to be reusable, and I want to use slots to override parts.
As I understand the canon, I must pass the onClick method as a scoped property up to parent from reusable:
<div class="reusable"> <h2>Reusable</h2> <slot name="clicker" v-bind:onClick="onClick"> Default stuff <button v-on:click="onClick">Close</button> </slot> <p v-if="clicked">You clicked me</p> </div> <div class="parent"> <h1>Parent</h1> <reusable> <template slot="clicker" scope="reusable"> <button click="reusable.onClick"> Close from parent </button> </template> </reusable> </div>This might get verbose and noisy if I have a lot of methods, and I wondered: is there a better way, or is this entirely cromulent?
I've looked at using refs, and having methods on the parent call this.$refs.reusable.onClick, as well as specifying dynamic components and swapping them out; both seem counterintuitive.
Can't running Vuejs dependencies were not found
why i can't running my Vue script using webpack. I get this error.
ERROR Failed to compile with 11 errors 19.32.28 These dependencies were not found: * @/components/naven in ./src/main.js * @/components/navtab in ./src/main.js * @/components/artikel in ./src/main.js * @/components/navbtm in ./src/main.js * @/components/hero in ./src/main.js * @/components/btmdata in ./src/main.js * @/components/navbtn in ./src/main.js * @/components/foot in ./src/main.js * @/components/social in ./src/main.js * @/components/contenthome in ./src/main.js * @/components/Content-home in ./src/router/index.js To install them, you can run: npm install --save @/components/naven @/components/navtab @/components/artikel @/components/navbtm @/components/hero @/components/btmdata @/components/navbtn @/components/foot @/components/social @/components/contenthome @/components/Content-home > Listening at http://localhost:8080 ppabcd@ppabcd:~/server/vue-test$I get this result in my browser
Cannot GET /Custom directives proceeds component render
I am using a custom click-outside directive from this post:
This is my element:
<div class="datepicker panel panel-default" v-click-outside="close">The custom directive:
module.exports = { bind(el, binding, vnode) { el.event = (event) => { // Check that click was outside the el and his children. if (!(el === event.target || el.contains(event.target))) { console.log('Clicked outside'); // Call the method provided as the attribute value. vnode.context[binding.expression](event); } }; document.body.addEventListener('click', el.event); }, unbind(el) { document.body.removeEventListener('click', el.event); } };It works and to my knowledge the bind takes place on render of the element. Because I only want the click event to be registered when my datepicker is in view I wrapped it with a v-if.
The problem is that when I use a button to toggle the display of the v-if on the datepicker, the close method from the directive immediately fires.
It seems that the event within bind takes places before the element is even shown, therefore it closes immediately and nothing is shown at all.
This looks like pretty strange behavior singe the button is responsible for showing the datepicker and I would expect the bind to take place when the datepicker has rendered. Not at the same time or before.
Now it seems to take place even before the element has fully rendered. This causes my display button to cause a v-click-outside event.
What is causing this?
Edit:
Made a Jsfiddle to demonstrate this problem(open console):
self-defined wxcompent in weex whereas empty view
MyTabMenu is extends WXCompent and it has Register in application,
public class MyTabMenu extends WXComponent {
public MyTabMenu(WXSDKInstance instance, WXDomObject dom, WXVContainer parent) { super(instance, dom, parent); } @Override protected View initComponentHostView(@NonNull Context context) { View rootView = LayoutInflater.from(context).inflate(R.layout.myview_layout,null); return rootView; } @WXComponentProp(name = "msg") public void setMsg(String msg){ Log.e("cable",msg); }}
but the result page is empty
Simple if(falsey) statement not working [on hold]
I have a statement in code which checks a string like so:
if(str){ //do something here }Even if my str = "" the code inside the check is being executed. Anyone had this? I have checked in console that str == false returns true so really cannot see why the code would be reached?
Cheers
Editing to add answer
My issue appears to be due to the fact that I was using webpack sourcemap and framework Vue.js. There is a setting in a file webpack.dev.config,
devtool: '#cheap-module-eval-source-map'If I remove the "cheap-module' then debugging operates as expected.
devtool: '#eval-source-map'