link3151 link3152 link3153 link3154 link3155 link3156 link3157 link3158 link3159 link3160 link3161 link3162 link3163 link3164 link3165 link3166 link3167 link3168 link3169 link3170 link3171 link3172 link3173 link3174 link3175 link3176 link3177 link3178 link3179 link3180 link3181 link3182 link3183 link3184 link3185 link3186 link3187 link3188 link3189 link3190 link3191 link3192 link3193 link3194 link3195 link3196 link3197 link3198 link3199 link3200 link3201 link3202 link3203 link3204 link3205 link3206 link3207 link3208 link3209 link3210 link3211 link3212 link3213 link3214 link3215 link3216 link3217 link3218 link3219 link3220 link3221 link3222 link3223 link3224 link3225 link3226 link3227 link3228 link3229 link3230 link3231 link3232 link3233 link3234 link3235 link3236 link3237 link3238 link3239 link3240 link3241 link3242 link3243 link3244 link3245 link3246 link3247 link3248 link3249 link3250 link3251 link3252 link3253 link3254 link3255 link3256 link3257 link3258 link3259 link3260 link3261 link3262 link3263 link3264 link3265 link3266 link3267 link3268 link3269 link3270 link3271 link3272 link3273 link3274 link3275 link3276 link3277 link3278 link3279 link3280 link3281 link3282 link3283 link3284

[Vue.js] How to comment within an HTML attribute?

The final (closing) angle bracket in the code below is not interpreted as closing the <input> element:

<input type=’text’ name=’name’ <!– id=’name’ –>>

I thought this was a valid way to comment out this attribute but Google Chrome, Firefox and Notepad++ (color coding) all suggest that this is not the way to go.

I used CTRL+Shift+Q in Notepad++ to do this.

Then what is the proper way to comment out this <id> attribute?

Solution :

HTML provides no way to place a comment inside a tag.

If you are generating the HTML from a template / programming language, then you can use features of that to comment something out.

For example, in Template-Toolkit:

<input type=’text’ name=’name’ [%# id=’name’ %]>

or PHP:

<input type=’text’ name=’name’ <?php # id=’name’ ?>>

If you are using HTML 5 then you could (as an ugly hack) use a data attribute to “comment” out entire attributes.

<input type=’text’ name=’name’ data-comment-id=’name’>

Solution 2:

<input type=’text’ name=’name’ <?php /* id=’name’ */ ?> >

you may use this it will not be interpreted when viewing the source info

Solution 3:

I usually just put _x at the end of the attribute name. Then the attribute is ignored because it’s unknown. So if I wanted to comment out the id attribute from this element:

<input type=”text” name=”name” id=”name”>

I would change it to this:

<input type=”text” name=”name” id_x=”name”>

This also has the advantage of being able to search for “_x=” to find all commented attributes.

Solution 4:

I agree, that you should not use comments at this place. That said, the following should work in Chrome, Firefox and IE:

<input type=”text” %id=”test1”% class=”test2”>

[Vue.js] How to fix mongodb update function with express

there is two inputs that add some data in MongoDB, One is the title of the todo and the other is the description. When to use the updateTodo function it only works properly if I edit the title and the description at the same time, if to edit only the description it deletes the title and leaves me with the edited description. The app uses express for the server side and VueJs for the frontend and axios to make them communicate.

<template lang=”html”>
<div>
<form v-on:submit=’addTodo($event)’>
<input type=’text’ placeholder=’Add or edit a todo’ v-model=’newTodo’/>
<textarea placeholder=’Add or edit a description’ v-model=’newDescription’></textarea>
<input type=’submit’ />
</form>
<ul>
<li v-for=’todo in todos’ :key=’todo._id’>
<button>Complete</button>
<button @click=”deleteTodo(todo._id)”>X</button>
<p>{todo.title}</p>
<p>{todo.description}</p>
<button @click=”updateTodo(todo._id)”>Edit</button>
</li>
</ul>
</div>
</template>

<script>
import ToDoAPI from ‘@/services/ToDoAPI.js’
export default {
data () {
return {
newTodo: ‘’,
newDescription: ‘’,
state: ‘active’,
todos: []
}
},
mounted () {
this.loadTodos()
},
methods: {
async addTodo (evt) {
evt.preventDefault() // prevents the form’s default action from redirecting the page
const response = await ToDoAPI.addTodo(this.newTodo, this.newDescription, this.state)
this.todos.push(response.data)
this.newTodo = ‘’ // clear the input field
this.newDescription = ‘’ //clear description
},
async loadTodos () {
const response = await ToDoAPI.getToDos()
this.todos = response.data
},
deleteTodo(todoID){
ToDoAPI.deleteTodo(todoID)
//remove the array element with matching id
this.todos = this.todos.filter(function(obj){
return obj._id !== todoID
})
},
//add an update function to update each todo
async updateTodo(todoID){
await ToDoAPI.updateTodo(todoID, this.newTodo, this.newDescription)
this.loadTodos()
this.newTodo = ‘’ // clear the input field
this.newDescription = ‘’ //clear description
}
}
}
</script>

<style lang=”css”>

textarea {
resize: none;
}

li{
border: 1px;
border-style: solid;
border-color: black;
margin-top: 10px;
}

</style>

//express setup

//the routes
//get the todos to display (READ)
app.get(“/todo”, (req, res) => {
const collection = client.db(‘todoapp’).collection(“todos”); //connecting to the atlas collection

collection.find().toArray(function (err, results){ //filtering the results
if(err){
console.log(err)
res.send([])
return
}

res.send(results)
})
})
//add a todo (CREATE)
app.post(‘/addTodo’, (req, res) => {
const collection = client.db(‘todoapp’).collection(‘todos’)
let todo = req.body.todo //parse the data from the request body
let description = req.body.description
let state = req.body.state
collection.insert({title: todo , description: description , state: state}, function(err, results) {
if (err){
console.log(err);
res.send(‘’);
return
}
res.send(results.ops[0]) //retruns the new document
})
})

//delete a todo (DELETE)
app.post(‘/deleteTodo’, (req, res) => {
const collection = client.db(‘todoapp’).collection(‘todos’);
// remove the document by the unique id
collection.removeOne({‘_id’: mongo.ObjectID(req.body.todoID)}, function(err, results){
if(err) {
console.log(err)
res.send(‘’)
return
}
res.send()
})
})

// add an update functio to update the existing mongodb data by its unique id
//update a todo (UPDATE)
app.post(‘/updateTodo’, (req, res) => {
const collection = client.db(‘todoapp’).collection(‘todos’);
let todo = req.body.todo;
let description = req.body.description;
console.log(description + “ is not a null value”)
collection.update({‘_id’: mongo.ObjectID(req.body.todoID)}, {$set: {title: todo , description: description}, function(err, results){
if(err) {
console.log(err)
res.send(‘’)
return
}
res.send()
})
})

//axios setup
import API from ‘@/services/API’

export default {
getToDos () {
return API().get(‘todo’) // connecting to the api
},
addTodo (todo, description, state) {
return API().post(‘addTodo’, {
todo: todo, // add our data to the response body
description: description,
state: state
})
},
deleteTodo (todoID) {
return API().post(‘deleteTodo’, {
todoID: todoID // add data to the request body
})
},
updateTodo (todoID, todo, description) {
return API().post(‘updateTodo’, {
todoID: todoID,
todo: todo,
description: description
})
}
}

Solution :

Basically, if you are setting only the title then you should not update the description. As it will be undefined and will overwrite the previous value.

Change the query to this:-

// add an update function to update the existing mongodb data by its unique id
//update a todo (UPDATE)
app.post(‘/updateTodo’, (req, res) => {
const collection = client.db(‘todoapp’).collection(‘todos’);
const updateOperation = {};

if(req.body.todo) updateOperation.title = req.body.todo;
if(req.body.description) updateOperation.description = req.body.description;

console.log(description + “ is not a null value”)
collection.update({‘_id’: mongo.ObjectID(req.body.todoID)}, {$set: {…updateOperation}, function(err, results){
if(err) {
console.log(err)
res.send(‘’)
return
}
res.send()
})
})

[Vue.js] Retrieve Prismic slices content in Nuxtjs using GraphQL not working in project

When testing the query in the browser I can easily query slices but once in my project, when I try to query Prismic slices it all falls apart.
Packages: apollo-client, apollo-cache-inmemory, apollo-link-prismic

the query looks something like:

{
thepage(uid: “page”, lang: “en-gb”) {
page_title
page_description
body {
… on ThePageBodyHero {
type
fields {
title
description
button_text
button_link {
_linkType
}
}
}
}
}
}

this works in the interface but as soon as I add the slices section in the project the query returns a 404.

Solution :

When using Apollo Client with Slices, you need to have a proper cache setup to resolve the slices. Meaning having a fragment matcher setup based on the introspection query to Prismic: https://www.apollographql.com/docs/react/advanced/fragments#fragment-matcher.
We planned to do it in the Prismic library for Apollo so people won’t have to care about it no more.
In the case you got a 404 but it would be interesting to see who return a 404 because all the symptoms seem to lead to what I just explained.
Tell me if you got more info on the side ;)

In the meantime, here is a proper implementation: https://github.com/birkir/gatsby-source-prismic-graphql/blob/master/packages/gatsby-source-prismic-graphql/src/utils/getApolloClient.ts#L17

[Vue.js] Add SCSS support to Vue project

In my packages.json file by default I get:

“postcss”: {
“plugins”: {
“autoprefixer”: {}
}

When I add <style lang=’scss’> It doesn’t compile like magic like it does for Typescript support. I know I will need to specify some NPM package as devDependencies and specify something above in the postcss section to get scss to compile, but I can’t find any documentation outside of webpack so when lost.

Solution :

See https://vue-loader.vuejs.org/guide/pre-processors.html.

For example, to compile our <style> tag with SASS/SCSS:

npm install -D sass-loader node-sass

In the webpack config:

module.exports = {
module: {
rules: [
// … other rules omitted

// this will apply to both plain `.scss` files
// AND `<style lang=”scss”>` blocks in `.vue` files
{
test: /\.scss$/,
use: [
‘vue-style-loader’,
‘css-loader’,
‘sass-loader’
]
}
]
},
// plugin omitted
}

Now in addition to being able to import ‘style.scss’, we can use SCSS
in vue.js components as well:

<style lang=”scss”> /* write SCSS here */ </style>

Any content inside the block will be processed by webpack as if it’s
inside a *.scss file.

[Vue.js] Import a SCSS exported variable into the Javascript code within a .vue file that is loaded by vue-loader and bundled by webpack

there is a variable in my vars.scss that to access from Javascript in root/app/app.vue.

root/app/scss/vars.scss

:export {
cursor: #fff;
}

root/app/app.vue

<template>
<div id=”yes”>
</div>
</template>

<script lang=”ts”>
import vue.js from ‘vue’;
import colors from ‘@/scss/vars.scss’;

export default Vue.extend({
mounted() {
console.log(colors.cursor);
},
});
</script>

<style >
</style>

there is read approximately 30 different stackoverflow questions that appear to be dealing with the similar problem of importing variables into the style block of the .vue.js file, as well as the identical problem of importing the variables directly into the Javascript code. As a result, my webpack.config.js looks like the following:

root/webpack.config.js

const path = require(‘path’);
const HtmlWebpackPlugin = require(‘html-webpack-plugin’);
const CleanWebpackPlugin = require(‘clean-webpack-plugin’);
const webpack = require(‘webpack’);
const VueLoaderPlugin = require(‘vue-loader/lib/plugin’);
const env = process.env.NODE_ENV

module.exports = {
entry: ‘./app/index.ts’,
output: {
filename: ‘main.js’,
path: path.resolve(__dirname, ‘staticfiles’)
},
resolve: {
extensions: [ ‘.ts’, ‘.js’, ‘.vue’, ‘.scss’, ‘.sass’],
alias: {
‘vue$’: ‘vue/dist/vue.esm.js’,
‘@’: path.resolve(__dirname, ‘/app/‘)
}
},
plugins: [
new HtmlWebpackPlugin(),
new CleanWebpackPlugin(),
new webpack.HotModuleReplacementPlugin(),
new VueLoaderPlugin()
],
module: {
rules: [
{
enforce: ‘pre’,
test: /\.(js|vue|ts)$/,
loader: ‘eslint-loader’,
exclude: /node_modules/
},
{
test: /\.vue$/,
loader: ‘vue-loader’,
options: {
loaders: {
// Since sass-loader (weirdly) has SCSS as its default parse mode, we map
// the “scss” and “sass” values for the lang attribute to the right configs here.
// other preprocessors should work out of the box, no loader config like this necessary.
‘scss’: ‘vue-style-loader!css-loader!sass-loader’,
‘sass’: ‘vue-style-loader!css-loader!sass-loader?indentedSyntax’,
}
// other vue-loader options go here
}
},
{
test: /\.css$/,
use: [
‘vue-style-loader’,
‘css-loader’
]
},
{
test: /\.tsx?$/,
loader: ‘ts-loader’,
exclude: /node_modules/,
options: {
appendTsSuffixTo: [/\.vue$/],
}
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: ‘file-loader’,
options: {
name: ‘[name].[ext]?[hash]‘
}
},
{
test: /\.s(a|c)ss$/,
use: [ {
loader: “style-loader”,
options: {
sourceMap: env === ‘development’,
}
}, {
loader: “css-loader”,
options: {
sourceMap: env === ‘development’,
}
}, {
loader: “sass-loader”,
options: {
sourceMap: env === ‘development’,
}
},
‘vue-style-loader’],
}]
}
};

there is also tried, in the test: /\.s(a|c)ss$/ section, to put vue-style-loader at the beginning of the array.

there is tried many combinations of filenames when attempting to import the .scss file, such as relative (../scss/vars.scss), removing the extension, using .css as an extension, etc.

The error I get is:

ERROR in /home/Documents/application/app/app.vue.ts
[tsl] ERROR in /home/Documents/application/app/app.vue.ts(10,28)
TS2307: Cannot find module ‘@/scss/vars.scss’.

My question:

In a project that uses vue-style-loader and vue-loader to build .vue.js files with webpack, how can I import .scss variables into the <script> portion of a .vue.js file? (please note - when NOT attempting to import them into the <style> section of the .vue.js file)

Solution :

An example based on my comment:

SCSS fragment:

$foo: #333;

body {
--variable-foo: $foo;
}

And then anywhere in the JavaScript

const value = document.body.style.getPropertyValue(“–variable-foo”);
console.log(value); // outputs “#333”

[Vue.js] What is the practice for handling Vuex action outcomes

I’m creating a login system using vue.js and Vuex following this guide

https://scotch.io/tutorials/handling-authentication-in-vue-using-vuex#toc-setup-components

This have the login action return a promise, which I was told does not follow the Flux Pattern which Vuex is based on.

So I’ve changed it up a bit and done the following:

// This is the action from my “auth store”
login: ({commit}, userData) => {
commit(‘auth_request’)
Api.post(‘login’, userData)
.then(res => {
const token = res.data.data.token
localStorage.setItem(‘token’, token)
Api.defaults.headers.common[‘Authorization’] = “Bearer “ + token
commit(‘auth_success’, token)
})
.catch(err => {
commit(‘auth_error’)
console.log(“Failed to login, check the username or password”)
})
}

This is all fine and dandy, but when I press my login button in my application I see all the commits come through, auth_request, auth_success and the store gets filled with user data from that auth_success.

But since I now does not return a promise, how can I now ask the router to change the view? there is no “feedback” on when the system is done loading? What is the best practice for acknowledging a successful or failed login?

Solution :

The idea that it’s an anti-pattern to return from a Promise is something that was a React driven ideology to push the idea of Flux. The piece of the puzzle that you would be missing is the dispatcher to listen to when an action finally calls it.

You would listen to it like an event listener, something like`:

this.$flux.on(‘login’, (data) => {
//login was called here
})

And you would dispatch it something like:

this.$flux.emit(‘login’, data)

The idea is that you’re not wholly reliant on a single piece of architecture which may in fact have side-effects, or, alternatively, may actually represent changes all over the system.

The down side to this is that you’re adding another layer of data management to the application. You can completely forego this in smaller app’s and just use async/await with try/cache and return a Promise.resolve/reject. However, maybe you want to learn the Flux pattern. It’s super simple in Vue.

Make a new File called bus.js. Inside of this file, we’ll actually just create a new vue.js instance and export it:

import vue.js from ‘vue’

const Bus = new Vue({})

export default Bus

Now we can go ahead and import that, say in our login page:

import Bus from ‘bus’

And in our mounted function, we can add a listener:

Bus.$on(‘login.success’, this.loginHappened)

And in our methods in that Login component, we can define loginHappened.

loginHappened (data) {
console.log(data)
}

Now we just dispatch it from our Action:

// store

import Bus from ‘bus’

login: async ({ commit }, userData) => {
try {
const res = await Api.post(‘login’, userData)

const token = res.data.data.token
localStorage.setItem(‘token’, token)
Api.defaults.headers.common[‘Authorization’] = “Bearer “ + token
commit(‘auth_success’, token)

Bus.$emit(‘login.sucesss’, res.data.data)
} catch (err) {
Bus.$emit(‘login.failure’, err.response.data)
}
}

Oh, you’ll also want to watch that failure:

Bus.$on(‘login.failure’, this.loginFailed)

And now in that same Login component, or anywhere really, you can define that method:

loginFailed (error) {
console.log(error) // the server side data from axios.
}

Now we have a system where actions are completely asynchronous and decoupled, and we rely on event dispatching and listeners in order to react to asynchronous actions.

Of course all of this is completely overkill for a 3 page SPA.

[Vue.js] What is the best practice for reactive setter for an object in array in Vuex?

there is a vuex object with array of languages that has objects with guid, name and level.

How can I write method so that it will make it reactive. I got to the point where there is input field with value=”language.name” and to write method for @input but I don’t know what best practice for it.

there is Vuex store:

const state = () => ({

obj: {
skills: [],
languages: []
},

})

An example the use in template in v-for=”(language, index) in obj.languages”:

v-text-field(
:value=”language.name”
@input=”setLanguage”
)

And code after reading in depth about getters, setters, modern Javascript limitations for vue.js so it can’t track changes of an array in state therefore it is required to use workaround as Vue.set() built-in method and use of TodoMVC example on vuex github that I came up with:

setLanguage: (e) => {
function f({language, guid = language.guid, name = language.name, level = language.level}){
Vue.set(this.$store.state.obj.languages, this.$store.state.obj.languages.findIndex((it) => it.guid === guid), {guid, name, level})
}
const name = e.target.value.trim()
const language = this
f({language, name})
}

It doesn’t seems to be right. And I feel I don’t understand the concept.

Can you show what is the best practice to make reactive objects of an array in state of vuex?

Solution :

With vuex, you want to be using actions and mutations.

setLanguage: (e, index) => {
let name = e.target.value.trim()
this.$store.dispatch(‘setLanguage’, {name, index}) //dispatches a vuex action
}

Then define an action:

setLanguage({ commit }, payload) {
commit(‘setLanguage’, payload) //commits a vuex mutation
}

And finally a mutation:

setLanguage(state, payload) {
state.languages[payload.index].name = payload.name
}

see the vuex documentation on this: https://vuex.vuejs.org/guide/actions.html

[Vue.js] changing the background color of a v-list header

when tying to change the color of a v-list header item. I seem to only be able to change the colour of the title but not the whole tile. Note that I need this to be reactive since the background color when trying to change will not remain the same over time.

there is tried using the color property on the v-list-tile-content but it does not do anything. Then I tried the same on the v-list-tile-title but this only changes the title part not the action/avatar part

In other words it’s like changing the colour of the Dining title in the following codepen https://codepen.io/patrick2009/pen/pmdgNz

<v-list-tile-content color=”red”>
<v-list-tile-title>{ subItem.title }</v-list-tile-title>
</v-list-tile-content>

Something like that would be nice!

Thanks guys,

Pat

Solution :

EDIT: there is updated my answer to show how you can add css dynamically, using props.

Example:

const myList = {
template: “#my-list”,
props: [“color”, “hover”],
mounted() {
var css = `
.v-list__group__header {
background-color: ${this.color};
}
.v-list__group__header:hover {
background-color: ${this.hover} !important;
}
`;
var style = document.createElement(“style”);
if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
document.getElementsByTagName(“body”)[0].appendChild(style);
},
data() {
return {
items: [{
action: “local_activity”,
title: “Attractions”,
items: [{
title: “List Item”
}]
},
{
action: “restaurant”,
title: “Dining”,
active: true,
items: [{
title: “Breakfast & brunch”
},
{
title: “New American”
},
{
title: “Sushi”
}
]
},
{
action: “school”,
title: “Education”,
items: [{
title: “List Item”
}]
},
{
action: “directions_run”,
title: “Family”,
items: [{
title: “List Item”
}]
},
{
action: “healing”,
title: “Health”,
items: [{
title: “List Item”
}]
},
{
action: “content_cut”,
title: “Office”,
items: [{
title: “List Item”
}]
},
{
action: “local_offer”,
title: “Promotions”,
items: [{
title: “List Item”
}]
}
]
};
}
};

new Vue({
el: “#app”,
components: {
myList
}
});
<script src=”https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<script src=”https://cdnjs.cloudflare.com/ajax/libs/vuetify/1.5.14/vuetify.min.js"></script>
<link href=”https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel=”stylesheet” />
<link href=”https://cdn.jsdelivr.net/npm/vuetify@1.5.14/dist/vuetify.min.css" rel=”stylesheet” />

<div id=”app”>
<v-app id=”inspire”>
<v-layout row>
<v-flex xs12 sm6 offset-sm3>
<my-list color=”red” hover=”blue”></my-list>
</v-flex>
</v-layout>
</v-app>
</div>

<script type=”text/x-template” id=”my-list”>
<v-card>
<v-toolbar color=”teal” dark>
<v-toolbar-side-icon></v-toolbar-side-icon>
<v-toolbar-title>Topics</v-toolbar-title>
<v-spacer></v-spacer>
<v-btn icon>
<v-icon>more_vert</v-icon>
</v-btn>
</v-toolbar>
<v-list>
<v-list-group v-for=”item in items” :key=”item.title” v-model=”item.active” :prepend-icon=”item.action” no-action>
<template v-slot:activator>
<v-list-tile>
<v-list-tile-content>
<v-list-tile-title>{ item.title }</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
</template>
<v-list-tile v-for=”subItem in item.items” :key=”subItem.title” @click=””>
<v-list-tile-content color=”red”>
<v-list-tile-title>{ subItem.title }</v-list-tile-title>
</v-list-tile-content>
<v-list-tile-action>
<v-icon>{ subItem.action }</v-icon>
</v-list-tile-action>
</v-list-tile>
</v-list-group>
</v-list>
</v-card>
</script>

[CodePen Mirror]

Old Answer:

Looks like you have to set this via css for that class.. The class you’ll have to target is v-list__group__header.

EDIT: You can also use a :hover “event” to change the background-color on hover - unfortunately, this requires you to use the !important modifier, which is typically frowned upon. Figured I would mention it regardless.

.v-list__group__header:hover {
background-color: blue !important;
}

[Vue.js] Input fields not working in Vue with v-model

there is the following template syntax in a vue.js single-file component:

<template>

<input v-model=”newInput”>

</template>

In the same component, there is this data:

<script>

data: () => {
return {
newInput: “”,
}
}

</script>

Problem: In Chrome, this input field will not accept any text or numbers. The cursor is blinking in the field, but no text is entering. I opened dev tools, and there is no data change when I type. I checked my keyboard settings, nothing weird there.

Appreciate any guidance on this!

Solution :

In my case this work perfectly,

Here in template tag I’ve modified input and in the script tag I’ve modified ‘data()’ method which accept any text or number.

Try this:

<template>

<input type=”text” v-model=”newInput”>

</template>

<script>

export default {
data () {
return {
newInput: ‘’
}
}
}
</script>

[Vue.js] Why is the Vue.js input value not updating?

there is a Vue.js text-input component like the following:

<template>
<input
type=”text”
:id=”name”
:name=”name”
v-model=”inputValue”
\>
</template>

<script>
export default {
props: [‘name’, ‘value’],
data: function () {
return {
inputValue: this.value
};
},
watch: {
inputValue: function () {
eventBus.$emit(‘inputChanged’, {
type: ‘text’,
name: this.name,
value: this.inputValue
});
}
}
};
</script>

And when using that text-input in another component as follows:

<ul>
<li v-for=”row in rows” :key=”row.id”>
<text-input :name=”row.name” :value=”row.value”>
</text-input>
</li>
</ul>

Then, within the JS of the component using text-input, there is code like the following for removing li rows:

this.rows = this.rows.filter((row, i) => i !== idx);

The filter method is properly removing the row that has an index of idx from the rows array, and in the parent component, I can confirm that the row is indeed gone, however, if I have, for example, two rows, the first with a value of 1 and the second with a value of 2, and then I delete the first row, even though the remaining row has a value of 2, when still seeing 1 in the text input.

Why? I don’t understand why Vue.js is not updating the value of the text input, even though the value of value is clearly changing from 1 to 2, and I can confirm that in the parent component.

Maybe I’m just not understanding how Vue.js and v-model work, but it seems like the value of the text input should update. Any advice/explanation would be greatly appreciated. Thank you.

Solution :

From the code you are trying to listen to changes.. in v-model data..
// the vue.js components

<template>
<input
type=”text”
:id=”name”
:name=”name”
v-model=”inputValue”
\>
</template>

<script>
export default {
props: [‘name’, ‘value’],
data: function () {
return {
inputValue: “”
};
},

};
</script>

If You really want to listen for changes..

<ul>
<li v-for=”row in rows” :key=”row.id”>
<text-input @keyup=”_keyUp” :name=”row.name” :value=”row.value”>
</text-input>
</li>
</ul>

in the component file

<template>…</template>
<script>
export default {
props: [‘name’, ‘value’],
data: function () {
return {
inputValue: “”
};
},
methods : {
_keyUp : () => {// handle events here}

};
</script>

check here for events on input here

To bind value from props..

get the props value, then assign it to ‘inputValue’ variable

it will reflect in tthe input element

Solution 2:

You cannot mutate values between components like that.

Here is a sample snippet on how to properly pass values back and forth. You will need to use computed setter/getter. Added a button to change the value and reflect it back to the instance. It works for both directions.

<template>
<div>
<input type=”text” :id=”name” v-model=”inputValue” />
<button @click=”inputValue=’value2’”>click</button>
</div>
</template>
<script>
export default {
props: [‘name’, ‘value’],
computed: {
inputValue: {
get() {
return this.value;
},
set(val) {
this.$emit(‘updated’, val);
}
}
}
}
</script>

Notice that the “@updated” event updates back the local variable with the updated value:

<text-input :name=”row.name” :value=”row.value” @updated=”item=>row.value=item”></text-input>