I have issue to get some values from methods and want to parse to provide.
How I can solve the problem?
methods: {
onClickCategory: (value) => {
return (this.catId = value);
},
},
provide() {
return {
categoryId: this.value,
};
},
I get always categoryId:undefined
I found solution:
methods: {
onClickCategory(value) {
this.categoryId.value = value;
},
},
provide() {
this.catID = this.categoryId;
return {
catId: this.catID,
};
},
As Vue Guide highlights,
Note: the provide and inject bindings are NOT reactive. This is
intentional. However, if you pass down an observed object, properties
on that object do remain reactive.
So one solution is wrap your value into one observed object, like test2.value in below example:
Vue.config.productionTip = false
Vue.component('v-parent', {template: `
<div>
<h4>Example</h4>
<p>Not Working: <input v-model="test1"></p>
<p>Working: <input v-model="test2.value"></p>
<v-child></v-child>
</div>
`,
data () {
return {
test1: 'blabla1',
test2: {value: 'blabla2'}
}
},
provide () {
return {parent1: this.test1, parent2: this.test2}
}
}),
Vue.component('v-child', {
template: `<div><pre>{{parent1}}</pre><pre>{{parent2.value}}</pre></div>`,
inject: ['parent1', 'parent2']
})
new Vue({
el: '#app',
data() {
return {
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
<div>
<v-parent/>
</div>
</div>
Related
i want the function:createComparation work when tableRowName change,but acturely when tableRowName change , it didnt works,vue follows;
createComparation is another function which didnt define by vue but only by javascript
const selectedRight =Vue.createApp({
data(){
return {
tableRow:0,
tableRowName:[],
stockName:[],
rectWidth:40,
rectHeight:5,
}
},
watch: {
tableRowName(newtable,oldtable){
console.log(1)
createComparation()
},
immediate:true,
stockName(){
changeTip()
},
},
methods:{
}
}).mount('#selectedRight')
in case of tableRowName contain objects then you have to use
deep:true
watch: {
tableRowName(newtable,oldtable){
console.log(1)
createComparation()
},
immediate:true,
deep: true,
stockName(){
changeTip()
},
},
but i think you are updating the array without reactive manner, Vue cannot detect the following changes to an array:
When you directly set an item with the index, e.g.
vm.items[indexOfItem] = newValue
When you modify the length of the array, e.g.
vm.items.length = newLength
var vm = new Vue({
data: {
items: ['a', 'b', 'c']
}
})
vm.items[1] = 'x' // is NOT reactive
vm.items.length = 2 // is NOT reactive
I guess whatching array might be the issue. You can try this:
computed: {
rowNames() {
return this.tableRowName;
// if the line above doesn't work:
return this.tableRowName.join();
}
},
watch: {
rowNames(newtable,oldtable){
createComparation()
},
I think this is what you're looking for. You need to define the handler as an object for the property you're trying to watch and set immediate: true.
Vue.config.productionTip = false
Vue.config.devtools = false
new Vue({
el: "#app",
data() {
return {
tableRow: 0,
tableRowName: [],
stockName: [],
rectWidth: 40,
rectHeight: 5,
}
},
watch: {
tableRowName: {
handler(newtable) {
console.log('Calling createComparation function');
console.info(newtable);
},
immediate: true
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<button #click="tableRowName.push(Math.random())">Trigger change manually again</button>
</div>
The watch method definition is wrong. When you need to use immediate, you have to put you function body into handler property.
For example,
watch: {
tableRowName: {
handler: function() {
},
immediate: true
}
},
I'm having an undefined value when I put my object data inside the event.
Here are my codes:
data(){
return {
eventSources: [],
myId: 1
}
},
methods:{
myMethod(){
this.eventSources = [{
events(start,end,timezone,callback){
alert(this.myId);
axios.get(`/Something?id=${this.myId}`).then(response=>{
callback(response.data);
}).catch(error=>{console.log(error);});
}
}]
}
}
My alert is resulted to undefined but when I put my alert above the this.eventSources = [{...]] the alert has a value of 1
I hope somebody helps me.
The problem is this inside events() is not actually your Vue instance. You can fix the context by declaring events as an arrow-function:
this.eventSources = [{
events: (start,end,timezone,callback) => {
alert(this.myId);
}
}]
new Vue({
el: '#app',
data() {
return {
eventSources: [],
myId: 1
};
},
methods: {
myMethod() {
this.eventSources = [{
events: (start,end,timezone,callback) => {
alert(this.myId);
}
}]
this.eventSources[0].events(0, 1, 'UTC', data => console.log(data))
}
}
})
<script src="https://unpkg.com/vue#2.5.16"></script>
<div id="app">
<button #click="myMethod">Click</button>
</div>
So I'm fairly new to Vue and I'm trying to make a customer list search work with Fuse.js.
I do get the array of customers back and it's being assigned to customer_search. my keys are populated properly and the only issue is that results doesn't return anything. I'm wondering if I need to structure my customer array differently or am I missing something else altogether?
Any help would be appreciated.
Here is my code:
<template>
<div>
<div class="container">
<h1>Search</h1>
<input type="text" class="input-search" value="" v-model="query">
<p v-html="results"></p>
<p v-for="info in data" >{{info}}</p>
</div>
</div>
</template>
<script>
import Fuse from 'fuse.js'
import $ from 'jquery'
import PageService from '../../common/services/PageService'
const Search = {
data(){
return {
data: {},
fuse: {},
results: {},
query: '',
options: {
keys: [
'id',
'name',
'company',
],
minMatchCharLength: 3,
shouldSort: true,
threshold: 0.5
},
}
},
methods:{
runQuery(query){
if(query.length >= 3)
this.results = this.fuse.search(query)
},
},
computed:{
customers: function(){
return this.data
},
customer_search: function(){
return Object.values(this.data)
},
},
watch: {
query: function(){
this.runQuery(this.query)
}
},
created(){
this.fuse = new Fuse(this.customer_search, this.options)
if(this.$store.state.search != ''){
this.query = this.$store.state.search
}
PageService.getSearchObject().then((response)=>{
this.data = response.data
}).catch((err)=>{
console.log('Error')
});
},
}
export default Search
</script>
I think your runQuery method is created before your this.fuse get created so the this.fuse inside your runQuery method is not up-to-date.
Maybe try:
methods:{
runQuery(query){
if(query.length >= 3)
this.results = new Fuse(this.customer_search, this.options).search(query)
},
},
When reading Vue document
Non parent-child communication
For practice, I tried to build an example to see if it works, below is my code:
I build two component and tried to use Vue instance bus to transport message from dudi-station to dudo-station while on-click, but it's not working.
Can anyone help? Thanks!
Vue.component('dudi-station', {
template: '<div #click="sentMsg">{{dudiMsg}}</div>',
data: function() {
return {
dudiMsg: 'Dudi!!',
}
},
methods: {
sentMsg: function() {
bus.$emit('callout', this.dudiMsg);
},
}
});
Vue.component('dudo-station', {
template: '<div>{{dudoMsg}}</div>',
data: function() {
return {
dudoMsg:'',
}
},
created: function() {
bus.$on('callout', function(value) {
this.dudoMsg = value;
console.log(value);
});
}
});
var bus = new Vue();
new Vue({
el: '#app',
})
<script src="https://unpkg.com/vue"></script>
<div id="app">
<dudi-station></dudi-station>
<dudo-station></dudo-station>
</div>
Use arrow function as event handler when receiving message in component from another component. It will help you with "this" keyword scope.
bus.$on('callout', function(value) {
this.dudoMsg = value;
console.log(value);
});
instead of this use it as below
bus.$on('callout', (value) => {
this.dudoMsg = value;
console.log(value);
});
Because in this statement:
bus.$on('callout', function(value) {
this.dudoMsg = value;
this this is not mean your vue instance.
You need to use arrow function to make sure that 'this' means the vue instance.
Like below:
Vue.component('dudi-station', {
template: '<div #click="sentMsg">{{dudiMsg}}</div>',
data: function() {
return {
dudiMsg: 'Dudi!!',
}
},
methods: {
sentMsg: function() {
bus.$emit('callout', this.dudiMsg);
},
}
});
Vue.component('dudo-station', {
template: '<div>{{dudoMsg}}</div>',
data: function() {
return {
dudoMsg:'',
}
},
created: function() {
bus.$on('callout',value => {
this.dudoMsg = value;
console.log(value);
});
}
});
var bus = new Vue();
new Vue({
el: '#app',
})
<script src="https://unpkg.com/vue"></script>
<div id="app">
<dudi-station></dudi-station>
<dudo-station></dudo-station>
</div>
I have an array:
basicForm.schema = [
{},
{} // I want to watch only this
]
I tried doing this:
‘basicForm.schema[1].value’: {
handler (schema) {
const plan = schema.find(field => {
return field.name === ‘plan’
})
},
deep: true
},
But I got this error:
vue.js?3de6:573 [Vue warn]: Failed watching path:
“basicForm.schema[1]” Watcher only accepts simple dot-delimited paths.
For full control, use a function instead.
What's the correct way of doing this?
You can watch a computed property instead:
new Vue({
el: '#app',
data: {
basicForm: {
schema: [
{a: 1},{b: 2} // I want to watch only this
]
}
},
computed: {
bToWatch: function() {
return this.basicForm.schema[1].b
}
},
methods: {
incB: function() {
this.basicForm.schema[1].b++
}
},
watch: {
bToWatch: function(newVal, oldVal) {
console.log(newVal)
}
}
});
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
<button #click="incB()">Inc</button>
</div>
You should use a function as the warning message suggests. You need to do so via vm.$watch.
new Vue({
el: '#app',
data: {
items: [
{ name: 'bob' },
{ name: 'fred' },
{ name: 'sue' },
],
},
created() {
this.$watch(() => this.items[1].name, this.onNameChanged);
},
methods: {
changeValue() {
this.items[1].name = 'rose';
},
onNameChanged(name) {
alert('name changed to ' + name);
},
},
});
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
<button #click="changeValue">Click me</button>
</div>
You should probably check that this.items[1] exists before accessing it inside the watch function otherwise you'll get an error.