How to replace css class name partially in Vue? - vue.js

Let's say I have this html element
<div class="progress-bar w-90"></div>
and I want to replace 90 with an object from vue. I tried below but syntax
<div :class="progress-bar w-{{ progress.value }}"></div>

You cannot use {{ }} in attribute/props, better to use template literals as below.
<div :class="`progress-bar w-${progress.value}`"></div>

You can achieve text-binding in this way
<div :class="'progress-bar w-'+progress.value"></div>

Related

Concatenating variable with querySelector VueJS

I am trying to concatenate a Vue variable with an id in querySelector, and for some reason it is not targeting any element.
I am currently using:
document.querySelectorAll(".container:not(#`${this.id}`"));
this.id is just a string, and doesn't include the '#', which is why I am adding it to the querySelector here
What I have in the DOM is:
<div id="header-1" class="container">
.......
</div>
<div id="header-2" class="container">
.......
</div>
<div id="header-3" class="container">
.......
</div>
You should look at using 'refs' to select a DOM directly instead of native javascript and CSS selectors.
For example this.$refs[this.id]
https://v2.vuejs.org/v2/api/#ref

Vue how to use id in components?

how to use id in components, the code as below:
The components code as below:Profilelist.js
<template>
<div class="col col-m-12 col-t-6 col-d-6 box-item f-software">
<div class="item animated">
<div class="desc">
<div class="image">
<a href="#popup-{{id}}" class="has-
popup"><img src="{{workpic}}" alt="" /></a>
</div>
<div class="category">{{category}}</div>
<div class="name">
<a href="#popup-{{id}}" class="has-
popup">{{project_name}}</a>
</div>
</div>
</div>
<div id="popup-{{id}}" class="popup-box mfp-fade mfp-hide">
<div class="content">
<div class="image">
<img src="{{workpic}}" alt="">
</div>
<div class="desc">
<div class="category">{{category}}</div>
<h4>{{project_name}}</h4>
<p>
{{project_content}}。
</p>
<a href="{{project_link}}"
class="btn">View Project</a>
</div>
</div>
</div>
</div>
</template>
The index file code as below:
<div class="row box-items">
<ProfileList
v-for="profile in loadedProfiles"
:key="profile.id"
v-bind:id="profile.id"
:workpic="profile.workpic"
:category="profile.category"
:project_name="profile.project_name"
:project_content="profile.project_content"
v-bind:project_link="profile.project_link"
/>
</div>
And it outcome an error code as below:
href="#popup-{{id}}": Interpolation inside attributes has been removed. Use v-bind or the colon shorthand instead. For example, instead of , use .
src="{{workpic}}": Interpolation inside attributes has been removed. Use v-bind or the colon shorthand instead. For example, instead of , use .
href="#popup-{{id}}": Interpolation inside attributes has been removed. Use v-bind or the colon shorthand instead. For example, instead of , use .
id="popup-{{id}}": Interpolation inside attributes has been removed. Use v-bind or the colon shorthand instead. For example, instead of , use .
src="{{workpic}}": Interpolation inside attributes has been removed. Use v-bind or the colon shorthand instead. For example, instead of , use .
href="{{project_link}}": Interpolation inside attributes has been removed. Use v-bind or the colon shorthand instead. For example, instead of , use .
You have to bind the data to your attributes and do the proper concatenation using template literals, replace your attributes following the examples
:href="`#popup-${id}`"
:src="workpic"
:id="`popup-${id}`"
:href="project_link":

ThymeLeaf pass variable to vue js

Thymeleaf th:attr not working with Vue bind property
<truncate th:attr="'v-bind:text'=${message}"/>
The above line not giving me error in both Vue and Thymeleaf but nothing display on page
below is the response from server side
Once I remove 'v-bind:' prefix and use some thing like "th:attr="text=${user.comment}" its working as expected
<div class="col-lg-12 col-sm-12 col-xs-12 row_block_padding" th:each="user : ${response.users}">
<!-- OTHER CODE -->
<div class="col-lg-10 col-sm-10 col-xs-10" style="padding-top: 15px;">
<truncate th:attr="text=${user.comment}"></truncate>
</div>
</div>
You'll need to use the th:attr directive. For example
<div th:with="message='Simple message'">
<truncate th:attr="'v-bind:text'=${message}"/>
</div>
See https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#setting-the-value-of-any-attribute
Update: to use th:attr with HTML5 invalid attributes (like v-bind:text), you need to quote the attribute name (fixed above).
This produces the following markup
<div>
<truncate v-bind:text="Simple Message"/>
</div>
You may note that this is not a valid Vue binding expression so perhaps you don't actually want to use binding and instead use
<truncate th:attr="text=${message}"/>
which would produce
<truncate text="Simple message"/>
<truncate th:attr="'v-bind='{text:'+${message}+'}'"/>
the solution of vue: another usage of v-bind
https://v2.vuejs.org/v2/api/#v-bind

VueJS render once into an element

Is it possible to just render once into an element?
Suppose I have a contenteditable div, and only want to render the first value, then stop rerendering as the model changes. Here only the initial value of variable will be rendered.
<div contenteditable="true"> {{variable}} </div>
Use v-once
<div contenteditable="true" v-once> {{variable}} </div>
You can also wrap it with a <span>:
<div contenteditable="true">
<span v-once> {{variable}} </span>
</div>
refs:
https://v2.vuejs.org/v2/guide/components.html#Cheap-Static-Components-with-v-once
https://v2.vuejs.org/v2/api/#v-once
Or another solution is simply clone the variable and just don't modify it, for example if you call it readOnlyVariable:
<div contenteditable="true"> {{readOnlyVariable}} </div>

Referencing v-model

I am trying to reference a v-model in one of my html files.
I've gone ahead and created a jsbin with a small example of what I'm trying to achieve:
https://jsbin.com/saqirekasa/edit?html,js,output
Essentially, what seems to be happening is that Vue gives an error like this in my actual project:
[Vue warn]: Invalid expression. Generated function body: scope.lookForUser({{scope.input_field}})
The problem (I believe) appears to be when I introduced this line:
<input type="text" class="form-control input-lg" placeholder="email-address" id = "button_email_submit" v-model = "input_field"/>
And then tried to reference the v-model 'input field' as such:
<button class="btn btn-info btn-lg" type="button" v-on= "click: lookForUser(#{{input_field}})">
Any ideas why Vue doesn't like this statement?
I figured this out with a bit more fiddling around -- the issue was I was not supposed to use #{{input_field}} but rather simply pass input_field text into the arguments.
Thanks! Here's my example code in case it helps anyone.
<div v-repeat="company: companies">
<div class="col-xs-12 col-md-6 col-lg-6">
<a href="#" v-on="click: selected_company_id = company.id">
</div>
</div>
I kept wanting to wrap the company.id in mustache brackets:
<a href="#" v-on="click: selected_company_id = {{company.id}}">
but I'm assuming that since it is already part of an expression, you don't need to do that.