Vue - Is it better to keep all props in one large mixin - vue.js

I have a component library where i would like to standardize the props, component etc.
Thoughts on combining them props/methods/other mixins/etx into one larger mixin
All property names would be the same
Remove duplicated code on refactoring to adjust components from local props/methods/computed/ to "global"
Not all components would have need for every piece of data contained within the mixin - point 4
Would tree shaking remove the unused code on Rollup?
Is this a good idea?

If your component library is not constrained to using Vue 2 you might want to take a look at Vue Composition API to share functionality (methods + reactive state) between different components.
Mixins might not be what you really want to be using because you kind of lose information as to what features/props/methods really will be put inside your component without re-checking the mixin code. You also might run into issues when component options get merged by Vue at runtime. Check out these posts for more information:
https://css-tricks.com/how-the-vue-composition-api-replaces-vue-mixins/
https://reactjs.org/blog/2016/07/13/mixins-considered-harmful.html
As for sharing props: What I've seen just yesterday (but not yet tried!) in a talk by John Leider - creator of Vuetify - is create a function that returns the props you want to reuse between components. Then you just call said function inside your props definition and use the spread operator.

Related

Vuejs - Find unused props. events and components

I have a Vuejs SPA that I want to clean-up and do some refactoring on. One thing I would like to do is detect
Unused or extra props defined in custom components. I don't mean within the component itself (this I do via eslint-plugin-vue), but when the component is instantiated somewhere in the app within another component.
Unused or extra $emits defined in custom components. Again, are there $emit that are never actually handled when instantiating a component?
Identify component's data that actually dont need to be reactive and can be removed from data
Unused components
Unused exports in my js files
The linter I use, eslint-plugin-vue, does its work component by component but here I want to be checking unused stuff across several components.
I could not find any built-in tool for these tasks, what's the best way to do this?
Even if the app contains hundreds of components I could still do this manually, but ideally I would like to run this process frequently to keep the app clean.
After some research I ended up writing my own node.js script using regex for parsing my codebase. It's too ugly for me to post it anywhere but it is <300 lines and writeable in a day or so.

Is it possible to have dynamic element names in a Vue template?

I need to have a component, where I get the type of another component that this component should create. (it could be one of n different elements) Doing this in the component's render function is not a problem, but since I am new to Vue and I am trying to do things the Vue way, not the way I would do it in React.
I have not been able to find any solution with just using a Vue template. Is there one?
This is how I would like to be able to use the component:
<factory elm="first-component"></factory>
The factory should then internally in some way result in this:
<first-component></first-component>
(it should also be able to add attributes to the component, but that I know how to do, so a suggested solution does not need to care about attributes)
There is <component :is="myCoolComponent"></component> that will basically generate <my-cool-component></my-cool-component>.
Is it what you're looking for?
From the documentation: https://v2.vuejs.org/v2/guide/components-dynamic-async.html#keep-alive-with-Dynamic-Components
You could also totally create a Factory.vue component and put that kind of logic inside of it (<component :is="" ...>).

What should be structure of Vue component? in which order functions should be added?

Is there any systematic structure for Vue component? In which order computed , methods, components, mounted watch etc should be written?
Update
For component I mostly prefer putting script tags before html tags. As the idea that we mostly use to play with js so I feel itchy to move down always in the page. Else make your layout as per your preference
As per Vue official style guide -
Component/instance options should be ordered consistently.
This is the default order we recommend for component options. They’re split into categories, so you’ll know where to add new properties from plugins.
Side Effects (triggers effects outside the component)
el
Global Awareness (requires knowledge beyond the component)
name
parent
Component Type (changes the type of the component)
functional
Template Modifiers (changes the way templates are compiled)
delimiters
comments
Template Dependencies (assets used in the template)
components
directives
filters
Composition (merges properties into the options)
extends
mixins
Interface (the interface to the component)
inheritAttrs
model
props/propsData
Local State (local reactive properties)
data
computed
Events (callbacks triggered by reactive events)
watch
Lifecycle Events (in the order they are called)
beforeCreate
created
beforeMount
mounted
beforeUpdate
updated
activated
deactivated
beforeDestroy
destroyed
Non-Reactive Properties (instance properties independent of the reactivity system)
methods
Rendering (the declarative description of the component output)
template/render
renderError
For more recommended style-guide of Vue - Look here vue-style-guide
No, there is not. 100% personal preference. I like to start with the data, methods and usually end with the lifecycle methods. That is similar to how it is usually positioned in the docs and seems convenient because data and methods get changed a lot, and lifecycle methods not so much. However, there is no reason to do it like that from the framework. Go your game.
It's possible to maintain the order of object keys in practice in JavaScript, but this isn't guaranteed for ES5 specification, which is supported by Vue. So it shouldn't be expected that the framework will rely on the order in which component properties are defined.
Component functions can maintain a certain order for consistency like other answers explains, but they should not. This is purely a matter of style.

Object.assign breaks v-for (functional component)

I am creating a Vue component ("Polar") to layout divs in a circular pattern. It does so setting the inline styles.
Now, I am having a weird issue when I use the component. It happens only under a very specific set of circumstances:
I create multiple instances through v-for
The Polar component is a "functional" component
I pass the props as a referenced object (inline works fine!)
The propsObject contains a nested StylesObject
The custom Styles object gets merged as the first parameter of ObjectAssign()
What happens? All the instances in the v-for take on the value of the last item, like a closure was broken.
The code is a bit much to display here, so I have a codesandbox and github. The first test shows the issue: all items are displayed on top of each other. The second test demonstrates that I can pass the exact same propsObject, only inline, and it works. Reversing the arguments in Object.assign also makes it work, as does converting the component to a normal/non-functional one.
I suspect this is some sort of Vue bug (or at least undocumented behavior).
Quick answer:
Object.assign will change the first parameter (=target object). This caused my settingsObj to take on the other settings every time, until it had the settings of the last instance.
Easily resolved by changing
Object.assign(props.settingsObj, {setting: val, })
into
Object.assign({}, props.settingsObj, {setting: val, })
Sorry for blaming Vue, all my fault. Not exactly sure why this only happens with functional components, but it must be related to normal components being isolated in their own Vue instance.

Differences between vue instance and vue component?

I'm new to vue js and have some questions when learning it.
I'm now a little confused about the relationship between its instance and component. As far as I learned, every app build by vue should only have one instance and one instance only, it can have as many components as you like if needed. But recently I've seen a demo, and in that demo it has more than one instance.
So my question is, is that ok to have multiple intances in one app( the demo code works fine, but is that the correct way)? What's the best practice to use instance and component in vue app?
It's ok to have two instances in the same project, however, you probably don't want to do that.
A good scenario is to have one main instance to control your app, specially if you are creating a Single Page Application (SPA). Then use as many components as you want.
Components are a great way to reuse code and keep it organized, and, with Vue.js, is very easy to communicate between your components and your "main" Vue instance.
It depends very much on your situation.
I work on a large web project which is not an SPA. We have a Vue instance for each "silo" of the application. We are slowly transitioning an older project from a mostly jQuery frontend so it's possible that as it evolves We'll be able to condense down to a single Vue instance but we're having no trouble with multiple instances. The ease of using Vue in existing projects was one of the biggest deciding factors in choosing it over another library such as react.
I have taken a different approach with green development, one instance and many components.
There are something in common, and some difference between Vue instance and Vue component.
From Vue docs:
all Vue components are also Vue instances, and so accept the same options object (except for a few root-specific options).
The root Vue instances accept properties like el, router, the Vue components cannot.
The data property in root Vue instances is an object, but in Vue components must be a function.
The design target is different:
A root Vue instance is a Vue application launcher, Vue component is an extension of the Vue instance.
Vue components can create elements to be reused in many places. This is Vue characteristic of componentization mainly reflect point.
Vue instance can associated with and manipulate an element which is already exist.
Vue component more suitable for create new element and reuse it at anywhere.
Think of a Vue Component as a blueprint or set of rules on how to create something that can be inserted into the DOM that the user can interact with.
So when you create a Vue file you are going to define exactly one component with a set of rules that tells Vue how to display stuff on the screen and tells a user how to interact with it.
On the other hand is a Vue instance, its an instance of a Vue component, it represents something that has been inserted into the DOM and is something that a user can interact with.
If you have a background in Object-Oriented Programming, think of a Vue Component as being like a class and a Vue instance as an instance of that class.
What has not been mentioned in previous answers that I will cover in regards to the difference between Vue instance and Vue component is how we define the data property that we are working with.
If we are working with a Vue instance, then we can define the data property as an object or a function that returns an object like so:
With a Vue Component that data property must be a function that returns an object.
So for example this is a Vue component:
export default {
name: "App",
components: {
SearchBar,
VideoList
},
And if we want to make use of data inside of that Vue component, we have to make a function that returns an object.
Vue components extends Vue instances
but Vue instances accept properties like el, router, the Vue components cannot.
best practice:
one Vue instance
many Vue component