I use this vue-multiselect plugin: https://vue-multiselect.js.org/
Since I'm going to use it many times, I want to set some defaults props.
For example I want the selectLabel prop to be an empty string, and maybe to sets some <slot>s.
In a typical jQuery plugin I could use $.plugin.defaults to set the defaults. How to do the same with vue plugins?
You can use extends to subclass your component. Pass it a spec just like you would use when defining a component, but only supply the things you want to provide defaults for.
<script>
import Multiselect from 'vue-multiselect';
export default {
extends: Multiselect,
props: {
selectLabel: {
type: String,
default: ''
}
}
}
</script>
Related
In Vue 3, I'm creating a function that will accept an instance of a component and props to pass through. I'm also using TypeScript and was wondering if I can type those parameters. For example, the function would be something like:
const example = (component, props) => {
//
};
So my questions would be:
How can I specify a type for a component instance? These are not always going to be the same component, but would at least be components that are used for a similar purpose.
Would there be a way for me to specify the type for the props and confine it to the props that would be for the first parameter (the component)?
You could use many feature provided by typescript and the Component type from vue to achieve your proper typing, make a generic type that extends the Component then infers the component options/props using infer, use Partial to make them optional :
import type { Component } from "vue";
function example<T extends Component>
(Comp: T, props: T extends Component<infer P> ? Partial<P> : never) {
//....
}
example(Alert, { variant: "success"})
Note: this also infers the attributes and component instance utilities
I would like to know if I can preset some props of components. I'm using Vuetify for this sample: Let's say you would want to customize the v-btn with some props. So the customized implementation would act as a child component because it still offers everything the parent component does but it implements some props directly.
You want to have some predefined buttons with a specific color so you could create your child button like
<template>
<v-btn color="primary"></v-btn>
</template>
but this would be bad because you still want to offer all the props and listeners the "real" button does. You just want to implement some props.
Is there a simple way I can achieve that?
You can import the VBtn component as a mixin and redefine the prop defaults.
import {VBtn} from 'vuetify/lib'
export default {
name : 'VBtnGreen',
mixins: [VBtn],
props: {
color : {
default : 'green'
}
}
}
In my Nuxt project, I created a custom plugin file that returns an object. /helpers/settings:
export const settings = {
baseURL: 'https://my-site.com',
...
};
I register this file in /plugins/settings.ts:
import Vue from 'vue';
import { settings } from '~/helpers/settings';
Vue.prototype.$settings = settings;
And in nuxt.config.js:
export default {
...
plugins: [
'~/plugins/settings',
Then, in a component, I can use my plugin like so:
export default Vue.extend({
data() {
return {
url: `${this.$settings.baseURL}/some-path`,
Everything works as expected, except in that in my console, I get a typescript error from the line that I refer to my plugin in my component:
Property '$settings' does not exist on type 'CombinedVueInstance<Vue, unknown, unknown, unknown, Readonly<Record<never, any>>>'.
Hence my question: what is the proper way to apply a type to my custom plugin so that I don't get this error every time I use it?
According to the docs, you'll need to augment the type file for Vue.
Place the following code in a file named plugin-types.d.ts.
// 1. Make sure to import 'vue' before declaring augmented types
import Vue from 'vue'
// 2. Specify a file with the types you want to augment
// Vue has the constructor type in types/vue.d.ts
declare module 'vue/types/vue' {
// 3. Declare augmentation for Vue
interface Vue {
$settings: string
}
}
This answer also work but I found an easier, though dirtier, way to fix it without the need of adding the plugin-types.d.ts file.
Just add a property to you componen with the name of plugin like following:
#Component
export default class YourComponent extends Vue {
private $settings!: string; // your plugin here
private url: string = `${this.$settings.baseURL}/some-path`
}
I am new to React and have been tasked with updating an existing component (a form). My task is to read a setting from JSON and show or hide an element based on that setting.
The JSON appears like:
"forms": {
"enquiry": {
"showConfirmCheckbox": "true"
},
},
Using and existing component that already reads this JSON and turns it into context which is called config, I can use the above as such:
In my propTypes I have:
static propTypes = {
config: PropTypes.object.isRequired,
}
And in my render function I just wrap the element in a conditional statement:
{config.forms.enquiry.showConfirmCheckbox &&
<Checkbox
etc, etc, etc
This works fine. However, I want to add a default for this value just in case the original JSON file is not updated correctly or is missing that entry. To that effect I added this to my defaultProps:
static defaultProps = {
config: {
forms: {
enquiry: {
showConfirmCheckbox: 'true',
},
},
},
}
However, this doesn't seem to work.
If I delete the line 'showConfirmCheckbox': 'true', from the JSON file the if condition still validates as false - it doesn't pick up the defaultProps value.
Would anyone know how to amend this? Is there something I am doing wrong here?
Are there other entries to your config, which are being passed while the showConfirmCheckbox isn't? The config prop is treated as a whole, if any object is passed, default props are not applied.
Docs on propTypes
There's no way you can default nested props because under the hood , defaultProps are only shallow merged with first-level props if props are missing.
, click for more information
However, in order to get around this, you may consider adding a few customized default logics in both lifecycle HOOK componentWillReceiveProps and constructor
And maybe the nested propTypes can also be helpful.
propTypes: {
configs: PropTypes.shape({
forms: PropTypes.shape({
enquiry: PropTypes.shape({
showConfirmCheckbox: PropTypes.bool.isRequired
})
})
})
}
I created a new React Native project using react-native init and in the generated template, the main component class looks like this:
export default class App extends Component<{}> {
...
}
I don't really understand what the <{}> part means. I've never seen this before and all the examples seem to omit it. Just curious as to what its purpose is and if it's necessary.
When you are using typescript, you have to specify the type of values to be expected. This allows detecting mismatching properties during compile time and reduces the amount of errors.
So when you do Component<{}>, {} is the type for Props, your component will receive.
This is how React's Component class looks like:
If you notice, the type is <P, S>, which stands for <Props, State>.
There is another interface called ComponentClass that has a signature <P>,
which initializes a new component internally with state as any. This interface is used in ReactElement's type:
So all in all, you are defining a Component which accepts no props and but can have state of any type. This is usually done when you are not sure about you component's interactions.
Ideally a component should look like this:
interface IComponentState {
...
}
interface IComponentProps {
...
}
export class MyComponent<IComponentProps, IComponentState> extends React.Component {
...
}
This enforces consumer to pass any necessary properties and enforces you to have proper value of state.
This is either Typescript of Flow. You usually don't describe props as propTypes, but rather as interface or type. Then the type is passed to React.Component as a generic.
Type of props would be the passed type plus { children?: ReactNode }
Actually there are two generic arguments, second for State
Very useful and convenient stuff.
https://www.typescriptlang.org/docs/handbook/generics.html
https://www.typescriptlang.org/docs/handbook/react-&-webpack.html
These are flow type annotations. See https://flow.org/
You'll notice that there's a #flow comment at the top of the file, and a .flowconfig file in the root of the project.
Using flow here is optional, but it can help you catch bugs.