Cannot set value of background image in Vue 3 storybook - vuejs2

I am making use of Vue 3 along with storybook to make components, I am trying to set up the value of background-image for a div, the code for that is given below.
1. import { Story } from "#storybook/vue3";
2. import BaseSelectionBox from "./index.vue";
3. import "../../../utils/external-styles.scss";
4.
5. export default {
6. title: "Element Vue3/BaseSelectionBox",
7. components: { BaseSelectionBox },
8. };
9.
10. const Template: Story = (args: any) => ({
11. components: { BaseSelectionBox },
12. setup() {
13. return { args };
14. },
15. template: `
16. <base-selection-box v-bind="args" class="center-div">
17. <div class="selection-icon" style="background-image: url({{args.backgroundImage}})"/>
18. <div class="box-content">
19. <div class="box-heading">
20. {{args.heading}}
21. </div>
22. <div class="box-description">
23. {{args.description}}
24. </div>
25. </div>
26. </base-selection-box>
27. `
28. });
29.
30. export const SelectionBox = Template.bind({});
31. SelectionBox.args = {
32. selected: false,
33. backgroundImage: "https://dlvkyia8i4zmz.cloudfront.net/WrIvrCRWRQyB3QV9zJSq_icon_resi_for_rent.png",
34. heading: "Residential Bridge",
35. description: "Ideal for home renos or anytime you’re planning to buy and sell within a few months.",
36. };
As you can see in line number 17, I am not able to inject the value of the image in the background-image property, how can I achieve this ?.

Related

Password Strength meter for Vue.js 3

I've started working with Vue.js version 3 and making a simple signup form. I need to implement a password strength meter for my password field but seems there isn't any compatible such component with Vue.js 3 version.
I've found few good components for password strength meter to use with Vue.js but they all seems to have compatibility with Vue.js 2.
I've tried
https://awesomeopensource.com/project/skegel13/vue-password
its working good in DEMO but not compatible with my Vue.js 3.
I'm stuck here. Any help/suggestions ?
Are you looking for a visual component or something that actually computes password strength?
zxcvbn is fairly well-known as a strength calculator - it outputs a score from 0-4 for how strong a password is. You could then roll a simple Vue component that outputs a different value depending on that score.
Below example uses Tailwind CSS classes for styling the visual meter. I wrote this in the browser and haven't tested the Vue but it's fairly simple and you should be able to get the idea.
<!-- PasswordStrengthMeter.vue -->
<template>
<div>
<div class="w-full h-4 flex">
<div :class="style"></div>
<div class="flex-1"></div>
</div>
<div>{{ strength }}</div>
</div>
</template>
<script>
props: {
score: {
required: true,
default: 0,
}
},
computed: {
strength() {
return [
'Very Weak', // 0
'Weak', // 1
'Moderate', // 2
'Strong', // 3
'Very Strong' // 4
][this.score];
},
style() {
return [
'w-1 bg-red-500', // 0
'w-1/4 bg-yellow-500', // 1
'w-1/2 bg-yellow-300', // 2
'w-3/4 bg-green-500', // 3
'w-full bg-blue-500' // 4
][this.score];
},
},
</script>
Here's what it might look like.
This one works nicely with Vue3.
https://github.com/miladd3/vue-simple-password-meter/tree/next
Sample code from the repository:
<template>
<div id="app">
<label>Password</label>
<input type="password" v-model="password" />
<password-meter :password="password" />
</div>
</template>
<script>
import { defineComponent, ref } from 'vue';
import PasswordMeter from 'vue-simple-password-meter';
export default defineComponent({
components: {
PasswordMeter,
},
setup() {
const password = ref('');
return {
password,
};
},
});
</script>

cant change type(danger,success) and add animated on vue strap

i Want to make a progress bar using vue strap . i install vue strap on this link
this link
now i add a progress bar, this progress bar is showing , this bar is only showing color primary and cant showing animated .
<template>
<div class="progress">
<progressbar now="99" type="danger" striped animated ></progressbar>
</div>
</template>
<script>
import { progressbar } from 'vue-strap'
export default {
components: {
progressbar
},
mounted() {
console.log('Component mounted.')
}
}
</script>
with this code , this type is primary and this animated didnt work .
i change browser from chrome to mozila , but its still didnt work . my browser is newest .
whats wrong about this ? i dont know why animated didnt work
There is a bug in VueStrap library when it comes to progress bar animations. The template for progress bar in VueStrap uses class active to animate, whereas, in Bootstrap 4 we have to use class progress-bar-animated. A work around of this problem is to created your own Progress Bar component which makes use of the Bootstrap 4.
Custom Progress Bar component could be written as:
Vue.component('c-progressbar', {
template: `
<div class="progress">
<div class="progress-bar" :class="progressClasses"
role="progressbar"
:style="progressStyle"></div>
</div>`,
props: {
striped: Boolean,
animated: Boolean,
now: {
type: Number,
required: true
},
contextType: {
type: String,
default: 'primary'
}
},
data: function() {
let context = 'bg-' + this.contextType
return {
progressClasses: {
'progress-bar-striped': this.striped,
'progress-bar-animated': this.animated,
[context]: true
},
progressStyle: {
width: this.now + '%'
}
}
}
})
new Vue({ el: '#app' })
You can use this pen for testing: https://codepen.io/abdullah-shabaz/pen/YzXdYgd

Pulling in several static properties into Vue.js

I am very new to Vue.js and we are working on adding in Vue.js into an existing project piece by piece. I'm working on rewriting the product slider in Vue. It is currently using the jquery slick slider. So in the current/old code in the html this js function is being called:
function productDetailsRecommendations(compositeNumbers) {
var params = {
compositeNumbers: compositeNumbers,
strategy: 'pp12',
backupStrategy: 'popular',
divId: 'recommendedProductsHorizontal',
isVertical: false,
isHideHeaderText: false,
headerText: 'Guests Who Viewed This Item Also Viewed These',
backupHeaderText: 'Popular Products',
itemsPerPage: 5,
itemDisplayLimit: 10,
numberOfItems: 15,
responseMap: null
};
createSlider(params);
}
Now I am using vue-carousel to recreate the slider. So I replaced that call with my own copied function: productDetailsRecommendationsVue.
Now I have created a ProductRecommendationsSlider.vue as the slider component. And I have a index.js as the entry point where the slider gets initialized.
Now my boss told me I need to put the productDetailsRecommendationsVue function into index.js.
// index.js
import Vue from 'vue';
import axios from 'axios';
import VueCarousel from 'vue-carousel';
import Slider from '/components/slider/ProductRecommendationsSlider'
Vue.use(VueCarousel);
window.productDetailsRecommendationsVue=function(compositeNumbers) {
var params = {
compositeNumbers: compositeNumbers,
strategy: 'pp12',
backupStrategy: 'popular',
divId: 'recommendedProductsHorizontal',
isVertical: false,
isHideHeaderText: false,
headerText: 'Guests Who Viewed This Item Also Viewed These',
backupHeaderText: 'Popular Products',
itemsPerPage: 5,
itemDisplayLimit: 10,
numberOfItems: 15,
responseMap: null
};
};
/* eslint-disable no-new */
new Vue({
el: '#itemDetailPage #recommendedProductsHorizontal .imageSlider',
components: {
Slider,
'carousel': VueCarousel.Carousel,
'slide': VueCarousel.Slide
},
template: '<product-slider></product-slider>'
});
But my main question is how do I get those parameters into the component?
They are needed in one of the functions in ProductRecommendationsSlider.vue. My boss said I was on the right track with placing the js function there in the index.js. All the tutorials I've found online talk about building a project from scratch. Tying Vue into an existing project is much more difficult IMO.
Since you're using single file components (*.vue within a Vue CLI generated project), your project already has modularization support, so you wouldn't need to attach properties/functions to the window object. Instead, you could encapsulate your static properties/functions within the component file itself:
// ProductRecommendationsSlider.vue
<script>
function productDetailsRecommendations() {
return { /*...*/ }
}
export default {
data() {
params: {}
},
methods: {
loadParams() {
this.params = productDetailsRecommendations();
}
}
}
</script>
or in separate files that you could import into your component:
// ProductRecommendationsSlider.vue
<script>
import { productDetailsRecommendations } from '#/utils';
export default {
data() {
params: {}
},
methods: {
loadParams() {
this.params = productDetailsRecommendations();
}
}
}
</script>
// <root>/src/utils.js
export function productDetailsRecommendations() {
return { /*...*/ }
}
Then, you could bind those parameters to your vue-carousel properties. Note only some of the parameters in your example appear to be supported by vue-carousel (unsupported marked by n/a):
"strategy": "pp12", // n/a
"backupStrategy": "popular", // n/a
"divId": "recommendedProductsHorizontal", // ID of container div
"isVertical": false, // n/a
"isHideHeaderText": false, // true = hide `headerText` h3; false = show it
"headerText": "Guests Who Viewed This Item Also Viewed These", // h3 text content (isHideHeaderText: true)
"backupHeaderText": "Popular Products", // h3 text content (isHideHeaderText: false)
"itemsPerPage": 5, // vue-carousel perPage
"itemDisplayLimit": 10, // n/a
"numberOfItems": 15, // vue-carousel item count
"responseMap": null // n/a
Example data bindings:
<template>
<div class="product-slider" :id="params.recommendedProductsHorizontal">
<h3 v-if="!params.isHideHeaderText">{{params.headerText}}</h3>
<carousel :perPage="params.itemsPerPage">
<slide v-for="i in params.numberOfItems" :key="i">
<span class="label">{{i}}</span>
</slide>
</carousel>
<section>
<button #click="loadParams">Load params</button>
<pre>params: {{params}}</pre>
</section>
</div>
</template>
demo
You can assign window.productDetailsRecommendationVue in vue data or computed properties
1) Change window.productDetailsRecommendationsVue from a function to
window.productDetailsRecommendationsVue = {
//compositeNumbers: "I have no idea where this comes from but it could be passed separately",
strategy: "pp12",
backupStrategy: "popular",
divId: "recommendedProductsHorizontal",
isVertical: false,
isHideHeaderText: false,
headerText: "Guests Who Viewed This Item Also Viewed These",
backupHeaderText: "Popular Products",
itemsPerPage: 5,
itemDisplayLimit: 10,
numberOfItems: 15,
responseMap: null
};
2) inside of your vue instance of index.js assign window.productDetailsRecommendtionsVue to a data property:
new Vue({
el: '#itemDetailPage #recommendedProductsHorizontal .imageSlider',
components: {
Slider,
'carousel': VueCarousel.Carousel,
'slide': VueCarousel.Slide
},
data: {
oldSliderData: window.productDetailsRecommendationsVue
}
template: '<product-slider></product-slider>'
});
It is now accessible to components using the standard prop process. I'm not sure where is coming from b/c I don't see it imported.

VueJS Datepicker wil not accept dd/MM/yy

UPDATE:
This is a bug and I have raised it as an issue on github. TBH, the component is not really ready for mainstream use yet.
My vuejs-datepicker will not accept a dd/mm/yy format if the day is 13 or greater. Presumably this is because it is interpreting the first two digits to be the month, and therefore rejects anything greater than 12.
The calendar pops up. You can select a date, and it shows in the input field. However, as soon as the field loses focus, it is cleared.
I have tried using both a static string as the value of format, and a function. Below is the function version.
HTML:
<div id="respond_by">
<date-picker name="respond_by"></date-picker>
</div>
Script at foot of page:
<script>
$(function () {
new Vue({ el: "#respond_by" });
});
</script>
My single file component:
<template>
<vue-date-picker placeholder="dd/mm/yy"
input-class="form-control"
:name="name"
:format="customDateFormat"
monday-first
typeable></vue-date-picker>
</template>
<script>
import moment from 'moment';
import DatePicker from 'vuejs-datepicker';
export default {
props : [
'name'
],
components: {
'vue-date-picker' : DatePicker
},
methods: {
customDateFormat(date) {
return moment(date).format('DD/MM/YY');
}
}
}
</script>
Globally registering the component:
import DatePicker from './date-time/date-picker.vue';
Vue.component('date-picker', DatePicker);
I have tested both Firefox and Chrome, with the same result.
I have tested the vuejs-datepicker code sand box and it works fine there, https://codesandbox.io/s/mpklq49wp. I tested it by adding the following line to the list of options in the formatting example:
<option value="dd/MM/yy">dd/MM/yy - e.g 13/11/18</option>

OpenLayer setCenter() doesn't work a second time

I am trying to reproduce a map app using openLayer API with VUE and this setCenter() function doesn't work on my second call of it. In the following snippet of code, the map would be initialized with a random centre of [60,60] and then when i input an number to update its Latitude it works ok, but when i try to change the centre again by repeating the step with a different input the map simply doesn't update the view.
In browser console, however,
window.map.getView().getCenter()
would give the latest coordinates that i want.
The reason why map is initialized in a setTimeout() fashion is how i imported openLayer using <script> tags in my index.html file. Therefore why must the map instance be bounded to window.
Here is the code:
<template>
<div id="map" class="map">
<input type="text" #keyup.enter="changeCenter" v-model="center">
</div>
</template>
<script>
export default {
name: "Olmap",
props: ["InitCenter"], //[60,60]
data(){
return{
center: ""
}
},
components:{
topInfoBar
},
methods:{
changeCenter: function(){
window.changeCenter([parseInt(this.center), 40])
}
},
created(){
setTimeout(()=>{
var map = new window.ol.Map({
target: 'map',
layers: [
new window.ol.layer.Tile({
source: new window.ol.source.OSM()
})
],
view: new window.ol.View({
center: window.ol.proj.fromLonLat(this.InitCenter),
zoom: 4
})
});
window.map = map;
},50);
var changeCenter = function(center){
window.map.getView().setCenter(center);
}
window.changeCenter = changeCenter;
},
}
</script>
Anyone can help me with this?