vue js use npm module as inline script - vue.js

I am not using webpack, I include vue as external script Something like this:
<script src ="unpckg.com/vue.js-latest"></script>
And I want to use npm module
https://github.com/stephan281094/vue-drag-select
So I include it like this:
<script src= "https://unpkg.com/vue-drag-select#0.1.5/dist/vue-drag-select.js
"></script>
How do I use it?
UPD: I corrected the path to external script.
My question is how to include vue-drag-select component in my app because
When I write
import DragSelect from 'vue-drag-select/src/DragSelect.vue'
It gives me an error because I don't use webpack, so there is no import function

This is just a url https://github.com/stephan281094/vue-drag-select to dispaly package details not any file path
Here is the raw data of .js file might be you want to include, go this url and save contents of this file in your local and then import/include
https://github.com/stephan281094/vue-drag-select/blob/master/dist/vue-drag-select.js

If you include cdn script, then DragSelect is global variable, you can access it directly
Vue.component('vue-drag-select', DragSelect.default)
Vue.component('vue-drag-select', DragSelect.default)
new Vue({
el: "#app1",
methods: {
getClasses (item, selectedItems) {
const isActive = !!(selectedItems.find((selectedItem) => {
return parseInt(selectedItem.dataset.item, 10) === item
}))
return {
item: true,
active: isActive
}
}
}
})
*,
*:before,
*:after {
box-sizing: inherit;
}
html {
box-sizing: border-box;
user-select: none;
}
html,
body {
margin: 0;
padding: 0;
min-height: 100vh;
}
body {
font: 16px / 1.5 'Helvetica Neue', sans-serif;
padding: 5%;
}
/* Custom styling */
.item {
display: inline-flex;
min-width: 80px;
height: 100px;
margin-right: 10px;
margin-bottom: 10px;
background-color: #ddd;
justify-content: center;
align-items: center;
text-transform: uppercase;
letter-spacing: 3px;
font-size: 10px;
}
.item.active {
background-color: rgb(0, 162, 255);
color: #fff;
}
<script src="https://unpkg.com/vue-drag-select#0.1.5/dist/vue-drag-select.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.16/dist/vue.js"></script>
<div id="app1">
<h1>Vue Drag Select Example</h1>
<vue-drag-select selector-class="item">
<template slot-scope="{ selectedItems }">
<div
v-for="item in 50"
:class="getClasses(item, selectedItems)"
:data-item="item"
>
Item {{ item }}
</div>
</template>
</vue-drag-select>
</div>

Related

Styles are not being applied to elements created in the setup function in vue

So I am working on this mini website and I'm trying to not hard code repetitive elements in the template, so I thought I would a function to display them all.
<template>
<div class="wrapper">
<div class="skills" ref="canvas">
</div>
</div>
import { ref, onMounted } from 'vue';
import MySkills from '../constants/skills';
export default {
setup() {
const skills = MySkills
const canvas = ref(null);
const displaySkills = () => {
skills.forEach(skill => {
const el = document.createElement('div');
el.className = 'skill';
el.innerText = skill.name;
const level = document.createElement('span');
level.className = 'level';
level.innerText = skill.level;
el.appendChild(level);
canvas.value.appendChild(el);
})
}
onMounted(() => {
displaySkills();
})
return {
canvas,
displaySkills
}
}
}
the styles are in a separate file
.skill {
padding: 10px;
border-radius: 100px;
text-align: center;
position: relative;
background-color: aqua;
}
.level {
position: absolute;
top: -5%;
left: 0%;
padding: 5px;
border-radius: 100px;
text-align: center;
}
Now the ssue is that those styles are not being applied the el and level elements
please help!!!
You should not access the DOM (createElement, appendChild) while working with Vue.
If you are new to Vue, v-for does exactly that, more info in the official docs.
So your code would be:
<template>
<div class="wrapper">
<!-- you should put a unique identifier in the key tag, if you don't have an id the name should be fine too -->
<div class="skills" v-for="skill in MySkills" :key="skill.id">
<your-skill-html>
{{ skill.name }} etc
</your-skill-html>
</div>
</div>
</template>
<script setup>
import MySkills from '../constants/skills';
</script>
<style>
.skill {
padding: 10px;
border-radius: 100px;
text-align: center;
position: relative;
background-color: aqua;
}
.level {
position: absolute;
top: -5%;
left: 0%;
padding: 5px;
border-radius: 100px;
text-align: center;
}
/* or import "path/to/my-css-file.css" */
</style>
Please note that I'm using the script setup syntax but it's not required, it's just quicker to write since you can omit the defineComponent part and the return values.

Is it possible to put a CSS template inside a Vue component?

I've created the following Vue component:
var loading = new Vue({
el: "#loading_id",
components:{
'loading' : {
template : `
<div>
<div id="screenLoading" class="background">
<div class="loading">
<div class="obj"></div>
<div class="obj"></div>
<div class="obj"></div>
<div class="obj"></div>
<div class="obj"></div>
<div class="obj"></div>
<div class="obj"></div>
<div class="obj"></div>
</div>
</div>
</div>
`,
methods: {
startLoading: function() {
const load = document.getElementById("screenLoading");
load.classList.add('show')
},
stopLoading: function(){
const load = document.getElementById("screenLoading");
load.classList.remove('show')
}
}
}
}
});
loading.$children[0].startLoading()
setTimeout(() => {
loading.$children[0].stopLoading()
}, 3500);
.background {
width: 100vw;
height: 100vh;
background: rgba(0, 0, 0,.5);
position: fixed;
top: 0px;
left: 0px;
z-index: 2000;
display: none;
justify-content: center;
align-items: center;
}
.background.show {
display: flex;
}
.loading{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
height: 40px;
display: flex;
align-items: center;
}
.obj{
width: 12px;
height: 70px;
background: white;
margin: 0 3px;
border-radius: 10px;
animation: loading 0.8s infinite;
}
.obj:nth-child(2){
animation-delay: 0.1s;
}
.obj:nth-child(3){
animation-delay: 0.2s;
}
.obj:nth-child(4){
animation-delay: 0.3s;
}
.obj:nth-child(5){
animation-delay: 0.4s;
}
.obj:nth-child(6){
animation-delay: 0.5s;
}
.obj:nth-child(7){
animation-delay: 0.6s;
}
.obj:nth-child(8){
animation-delay: 0.7s;
}
#keyframes loading{
0%{
height: 0;
}
50%{
height: 70px;
}
100%{
height: 0;
}
}
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<loading id="loading_id"></loading>
It works perfectly fine, its purpose is to be a loading screen for me to use when I have to make something wait on my webpage. However, instead of loading the CSS from an external CSS file with the <style> tag on the main HTML, I'd like to load my CSS directly from inside Vue, just like I did with the HTML on the template variable. Basically, it'd be something like the following:
var loading = new Vue({
el: "#loading_id",
components:{
'loading' : {
template : `myHTML template`,
cssTemplate: `myCSS template`,
methods: {
// my methods
}
}
}
});
Is it possible to do on Vue? Can I write CSS templates inside a Vue component?
I know I also can load small pieces of CSS styles with Vue as described here, but in my case, I'd like to keep the classes and ids declaration as they are in a normal CSS file...
You can include css in your vue component in the style tag section as below:
<style scoped src="#/assets/styles/myCSSTemplate.css">
</style>
Also try to use proper structure when creating a vue component by having template, script and style sections.
For exmaple you can create Vue instane in App.vue and then have a component as YourComponent.vue
Refer to Vue documentation here.

Animate width of div bound to data property in Vue

I have this progress bar div, whichs width is bound to the data property result and changes accordingly. At the moment it still jumps, but I want to animate it. I thought of tracking the old and the new Value and injecting it in the css with css variables or just using a setInterval method, but tracking the 2 values seems to get quite complicated and it seemed like a overkill for me. Does anyone have an easier idea?
<template>
<div class="progress">
<div class="progress-value" :style="{ 'width': result + '%' }">
<h2>{{ result }}%</h2>
</div>
</div>
</template>
<script>
export default {
props: ["result"],
};
</script>
<style scoped>
.progress {
background: #ccc;
border-radius: 100px;
position: relative;
padding: 5px 5px;
margin: 5px 5px;
height: 40px;
width: auto;
}
.progress-value {
animation: load 3s normal forwards;
border-radius: 100px;
background: #fff;
height: 30px;
text-align: center;
}
/* #keyframes load {
0% {
width:
}
100% {
width:
}
} */
</style>
Add css transition like this:
transition-property: all;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 1s;
And fix the binding:
<div class="progress-value" :style="'width: ' + result + '%'">
See this example
<template>
<div class="progress">
<div class="progress-value" :style="'width: ' + result + '%'">
<h2>{{ result }}%</h2>
</div>
</div>
</template>
<script>
export default {
data () {
return {
result: 5
}
},
mounted() {
this.increment()
},
methods: {
increment() {
this.result += 10
if (this.result < 95) {
setTimeout(this.increment, 1000)
}
}
}
}
</script>
<style scoped>
.progress {
background: #ccc;
border-radius: 100px;
position: relative;
padding: 5px 5px;
margin: 5px 5px;
height: 40px;
width: auto;
}
.progress-value {
transition-property: all;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 1s;
background: #fff;
height: 30px;
text-align: center;
}
</style>

Vuejs v-movable with #click is not working

Im trying to implement a moveable text that can also be click and call the method. However when i try to put #click its not calling the function. Can anyone help me? Thank you..
App.vue
<template>
<div id="app">
<div>
<a #click="next()">
<movable class="testmove" posTop="222" posLeft="222" shiftKey="true"
><span>Shift Key Behavior</span></movable
>
</a>
</div>
</div>
</template>
<script>
import movable from "v-movable";
export default {
name: "app",
movable,
methmethods: {
next() {
alert("Hello");
},
},
};
</script>
<style>
body {
padding: 0;
margin: 0;
font-family: Helvetica, Arial;
}
.movable {
cursor: pointer;
}
.testmove {
/* display:block;
position: absolute; */
top: 0;
height: 150px;
width: 150px;
background: #333;
color: white;
}
.modaltitle {
background: blue;
display: block;
width: 100%;
color: white;
}
</style>
Here is the code:
https://codesandbox.io/s/cold-darkness-0zm03?file=/src/App.vue
There is a typo in your code methmethods which should be corrected to methods
You can use start event for the v-movable.
#start: fires immediately after the pointerdown event on the element

How to make a link as a file input in vue.js 2?

My vue component like this :
<template>
...
<a href="javascript:;" class="thumbs"
:title="upload">
<span class="fa fa-plus fa-2x"></span>
</a>
...
</template>
<script>
export default {
props: ['...'],
data() {
return {
...
};
},
computed:{
...
}
}
</script>
I want if click the a link, it can upload file
In javascript, I know it. If javascript like this : How to make a link act as a file input
But How can I do it in vue.js 2?
I believe there is a small misunderstanding: Vue.js 2 is still javascript. Its goal is not the same as Polymer with its fancy components - it is supposed to enhance JS, not replace it with a different structure altogether.
#David Hallberg Jönsson's answer will work perfectly fine in Vue.js 2 perfectly fine. If you want it specifically in Vue's component structure:
<template>
<!-- ... -->
<a class="fileContainer">
Click here to trigger the file uploader!
<input type="file">
</a>
<!-- ... -->
</template>
<script>
export default {
props: ['...'],
data() {
return {
...
};
},
computed:{
...
}
}
</script>
<style>
a.fileContainer {
overflow: hidden;
position: relative;
cursor: pointer;
display: inline-block;
color: lightskyblue;
}
a.fileContainer:hover {
text-decoration: underline;
color: blue;
}
a.fileContainer > input[type=file] {
cursor: inherit;
filter: alpha(opacity=0);
opacity: 0;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
text-align: right;
}
</style>
If you want to use the programmatic way in your link, it's not going to be easy because some browsers don't allow you to trigger click events on input type="file" elements. Your best bet would be to go this way.
(Also, technically you can still use jQuery with Vue, so the code in that link could still work if you wanted it to.)
If you want to know how to handle uploading files, there are many tutorials and some components already pre-made.
You can actually do this using only CSS, as explained here.
Example (from the link above):
.fileContainer {
overflow: hidden;
position: relative;
}
.fileContainer [type=file] {
cursor: inherit;
display: block;
font-size: 999px;
filter: alpha(opacity=0);
min-height: 100%;
min-width: 100%;
opacity: 0;
position: absolute;
right: 0;
text-align: right;
top: 0;
}
/* Example stylistic flourishes */
.fileContainer {
background: red;
border-radius: .5em;
float: left;
padding: .5em;
}
.fileContainer [type=file] {
cursor: pointer;
}
}
<p>So various methods prevent file upload inputs from being styled conveniently. But that needn't be the case!</p>
<label class="fileContainer">
Click here to trigger the file uploader!
<input type="file"/>
</label>