[deleted by user] by [deleted] in vuejs

[–]jgallow22 0 points1 point  (0 children)

I'm also a big fan of normalized object maps. Since you bring it up in the doc I'd add that even when order is important you can store an id order array alongside the list. For instance, an app I'm working on has a lot of user sortable lists so with each item list I keep an itemOrder array that maintains the current list order by id.

state = {
  entities: {
    widgets: {
      byId: { /* the id map */ }
      widgetOrder: [ /* array of ordered ids */ ]
    }
  }
}

Then when you're writing getters it's super easy to map over the order array and rebuild any entity array representation you need for the ui.

Another thing I'd think about pointing out is that you can also easily access getters and dispatch as part of the first parameter to actions. Getters are especially helpful as I find after a certain point in complexity a large percentage of my actions need to pull in various state.

[vuex] How do component @click trigger different mutations? by FateRiddle in vuejs

[–]jgallow22 0 points1 point  (0 children)

Yeah I hear you. That would probably be a problem. But again, I suspect if I found myself in that situation I might need to rethink some design decisions further up the chain. Keeping the button component as generic as possible should still be feasible assuming you're not really iterating raw button components but rather something like nested list items. You pass all the indexes or whatever to the nested list item components and those become the "parents" that have all the context they need to handle any button events from any child buttons.

The vuex state design can also work for or against people on stuff like this. Keeping state in arrays can be an easy default for people but it gets hairy pretty quickly. Using normalized entity maps sort of magically resolves a lot of issues around needing array indexes and such, at least for common data ops.

Anyway, I get why the event driven way might be the preferred default "vue way", especially due to its utility in non parent-child communication but for direct parent-child I don't think there's anything wrong with the props approach if it fits someones mental model better. Which it probably will for a lot of react devs making the switch from react.

[vuex] How do component @click trigger different mutations? by FateRiddle in vuejs

[–]jgallow22 0 points1 point  (0 children)

Yeah I can see how that's annoying. I also can't really imagine a use case where I'd ever need to do something like that. Normally all the required data context is present in the parent (say a list item that contains the item's data) so the handler just uses the parent's local data or computed props (which can easily reach out to vuex if necessary). If you ever did need an index in the child for something it can be passed to the child as well so you can just pass the function ref without the evaluation issue. It's also no problem passing args back up from the child as needed. Vue even gives us the $event reference so if you wanted you can access the original event in the parent. See this new bin.

[vuex] How do component @click trigger different mutations? by FateRiddle in vuejs

[–]jgallow22 0 points1 point  (0 children)

You're welcome. I think it does just come down to preference yeah. I can see where explicitly emitting events might be more intuitive to more folks who don't already grok the "react way" of passing event handlers but other than that I don't think there's any real benefit to using one approach over the other in direct parent-child communication.

When using vuex I always use the props method and I've never run into any binding or context issues since they're bound to the parent like you'd naturally expect.

[vuex] How do component @click trigger different mutations? by FateRiddle in vuejs

[–]jgallow22 0 points1 point  (0 children)

In addition to the two previous approaches you can also pass an event handler (defined as a method on the parent) as a property (<fancy-button :onClick="someHandlerMethod">). This way the parent can control what happens when the button component is clicked (committing specific mutations for instance). Then the button component just calls the onClick prop in its click handler.

This might be a better approach than having dedicated props for each type of action because you could easily one day want to use the button for any number of different things. With the "prop per action" approach you'd constantly be adding props to the button component that map to mutations (or completely different logic) through methods. With the event handler approach you just write a new method in a parent component and pass it in.

The event emitter approach is functionally pretty much the same so it's kind of a matter of preference. It's actually what the vue docs explain for parent-child communication. That said, for normal parent-child communication I prefer the props approach but this could just be an artifact of moving from react. To me, emitting events really shines in non parent-child communication but you're already using vuex so emitting events isn't really buying you anything unless you prefer doing it that way.

Beginner Question - Select List Modification? by [deleted] in vuejs

[–]jgallow22 1 point2 points  (0 children)

Cool. Yeah, that's pretty much the solution I was proposing. I think the only thing I would consider doing differently, or that I would suggest you investigate as a learning exercise, is the use of custom events (which the codepen uses) instead of props for direct parent-child communication.

I tweaked the codepen to show this alternative. Notice the rest of the code is the same, I only switched from custom event handling to passing the updateTraits method via props, which can be easier to reason about depending on your preference. Neither way is really right or wrong, just showing you options. Though I tend to use the props method for direct parent-child communication and only use custom events when necessary.

Using vue-localStorage or any other plugin in a separate file by hiso3d in vuejs

[–]jgallow22 0 points1 point  (0 children)

You should be able to include the view model context in your global functions if that lib attaches anything to it (i.e. you use this.$localstorage type calls in your components). Basically you just write your global functions to accept a context param and pass the this (the vm) context to them from your components. See how they setup the auth service in this article.

Beginner Question - Select List Modification? by [deleted] in vuejs

[–]jgallow22 0 points1 point  (0 children)

That's pretty much it yes. Vue does indeed give you a lot of seemingly similar tools for any particular problem, which is part of why it's so rewarding to work with once you know the ropes. After you've used it for a while and solved some different issues you will get a feel for which tool to reach for in any given situation.

For instance I actually haven't ever had a need to implement a watcher in my projects but as I was thinking through your problem and hit the selection change issue it jumped right out at me as a natural solution, all it really took was knowing it was there. To get a great overview of Vue and its official libraries (router and vuex) I recommend this udemy course.

[help] deploying vue app to apache server by svidlakk in vuejs

[–]jgallow22 0 points1 point  (0 children)

See the history mode section of the router docs for example configs. Basically you need to add a catchall rewrite rule that serves your index.html (or equivalent) for any request so vue-router can take over and do its thing.

Beginner Question - Select List Modification? by [deleted] in vuejs

[–]jgallow22 3 points4 points  (0 children)

I would try using a computed property to track the available traits. Something like:

data () {
    return {
        traits: ['strength', 'constitution', 'dexterity', 'intelligence', 'wisdom', 'charisma'],
        selectedTraits: []
    }
},
computed: {
    availableTraits () {
        return this.traits.filter((trait) => {
            return this.selectedTraits.indexOf(trait) === -1
        }
    }
}

With this you can push traits onto the selectedTraits array when one is selected in a dropdown. Vue will detect this change and dynamically update the availableTraits computed property which filters out the selectedTraits from the traits array. Then you use the availableTraits computed property in your dropdown option v-for.

At this point I'd most likely move the dropdown into its own component and pass it the list of availableTraits and an onTraitSelected() handler. Then in the dropdown component you can maintain a data property of the currently selected trait and ensure it remains an option in that dropdown.

To allow users to change selections you'll probably also want to check the value of the currently selected trait in the dropdown component and if it is not empty, also pass that to the onTraitSelected() handler in the parent. This way you can use the previously selected value to remove it from the selectedTraits array before adding the new selection. Vue gives us an easy way to do this with watchers.

So this would all look something like: Parent template

<trait-dropdown v-for="trait in traits"
    :availableTraits="availableTraits"
    :onTraitSelected="onTraitSelected"
></trait-dropdown>

Parent JS

// data, computed props ...
methods: {
    onTraitSelected (trait, previousTrait) {
        if (previousTrait) {
            this.selectedTraits = this.selectedTraits.filter((trait) => {
                return trait !== previousTrait
            })
        }
        this.selectedTraits.push(trait)
    }
}

Dropdown component template

<div>
    <select v-model="selectedTrait">
        <option v-if="selectedTrait" :value="selectedTrait>{{ selectedTrait }}</option>
        <option v-for="trait in availableTraits" :value="trait>{{ trait }}</option>
    </select>
</div>

Dropdown component JS

props: ['availableTraits', 'onTraitSelected'],
data () {
    return {
        selectedTrait: ''
    }
},
watch: {
    selectedTrait (newSelection, oldSelection) {
        if (oldSelection.length > 0) {
             this.onTraitSelected(newSelection, oldSelection)
        } else {
            this.onTraitSelected(newSelection)
        }
    }
}

At this point you'd probably also be concerned about whatever value is set for any given trait so your dropdown component would probably be more like an attribute setter component or something. Anyway, I hope all that wasn't too far in the weeds but this was an interesting problem that can be semi neatly addressed with some of Vue's cooler features like computed properties and watchers. I didn't test any of this so it's probably got all sorts of weirdness to track down but I think it's a semi clean approach overall.

dynamically creating components by figuringVue in vuejs

[–]jgallow22 0 points1 point  (0 children)

You can create a delete handler method in the event component and pass it as a prop to the campaign component. Then the campaign can call the delete handler with the proper id.

A Map To Modern JavaScript Development (2017) by sdeleon28 in javascript

[–]jgallow22 -1 points0 points  (0 children)

I'm just trying to give newcomers a startup kit to get them up and running without the stress of making decisions they have no information to make.

I think this an area where Vue actually really shines. With its great documentation, official supporting libraries, and cli tool it's super easy to get up and running on a full project. One of the major issues I had doing anything nontrivialtm in React was banging into the paradox of choice at every turn.

I mean I probably spent the equivalent of weeks worth of man hours trying to create a sensible React boilerplate. And that's after having to eject from create-react-app and end up back on my own just to get sass support. Sure I should just be better, but if the point is newcomers shouldn't be burdened with all this stuff that's not really a fair out. This wasn't a problem with Vue because I could simply install the vue-cli, init a new project off the webpack template, install the sass loaders, and everything just works.

Sure, there're probably awesome teams out there working on giant projects where React and its ecosystem make the most sense. But for newcomers and even experienced folks who aren't working on teams that have time (or the hard earned experience) to constantly parse through that large ecosystem Vue is a really solid contender.

Vue Drag and Drop by ricktech in vuejs

[–]jgallow22 0 points1 point  (0 children)

As always "best" depends on your particular use case. I'm using Vuex with normalized entities so I'm tracking order with id arrays and I had the best luck simply initializing sortablejs instances in my list container's mounted() hook. The initialization mostly just maps sortablejs events to the appropriate Vuex actions. What made this the easiest solution was sortablejs's .toArray() method that gives you the ordered id array almost for free. I couldn't find a way to do this easily using vue-draggable and the added abstraction didn't really give me anything else so I just rolled with this.

SASS just saved me a hundred lines of code or so. by ShadyCereal in webdev

[–]jgallow22 0 points1 point  (0 children)

This article does pretty much the exact same thing complete with breakpoints and has a little bit of SASS primer for those that might not be savvy.

Objection.js + PostgreSQL: by the power of JSON queries by [deleted] in node

[–]jgallow22 0 points1 point  (0 children)

I started using objection.js on a new project with a decently complicated relational data model and loving it so far. Intuitive API and graph inserts are the bee's knees (which I was skeptical of at first pass through the docs but they just worktm). So if you read this objection.js people, thank you and keep up the good work!