Related
I used the Composition API when migrating the project from vue2.x to vue3.0, but the page does not work properly, in vue3.0
The environment prompts me to have an "Unexpected mutation of "task" prop" error, I want to know how to write the correct compos API
This is Vue2.x code
<template>
<transition name="fade">
<div class="task" v-if="!task.deleted">
<input :id="id" type="checkbox" v-model="task.done" />
<label :for="id">{{ task.title }}</label>
<transition name="fade">
<span
class="task_delete"
v-show="task.done"
#click="deleteTask({ task })"
>
<i class="fa fa-trash"></i>
</span>
</transition>
</div>
</transition>
</template>
<script>
import { mapMutations } from "vuex";
let GID = 1;
export default {
props: {
task: {
type: Object,
required: true,
},
},
data() {
return {
id: `task-${GID++}`,
};
},
methods: {
...mapMutations(["deleteTask"]),
},
};
</script>
<style lang="scss">
.task {
display: flex;
padding: 12px 0;
border-bottom: 1px solid #eee;
font-size: 14px;
}
.task input {
display: none;
}
.task label {
flex: 1;
line-height: 20px;
}
.task label:before,
.task label:after {
content: "";
display: inline-block;
margin-right: 20px;
margin-top: 1px;
width: 14px;
height: 14px;
vertical-align: top;
}
.task label:before {
border: 1px solid #ccc;
border-radius: 2px;
background-color: white;
}
.task label:after {
content: "\f00c";
position: relative;
display: none;
z-index: 10;
margin-right: -16px;
width: 10px;
height: 10px;
padding: 3px;
border-radius: 2px;
font: normal normal normal 10px/1 FontAwesome;
color: white;
background-color: #ccc;
float: left;
}
.task input:checked + label:after {
display: inline-block;
}
.task_delete {
padding: 0 10px;
color: #ccc;
font-size: 16px;
}
.fade-leave-to,
.fade-enter {
opacity: 0;
}
.fade-enter-to,
.fade-leave {
opacity: 1;
}
.fade-enter-active,
.fade-leave-active {
transition: all 0.3s ease;
}
</style>
This is Vue3.0 code use Composition API, but not work
<template>
<transition name="fade">
<div class="task" v-if="!data.task.deleted">
<input :id="id" type="checkbox" v-model="data.task.done" />
<label :for="id">{{ data.task.title }}</label>
<transition name="fade">
<span
class="task_delete"
v-show="data.task.done"
#click="deleteTask({ task })"
>
<i class="fa fa-trash"></i>
</span>
</transition>
</div>
</transition>
</template>
<script>
import { reactive } from "vue";
import { mapMutations } from "vuex";
let GID = 1;
export default {
name: "Task",
props: {
task: {
type: Object,
required: true,
},
},
setup(props) {
const data = reactive({
task: props.task,
id: `task-${GID++}`,
});
return { data };
},
methods: {
...mapMutations(["deleteTask"]),
},
};
</script>
<style lang="scss">
.task {
display: flex;
padding: 12px 0;
border-bottom: 1px solid #eee;
font-size: 14px;
}
.task input {
display: none;
}
.task label {
flex: 1;
line-height: 20px;
}
.task label:before,
.task label:after {
content: "";
display: inline-block;
margin-right: 20px;
margin-top: 1px;
width: 14px;
height: 14px;
vertical-align: top;
}
.task label:before {
border: 1px solid #ccc;
border-radius: 2px;
background-color: white;
}
.task label:after {
content: "\f00c";
position: relative;
display: none;
z-index: 10;
margin-right: -16px;
width: 10px;
height: 10px;
padding: 3px;
border-radius: 2px;
font: normal normal normal 10px/1 FontAwesome;
color: white;
background-color: #ccc;
float: left;
}
.task input:checked + label:after {
display: inline-block;
}
.task_delete {
padding: 0 10px;
color: #ccc;
font-size: 16px;
}
.fade-leave-to,
.fade-enter {
opacity: 0;
}
.fade-enter-to,
.fade-leave {
opacity: 1;
}
.fade-enter-active,
.fade-leave-active {
transition: all 0.3s ease;
}
</style>
I think the problem is you're using v-model for props on checkbox, it will change props value directly and vue not allow it. Try update props value manual by emit event. And u dont need to use props with reactive in child component, but need to reactive that props in parent component
<input :id="id" type="checkbox" v-value="task.done" #change="updateCheckbox($event)")/>
In script:
export default {
name: "Task",
props: {
task: {
type: Object,
required: true,
},
},
emits: ['updateCheckbox'],
setup(props) {
const data = reactive({
id: `task-${GID++}`,
});
return { data };
},
methods: {
updateCheckbox(e) {
this.$emit('updateCheckbox', e.target.value)
}
},
};
I'm trying to create an image slider, which fades the images. Image 1 should fade-out at the same moment as image 2 fades in. In other words: there shouldn't be a gap between them. Right now it does nothing like fading. The code is working, as so far that when the user clicks "next", the current images disappears, 0.9s later the next image appears. There is a delay of 0.9s between them (the same amount as declared in the CSS), so somehow it recognizes the transition time. It is only not fading, after clicking the button it immediately disappears. What am I missing?
My code
<template>
<div>
<transition-group name='fade' tag='div'>
<div v-for="i in [currentIndex]" :key='i'>
<img :src="currentImg" />
</div>
</transition-group>
<a class="prev" #click="prev" href='#'>❮</a>
<a class="next" #click="next" href='#'>❯</a>
</div>
</template>
<script>
export default {
data() {
return {
images: [
'https://cdn.pixabay.com/photo/2015/12/12/15/24/amsterdam-1089646_1280.jpg',
'https://cdn.pixabay.com/photo/2016/02/17/23/03/usa-1206240_1280.jpg',
'https://cdn.pixabay.com/photo/2015/05/15/14/27/eiffel-tower-768501_1280.jpg',
'https://cdn.pixabay.com/photo/2016/12/04/19/30/berlin-cathedral-1882397_1280.jpg'
],
timer: null,
currentIndex: 0,
show: true
};
},
mounted: function () {
this.startSlide();
},
methods: {
startSlide: function () {
this.timer = setInterval(this.next, 4000);
},
next: function () {
this.currentIndex += 1;
},
prev: function () {
this.currentIndex -= 1;
},
},
computed: {
currentImg: function () {
return this.images[Math.abs(this.currentIndex) % this.images.length];
},
},
};
</script>
<style>
.fade-enter-active,
.fade-leave-active {
transition: all 0.9s ease;
overflow: hidden;
visibility: visible;
position: absolute;
width:100%;
opacity: 1;
}
.fade-enter,
.fade-leave-to {
visibility: hidden;
width:100%;
opacity: 0;
}
img {
height:600px;
width:100%
}
.prev, .next {
cursor: pointer;
position: absolute;
top: 40%;
width: auto;
padding: 16px;
color: white;
font-weight: bold;
font-size: 18px;
transition: 0.7s ease;
border-radius: 0 4px 4px 0;
text-decoration: none;
user-select: none;
}
.next {
right: 0;
}
.prev {
left: 0;
}
.prev:hover, .next:hover {
background-color: rgba(0,0,0,0.9);
}
</style>
Change .fade-enter to .fade-enter-from.
See example
The position:absolute was messing things up here... Removed this line, now it works like a charm!
<div
class="BgContainer"
#mousemove="mouseMove"
v-bind:style="{
transform: 'matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)',
}"
>
I am trying to update a transform: matrix3d() style on mouseMove function
methods: {
mouseMove(event) {
console.log(event.clientX, event.clientY)
},
},
trying to learn Vue (Nuxt.js) and I am wondering what would be the best way to update this transform based on mouse position and update the transform on mouseMove. How can I achieve something like this where newX and newY are dynamic based on mouse position?
v-bind:style="{
transform: 'matrix3d(1.025,0,0,"newX",0,1.025,0,"newY",0,0,1,0,0,0,0,1)',
}"
EDIT - whole vue file
<template>
<div class="prop_scroller">
<div
class="BgContainer"
#mousemove="mouseMove"
v-bind:style="{
transform:
'matrix3d(1.025,0,0,' +
newX+
',0,1.025,0,' +
newY +
',0,0,1,0,0,0,0,1)',
}"
>
<i class="sacbg"> </i>
<div class="after"></div>
</div>
</div>
</template>
<script>
import VanillaTilt from 'vanilla-tilt'
export default {
data: function () {
newX: 0
newY: 0
},
mounted: function () {
// VanillaTilt.init(this.$refs.bg)
console.log(this.$refs)
},
methods: {
mouseMove(event) {
console.log(event.clientX, event.clientY)
},
},
}
</script>
<style lang="scss" scoped>
.prop_scroller {
position: absolute;
top: -50px;
right: -70px;
bottom: -60px;
left: -50px;
overflow: scroll;
}
.js-tilt-glare-inner {
backface-visibility: hidden;
}
.BgContainer {
height: 100%;
width: 100%;
overflow: hidden;
position: absolute;
// object-fit: cover;
z-index: 300;
backface-visibility: hidden;
transform-style: preserve-3d;
top: 0;
right: 0;
bottom: 0;
left: 0;
i {
position: absolute !important;
top: -70px !important;
right: -70px !important;
bottom: -60px !important;
left: -60px !important;
background-size: cover;
background-position: center;
background-image: url('~static/mural-bg.jpg');
}
.MuralBg {
// animation: 1s appear;
margin: auto;
width: 100vw;
height: auto;
}
.after {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(26, 33, 42, 0.2);
animation: 1.2s fadeBgOut;
}
}
#keyframes fadeBgOut {
0% {
background-color: rgba(26, 33, 42, 0.8);
}
100% {
background-color: rgba(26, 33, 42, 0.2);
}
}
</style>
Try out with string template literals :
v-bind:style="{
transform: `matrix3d(1.025,0,0,${newX},0,1.025,0,${newY},0,0,1,0,0,0,0,1)`,
}"
or by concatenation :
v-bind:style="{
transform: 'matrix3d(1.025,0,0,'+newX+',0,1.025,0,'+newY+',0,0,1,0,0,0,0,1)',
}"
and your data property should be a function that returns an object :
<script>
import VanillaTilt from 'vanilla-tilt'
export default {
data: function () {
return {
newX: 0
newY: 0
}
},
mounted: function () {
// VanillaTilt.init(this.$refs.bg)
console.log(this.$refs)
},
methods: {
mouseMove(event) {
console.log(event.clientX, event.clientY)
this.newX=event.clientX;
this.newY=event.clientY;
},
},
}
</script>
UPDATE dropped this approach and went with vue-awesome-swiper script
I"m been stuck on this for days. Basically I want to use css scroll snap and I want to monitor scroll also.
In this basic example with just javascript it works fine scroll event fires and div snaps with css. The other pen below with vue.js does not and that is my problem. Losing hair about this... any help appreciated!
https://codepen.io/travis-pancakes/pen/pGYOZK?editors=0011
var i = 0;
function Onscrollfnction(event) { document.getElementById("demo").innerHTML = i;
i = i + 1;
};
/* setup */
html, body, .holster {
height: 100%;
}
.holster {
display: flex;
align-items: center;
justify-content: space-between;
flex-flow: column nowrap;
font-family: monospace;
}
.container {
display: flex;
overflow: auto;
outline: 1px dashed lightgray;
flex: none;
}
.container.x {
width: 100%;
height: 128px;
flex-flow: row nowrap;
}
.container.y {
width: 256px;
height: 256px;
flex-flow: column nowrap;
}
/* scroll-snap */
.x.mandatory-scroll-snapping {
scroll-snap-type: x mandatory;
}
.y.mandatory-scroll-snapping {
scroll-snap-type: y mandatory;
}
.x.proximity-scroll-snapping {
scroll-snap-type: x proximity;
}
.y.proximity-scroll-snapping {
scroll-snap-type: y proximity;
}
.container > div {
text-align: center;
scroll-snap-align: center;
flex: none;
}
.x.container > div {
line-height: 128px;
font-size: 64px;
width: 100%;
height: 128px;
}
.y.container > div {
line-height: 256px;
font-size: 128px;
width: 256px;
height: 256px;
}
/* appearance fixes */
.y.container > div:first-child {
line-height: 1.3;
font-size: 64px;
}
/* coloration */
.container > div:nth-child(even) {
background-color: #87EA87;
}
.container > div:nth-child(odd) {
background-color: #87CCEA;
}
<div><p>Scrolled <span id="demo">0</span> times.</p></div>
<div class="container y mandatory-scroll-snapping" onscroll="Onscrollfnction();" dir="ltr">
<div>Y Mand. LTR</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</div>
The vue.js, vuetify version does not
https://codepen.io/travis-pancakes/pen/BMbqPq?editors=1111
new Vue({
el: '#app',
data: function(){
return {
i: 0
}
},
created () {
},
methods: {
Onscrollfnction (event) {
document.getElementById("demo").innerHTML = this.i;
this.i = this.i + 1;
console.log('i ', i)
}
}
});
/* setup */
html, body, .holster {
height: 100%;
}
.holster {
display: flex;
align-items: center;
justify-content: space-between;
flex-flow: column nowrap;
font-family: monospace;
}
.container {
display: flex;
overflow: auto;
outline: 1px dashed lightgray;
flex: none;
}
.container.x {
width: 100%;
height: 128px;
flex-flow: row nowrap;
}
.container.y {
width: 256px;
height: 256px;
flex-flow: column nowrap;
}
/* scroll-snap */
.x.mandatory-scroll-snapping {
scroll-snap-type: x mandatory;
}
.y.mandatory-scroll-snapping {
scroll-snap-type: y mandatory;
}
.x.proximity-scroll-snapping {
scroll-snap-type: x proximity;
}
.y.proximity-scroll-snapping {
scroll-snap-type: y proximity;
}
.container > div {
text-align: center;
scroll-snap-align: center;
flex: none;
}
.x.container > div {
line-height: 128px;
font-size: 64px;
width: 100%;
height: 128px;
}
.y.container > div {
line-height: 256px;
font-size: 128px;
width: 256px;
height: 256px;
}
/* appearance fixes */
.y.container > div:first-child {
line-height: 1.3;
font-size: 64px;
}
/* coloration */
.container > div:nth-child(even) {
background-color: #87EA87;
}
.container > div:nth-child(odd) {
background-color: #87CCEA;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<!-- could use v-scroll="Onscrollfnction" with vuetify" --->
<div class="container y mandatory-scroll-snapping"
v-on:scroll.native="Onscrollfnction" dir="ltr">
<div>Y Mand. LTR</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</div>
<p>Scrolled <span id="demo">0</span> times.</p>
</div>
</div>
vue-awesome-swiper does the functionality I'm going for
I have tried jsplumb script in .html file under the script tag. This is working fine.
<body>
<div id="q-app"></div>
<!-- built files will be auto injected -->
<script>
jsPlumb.ready(function() {
jsPlumb.connect({
source:"item_left",
target:"item_right",
endpoint:"Rectangle"
});
jsPlumb.draggable("item_left");
jsPlumb.draggable("item_right");
});
</script>
</body>
But now i want to integrate this jsplumb code/script in .vue file.I tried to put this script in .vue file under script tag, but i did not get any output except an blank page with zero errors. How can i proceed further?.Guide me with some simple example.
You can try this:
mydraggableview.vue
<template>
<div id="diagramContainer">
<div id="item_left" class="item"></div>
<div id="item_right" class="item" style="margin-left:50px;"></div>
</div>
</template>
<script>
import jsplumb from 'jsplumb'
export default {
props: ['yourProps'],
data() {
return {
your: data
}
},
mounted(){
jsPlumb.ready(function() {
jsPlumb.connect({
source:"item_left",
target:"item_right",
endpoint:"Rectangle"
})
})
}
}
</script>
Then you can import where you are going to use it.
otherfile.js
<script>
import myDraggableComponent from './path/to/component/mydraggableview'
</script>
and use it as directive or inside your component.
I managed to put together working code based on jsplumb demo community example -
<template>
<div id="canvas" class="jtk-demo-canvas canvas-wide flowchart-demo jtk-surface jtk-surface-nopan">
<div id="flowchartWindow1" class="window jtk-node">1</div>
<div id="flowchartWindow2" class="window jtk-node">2</div>
<div id="flowchartWindow3" class="window jtk-node">3</div>
<div id="flowchartWindow4" class="window jtk-node">4</div>
</div>
</template>
<script>
import { jsPlumb as JSPlumb } from 'jsplumb'
export default {
name: 'JsPlumb',
data () {
return {
}
},
mounted () {
JSPlumb.ready(function() {
var instance = window.jsp = JSPlumb.getInstance({
// default drag options
DragOptions: { cursor: 'pointer', zIndex: 2000 },
// the overlays to decorate each connection with. note that the label overlay uses a function to generate the label text; in this
// case it returns the 'labelText' member that we set on each connection in the 'init' method below.
ConnectionOverlays: [
[ "Arrow", {
location: 1,
visible:true,
width:11,
length:11,
id:"ARROW",
events:{
click:function() { alert("you clicked on the arrow overlay")}
}
} ],
[ "Label", {
location: 0.1,
id: "label",
cssClass: "aLabel",
events:{
tap:function() { alert("hey"); }
}
}]
],
Container: "canvas"
});
var basicType = {
connector: "StateMachine",
paintStyle: { stroke: "red", strokeWidth: 4 },
hoverPaintStyle: { stroke: "blue" },
overlays: [
"Arrow"
]
};
instance.registerConnectionType("basic", basicType);
// this is the paint style for the connecting lines..
var connectorPaintStyle = {
strokeWidth: 2,
stroke: "#61B7CF",
joinstyle: "round",
outlineStroke: "white",
outlineWidth: 2
},
// .. and this is the hover style.
connectorHoverStyle = {
strokeWidth: 3,
stroke: "#216477",
outlineWidth: 5,
outlineStroke: "white"
},
endpointHoverStyle = {
fill: "#216477",
stroke: "#216477"
},
// the definition of source endpoints (the small blue ones)
sourceEndpoint = {
endpoint: "Dot",
paintStyle: {
stroke: "#7AB02C",
fill: "transparent",
radius: 7,
strokeWidth: 1
},
isSource: true,
connector: [ "Flowchart", { stub: [40, 60], gap: 10, cornerRadius: 5, alwaysRespectStubs: true } ],
connectorStyle: connectorPaintStyle,
hoverPaintStyle: endpointHoverStyle,
connectorHoverStyle: connectorHoverStyle,
dragOptions: {},
overlays: [
[ "Label", {
location: [0.5, 1.5],
label: "Drag",
cssClass: "endpointSourceLabel",
visible:false
} ]
]
},
// the definition of target endpoints (will appear when the user drags a connection)
targetEndpoint = {
endpoint: "Dot",
paintStyle: { fill: "#7AB02C", radius: 7 },
hoverPaintStyle: endpointHoverStyle,
maxConnections: -1,
dropOptions: { hoverClass: "hover", activeClass: "active" },
isTarget: true,
overlays: [
[ "Label", { location: [0.5, -0.5], label: "Drop", cssClass: "endpointTargetLabel", visible:false } ]
]
},
init = function (connection) {
connection.getOverlay("label").setLabel(connection.sourceId.substring(15) + "-" + connection.targetId.substring(15));
};
var _addEndpoints = function (toId, sourceAnchors, targetAnchors) {
for (var i = 0; i < sourceAnchors.length; i++) {
var sourceUUID = toId + sourceAnchors[i];
instance.addEndpoint("flowchart" + toId, sourceEndpoint, {
anchor: sourceAnchors[i], uuid: sourceUUID
});
}
for (var j = 0; j < targetAnchors.length; j++) {
var targetUUID = toId + targetAnchors[j];
instance.addEndpoint("flowchart" + toId, targetEndpoint, { anchor: targetAnchors[j], uuid: targetUUID });
}
};
// suspend drawing and initialise.
instance.batch(function () {
_addEndpoints("Window4", ["TopCenter", "BottomCenter"], ["LeftMiddle", "RightMiddle"]);
_addEndpoints("Window2", ["LeftMiddle", "BottomCenter"], ["TopCenter", "RightMiddle"]);
_addEndpoints("Window3", ["RightMiddle", "BottomCenter"], ["LeftMiddle", "TopCenter"]);
_addEndpoints("Window1", ["LeftMiddle", "RightMiddle"], ["TopCenter", "BottomCenter"]);
// listen for new connections; initialise them the same way we initialise the connections at startup.
instance.bind("connection", function (connInfo, originalEvent) {
init(connInfo.connection);
});
// make all the window divs draggable
instance.draggable(JSPlumb.getSelector(".flowchart-demo .window"), { grid: [20, 20] });
// THIS DEMO ONLY USES getSelector FOR CONVENIENCE. Use your library's appropriate selector
// method, or document.querySelectorAll:
//JSPlumb.draggable(document.querySelectorAll(".window"), { grid: [20, 20] });
// connect a few up
instance.connect({uuids: ["Window2BottomCenter", "Window3TopCenter"]});
instance.connect({uuids: ["Window2LeftMiddle", "Window4LeftMiddle"]});
instance.connect({uuids: ["Window4TopCenter", "Window4RightMiddle"]});
instance.connect({uuids: ["Window3RightMiddle", "Window2RightMiddle"]});
instance.connect({uuids: ["Window4BottomCenter", "Window1TopCenter"]});
instance.connect({uuids: ["Window3BottomCenter", "Window1BottomCenter"] });
//
//
// listen for clicks on connections, and offer to delete connections on click.
//
instance.bind("click", function (conn, originalEvent) {
// if (confirm("Delete connection from " + conn.sourceId + " to " + conn.targetId + "?"))
// instance.detach(conn);
conn.toggleType("basic");
});
instance.bind("connectionDrag", function (connection) {
console.log("connection " + connection.id + " is being dragged. suspendedElement is ", connection.suspendedElement, " of type ", connection.suspendedElementType);
});
instance.bind("connectionDragStop", function (connection) {
console.log("connection " + connection.id + " was dragged");
});
instance.bind("connectionMoved", function (params) {
console.log("connection " + params.connection.id + " was moved");
});
});
JSPlumb.fire("jsPlumbDemoLoaded", instance);
})
}
}
</script>
<style>
.item{
height:50px;
width:50px;
background-color: red;
display: inline-block;
}
.demo {
/* for IE10+ touch devices */
touch-action:none;
}
.flowchart-demo .window {
border: 1px solid #346789;
box-shadow: 2px 2px 19px #aaa;
-o-box-shadow: 2px 2px 19px #aaa;
-webkit-box-shadow: 2px 2px 19px #aaa;
-moz-box-shadow: 2px 2px 19px #aaa;
-moz-border-radius: 0.5em;
border-radius: 0.5em;
opacity: 0.8;
width: 80px;
height: 80px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
text-align: center;
z-index: 20;
position: absolute;
background-color: #eeeeef;
color: black;
font-family: helvetica, sans-serif;
padding: 0.5em;
font-size: 0.9em;
-webkit-transition: -webkit-box-shadow 0.15s ease-in;
-moz-transition: -moz-box-shadow 0.15s ease-in;
-o-transition: -o-box-shadow 0.15s ease-in;
transition: box-shadow 0.15s ease-in;
}
.flowchart-demo .window:hover {
box-shadow: 2px 2px 19px #444;
-o-box-shadow: 2px 2px 19px #444;
-webkit-box-shadow: 2px 2px 19px #444;
-moz-box-shadow: 2px 2px 19px #444;
opacity: 0.6;
}
.flowchart-demo .active {
border: 1px dotted green;
}
.flowchart-demo .hover {
border: 1px dotted red;
}
#flowchartWindow1 {
top: 34em;
left: 5em;
}
#flowchartWindow2 {
top: 7em;
left: 36em;
}
#flowchartWindow3 {
top: 27em;
left: 48em;
}
#flowchartWindow4 {
top: 23em;
left: 22em;
}
.flowchart-demo .jtk-connector {
z-index: 4;
}
.flowchart-demo .jtk-endpoint, .endpointTargetLabel, .endpointSourceLabel {
z-index: 21;
cursor: pointer;
}
.flowchart-demo .aLabel {
background-color: white;
padding: 0.4em;
font: 12px sans-serif;
color: #444;
z-index: 21;
border: 1px dotted gray;
opacity: 0.8;
cursor: pointer;
}
.flowchart-demo .aLabel.jtk-hover {
background-color: #5C96BC;
color: white;
border: 1px solid white;
}
.window.jtk-connected {
border: 1px solid green;
}
.jtk-drag {
outline: 4px solid pink !important;
}
path, .jtk-endpoint {
cursor: pointer;
}
.jtk-overlay {
background-color:transparent;
}
/* ---------------------------------------------------------------------------------------------------- */
/* --- page structure --------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------- */
body {
background-color: #FFF;
color: #434343;
font-family: "Lato", sans-serif;
font-size: 14px;
font-weight: 400;
height: 100%;
padding: 0;
}
.jtk-bootstrap {
min-height:100vh;
display:flex;
flex-direction: column;
}
.jtk-bootstrap .jtk-page-container {
display:flex;
width:100vw;
justify-content: center;
flex:1;
}
.jtk-bootstrap .jtk-container {
width: 60%;
max-width:800px;
}
.jtk-bootstrap-wide .jtk-container {
width: 80%;
max-width:1187px;
}
.jtk-demo-main {
position: relative;
margin-top:98px;
display:flex;
flex-direction:column;
}
.jtk-demo-main .description {
font-size: 13px;
margin-top: 25px;
padding: 13px;
margin-bottom: 22px;
background-color: #f4f5ef;
}
.jtk-demo-main .description li {
list-style-type: disc !important;
}
.jtk-demo-canvas {
height:750px;
max-height:700px;
border:1px solid #CCC;
background-color:white;
display: flex;
flex-grow:1;
}
.canvas-wide {
margin-left:0;
}
.miniview {
position: absolute;
top: 25px;
right: 25px;
z-index: 100;
}
.jtk-demo-dataset {
text-align: left;
max-height: 600px;
overflow: auto;
}
.demo-title {
float:left;
font-size:18px;
}
.controls {
top: 25px;
color: #FFF;
margin-right: 10px;
position: absolute;
left: 25px;
z-index: 1;
display:flex;
}
.controls i {
background-color: #5184a0;
border-radius: 4px;
cursor: pointer;
margin-right: 4px;
padding: 4px;
}
li {
list-style-type: none;
}
/* ------------------------ node palette -------------------- */
.sidebar {
margin:0;
padding:10px 0;
background-color: white;
display:flex;
flex-direction:column;
border: 1px solid #CCC;
align-items: center;
}
.sidebar-item {
background-color: #CCC;
border-radius: 11px;
color: #585858;
cursor: move;
padding: 8px;
width: 128px;
text-align: center;
margin: 10px;
outline:none;
}
button.sidebar-item {
cursor:pointer;
width:150px;
}
.sidebar select {
height:35px;
width:150px;
outline:none;
}
.sidebar-item.katavorio-clone-drag {
margin:0;
border:1px solid white;
}
.sidebar-item:hover, .sidebar-item.katavorio-clone-drag {
background-color: #5184a0;
color:white;
}
/*
.sidebar button {
background-color: #30686d;
outline: none;
border: none;
margin-left: 25px;
padding: 7px;
color: white;
cursor:pointer;
}*/
.sidebar i {
float:left;
}
#media (max-width: 600px) {
.sidebar {
float:none;
height: 55px;
width: 100%;
padding-top:0;
}
.sidebar ul li {
display:inline-block;
margin-top: 7px;
width:67px;
}
.jtk-demo-canvas {
margin-left: 0;
margin-top:10px;
height:364px;
}
}
/* ---------------------------------------------------------------------------------------------------- */
/* --- jsPlumb setup ---------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------- */
.jtk-surface-pan {
display:none;
}
.jtk-connector {
z-index:9;
}
.jtk-connector:hover, .jtk-connector.jtk-hover {
z-index:10;
}
.jtk-endpoint {
z-index:12;
opacity:0.8;
cursor:pointer;
}
.jtk-overlay {
background-color: white;
color: #434343;
font-weight: 400;
padding: 4px;
z-index:10;
}
.jtk-overlay.jtk-hover {
color: #434343;
}
path {
cursor:pointer;
}
.delete {
padding: 2px;
cursor: pointer;
float: left;
font-size: 10px;
line-height: 20px;
}
.add, .edit {
cursor: pointer;
float:right;
font-size: 10px;
line-height: 20px;
margin-right:2px;
padding: 2px;
}
.edit:hover {
color: #ff8000;
}
.selected-mode {
color:#E4F013;
}
.connect {
width:10px;
height:10px;
background-color:#f76258;
position:absolute;
bottom: 13px;
right: 5px;
}
/* header styles */
.demo-links {
position: fixed;
right: 0;
top: 57px;
font-size: 11px;
background-color: white;
opacity: 0.8;
padding-right: 10px;
padding-left: 5px;
text-transform: uppercase;
z-index:100001;
}
.demo-links div {
display:inline;
margin-right:7px;
margin-left:7px;
}
.demo-links i {
padding:4px;
}
.jtk-node {
background-color: #5184a0;
border-radius: 4px;
cursor: pointer;
font-size: 12px;
position: absolute;
z-index: 11;
overflow: hidden;
min-width:80px;
min-height:30px;
width: auto;
}
.jtk-node .name {
color: white;
cursor: move;
font-size: 13px;
line-height: 24px;
padding: 6px;
text-align: center;
}
.jtk-node .name span {
cursor:pointer;
}
[undo], [redo] { background-color:darkgray !important; }
[can-undo='true'] [undo], [can-redo='true'] [redo] { background-color: #3E7E9C !important; }
</style>
See the official article to integrate with VueJs:
https://docs.jsplumbtoolkit.com/toolkit/current/articles/demo-vue2.html