A custom component need to set a default className if the caller not define it. How to do this?
The component :
Vue.component('the-component', {
template: 'div class="default-class">...</div>',
...
});
<the-component></the-component> render to div class="default-class"></div> is what I want.
but <the-component :class='user-class'></the-component>
actual render to div class="user-class default-class"></div>
but I wanna div class="user-class"></div>.
I'm not sure if this is the best answer but this could be achieved by doing something like:
computed: {
compClass () {
return 'class' in this.$vnode.data ? '' : 'default-class'
},
}
You can check to see if a class was passed, if it was then have this return nothing as the class has already been added, otherwise add your default class.
Related
I have a side-nav component that is hidden by default using v-show.
A click event in an external component sets a flag in vuex to toggle the side-nav.
How can I set focus to the side-nav component's root div once it's displayed?
I am trying to use this focus-on focus-off technique to hide the side-nav
Maybe something like this:
export default {
watch: {
someVarFromVuex(value) {
// Don't focus unless the value got switched on
if (!value) return;
// Make sure to add the ref to your template.
// You could also use an id.
const $input = this.$refs.input.$el;
// Just in case the input somehow doesn't exist...
if ($input) {
this.$nextTick(() => {
$input.focus();
})
}
},
},
};
Note that if you are actually trying to focus a div, then it will need to have a tabindex.
<button #click="startEffect"> Start Effect</button>
<br/>
<div id="effect" class="highlight" :class="{highlight: enableHighlight}"></div>
I just need the highlight class to be applied based on the data property enableHighlight but for some reason It doesn't apply the class when the startEffect function is called.
<script>
export default {
data() {
return {
enableHighlight: false
}
},
methods: {
startEffect: function () {
this.enableHighlight = !this.enableHighlight;
}
}
}
</script>
I have debugged and confirmed that value of enableHighlight is switched when clicking the button and that the CSS classes are present. However upon clicking the button the class is not applied to the div.
You really mess with Vue when having a "normal" class attribute and one dynamic. Remove the normal one.
<div id="effect" :class="{highlight: enableHighlight}"></div>
To make it work, you need to remove the function in startEffect's definition:
startEffect() {
this.enableHighlight = !this.enableHighlight;
}
Why? because this isn't the same in the different ways to define the function. Learn more about this here.
I am creating a component and want to pass two properties (item & brokerageID) to the component. Here is the HTML code:
{{brokerageID}}
<holiday-component v-bind:item="item" v-bind:brokerageID="brokerageID" testID="45" ></holiday-component>
Here is the code for 'holiday-component'
Vue.component('holiday-component', {
props: ['item',
'brokerageID',
'testID',
],
data () {
return {
holidaysData: [],
showHolidays: false,
}
},
methods: {
getHolidays(contactID) {
....
},
template: <div> {{testID}} {{item.contactName}} {{brokerageID}}
....
The 'item' property is getting passed to the component (item.contactName is displayed correctly in the component template. However, somehow, brokerageID (property of the Vue object) is not getting passed. This property exists which is confirmed as {{brokerageID}} used above the component in HTML displays value. But, within the component template, brokerageID is not available. Also, the testID property passed to the component is not displayed.
Could someone please advise, what is wrong in my implementation that I am unable to use brokerageID in my component?
See Vue's docs about prop naming https://v2.vuejs.org/v2/guide/components.html#camelCase-vs-kebab-case
In this instance, using v-bind:brokerage-id and v-bind:test-id should do the trick.
I am making an autocomplete component which does live search. These are its props:
<AutoCompleteInput
ref={autocomplete.tag}
tag={autocomplete.tag}
type={autocomplete.type}
title={autocomplete.title}
required={autocomplete.required}
photoRequired={autocomplete.photoRequired}
defaultValue={autocomplete.defaultValue}
options={autocomplete.options}
titleKey={autocomplete.titleKey}
valueKey={autocomplete.valueKey}
singleSelection={false}
maxSuggestionNumber={50}
minimumCharacterNumber={-2}
/>
singleSelection, maxSuggestionNumber and minimumCharacterNumber are optional props. I want to give default values to them and also I should check their prop values. For example; default value of minimumCharacterNumber should be '0', so if we dont use that prop, '0' value should be passed into the component. But, if that value is given lower than 0, the component should use default value which is '0'.
I tried the function
public static defaultProps() { ...... } , but I confused and couldn't handle it with conditions.
What is its ordinary technique ? Any solution will be appriciated.
EDIT: I solved my issue, and I want to share.
public static defaultProps = {
minimumCharacterNumber: 0,
maxSuggestionNumber: 50,
singleSelection: false,
}
constructor(props: ACModalProps) {
super(props)
this.state = {
maxSuggestionNumber:
this.props.maxSuggestionNumber && this.props.maxSuggestionNumber > 0
? this.props.maxSuggestionNumber
: ACModal.defaultProps.maxSuggestionNumber,
minimumCharacterNumber:
this.props.minimumCharacterNumber && this.props.minimumCharacterNumber > 0
? this.props.minimumCharacterNumber
: ACModal.defaultProps.minimumCharacterNumber,
singleSelection: this.props.singleSelection
? this.props.singleSelection
: ACModal.defaultProps.singleSelection,
.
.
.
I created public static defaultProps, then I put the default values. I passed these attributes to state, then check the values in state. I used the values from state. If you use typescript, you shouldnt forget to write these attributes' names in state interface with their proptypes.
Default props are assigned after the class or function definition:
class AutoCompleteInput extends Component {
...
}
AutoCompleteInput.defaultProps = {
title: 'Hello World'
}
See the React documentation on prop types for more information.
I have a custom attribute with a method to show and hide some HTML content, I've attached the attribute to an element in a view model.
How can I call a method defined in the custom attribute from the view model?
To access the custom attribute's view-model, just put the custom attribute on the element a second time, but this time put .ref="viewModelPropertyName" on to the attribute. Then, in the parent view-model, you can access methods on the attribute using viewModelPropertyName (or whatever name you gave it). You can see an example of this here: https://gist.run/?id=9819e9bf73f6bb43b07af355c5e166ad
app.html
<template>
<require from="./has-method"></require>
<div has-method="hello" has-method.ref="theAttribute"></div>
<button click.trigger="callMethod()">Call method</button>
</template>
app.js
export class App {
callMethod() {
const result = this.theAttribute.someMethod('blah');
}
}
has-method.js
export class HasMethodCustomAttribute {
someMethod(foo) {
console.log('someMethod called with foo = ' + foo + ', this.value = ' + this.value);
return `Hello ${foo}`;
}
}
There are some ways to do it, but I believe the ideal would be binding a property from your custom-attribute to your view-model. For example:
MyCustomAttribute {
#bindable showOrHide; //use this to show or hide your element
}
MyViewModel {
visible = false;
}
Usage:
<div my-custom-attribute="showOrHide.bind: visible"></div>
So, whenever you change visible you will also change showOrHide.
Nevertheless, is good to remember that Aurelia already has a show and if custom-attributes:
<div show.bind="visible" my-custom-attribute></div>
<div if.bind="visible" my-custom-attribute></div>
Make sure if you really need to create this behaviour in your custom-attribute.
This can be done without the need for a ref. Here is an example that shows how.
It calls a showNotification method on the custom attribute from the custom element using the custom attribute.
In the custom attribute:
#bindable({ defaultBindingMode: bindingMode.twoWay }) showNotificationCallback: ()=> void;
bind() {
this.showNotificationCallback = this.showNotification.bind(this);
}
showNotification() {
// Your code here
}
In the custom element view (Note the absence of parens in the value of this binding):
<div notification="show-notification-callback.bind: showSaveSuccessNotification;></div>
In the custom element view-model:
// Show the save success view to the user.
if (typeof this.showSaveSuccessNotification=== 'function') {
this.showSaveSuccessNotification();
}