1

I'm fiddling around with vue for the first time and having troubles with getting v-bind:style="styleObject" getting to work properly. It works when styleObject only has one key/value-pair in it, but nothing comes when I have more than 1 key/value-pair.

When running console.log() the values comes out as they should.

My vue code:

<script>
import Vue from 'vue';
import ImageObject from './SkyCropImage.class';

export default Vue.component('sky-crop', {
    props: {
        src: String,
        focalpoint: String,
        mode: String,
        round: String,
        type: {
            type: String,
            default: 'img',
        },
    },
    data() {
        return {
            image: new ImageObject(this.src),
            srcString: '',
            styleObject: { },
        };
    },
    methods: {
        anchorString(image) {
            if (this.$el.firstChild.localName !== 'img') {
                this.styleObject.backgroundPosition = `${image.anchor.x} ${image.anchor.y}`;
            } else {
                const pointX = (image.anchor.x.replace('%', '') * 1) / 100;
                const pointY = (image.anchor.y.replace('%', '') * 1) / 100;

                const differenceX = image.parent.width - image.calculatedInfo.width;
                const differenceY = image.parent.height - image.calculatedInfo.height;

                const anchorX = Math.min(0, differenceX * pointX);
                const anchorY = Math.min(0, differenceY * pointY);

                this.styleObject.transform = `translate(${anchorX}px, ${anchorY}px)`;
            }
        },
        concatSrc(string) {
            this.srcString = string;

            if (this.type !== 'img') {
                this.styleObject.backgroundImage = `url(${string})`;
            }
        },
    },
    created() {
        this.image.mode = this.mode;
        this.image.round = this.round;
        this.image.anchor = {
            x: this.focalpoint.split(',')[0],
            y: this.focalpoint.split(',')[1],
        };
    },
    mounted() {
        this.image.setParentInfo(this.$el);
        this.image.runCropJob();
        this.anchorString(this.image);
        this.concatSrc(this.image.outputUrl);
    },
});

My template:

<div class="skyCrop-parent">
<img
    class="skyCrop-element"
    alt=""
    v-if="type === 'img'"
    v-bind:src="srcString" 
    v-bind:style="styleObject" />
// img result: <img alt="" src="https://source.unsplash.com/Ixp4YhCKZkI/700x394" class="skyCrop-element" style="transform: translate(-50px, 0px);">

<div 
    class="skyCrop-element"
    v-bind:style="styleObject"
    v-else>
</div>
//div result: <div class="skyCrop-element"></div>

</div>

How the component is called:

<sky-crop
    src="https://source.unsplash.com/Ixp4YhCKZkI/1600x900"
    focalpoint="50%,50%"
    mode="width"
    round="175"
    type="div">
</sky-crop>

<sky-crop
    src="https://source.unsplash.com/Ixp4YhCKZkI/1600x900"
    focalpoint="50%,50%"
    mode="width"
    round="175">
</sky-crop>

1 Answer 1

2

The bug lies in the way Vue handles reactivity.

Since I tried to add key/value pair to styleObject like this:

this.styleObject.backgroundPosition = `${image.anchor.x} ${image.anchor.y}`;

Vue could not detect the change since the keys i tried to reference was not declare beforehand. The solution could be defining all future could be keys, which would work just fine. However using vm.$set() would be better since it handles creating the key and initiates the reactivity at the same time. In short this line (and the others which did the same):

this.styleObject.backgroundPosition = `${image.anchor.x} ${image.anchor.y}`;

Became this:

this.$set(this.styleObject, 'background-position', `${image.anchor.x} ${image.anchor.y}`);

Vue documentation about the reason for the change: https://v2.vuejs.org/v2/guide/reactivity.html

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.