vue.js Failed to mount component: template - laravel

i am working hard to solve this issue but not found any one please help me about this
here is my code
calling component
Vue.component('select2', require('./components/select2.vue'));
html of component
<template>
<select>
<slot></slot>
</select>
</template>
here is my vue.js script
<script>
export default {
props: ['options', 'value', 'params'],
mounted: function () {
var vm = this;
var params = !this.params ? {} : this.params;
params.val = this.value;
if(this.options) {
params.data = this.options;
}
$(this.$el).val(this.value);
$(this.$el).select2(params);
$(this.$el).on('change', function () {
vm.$emit('input', $(this).val())
})
$(this.$el).val(this.value).trigger('change');
},
watch: {
value: function (value) {
$(this.$el).val(value);
},
options: function (options) {
var params = !this.params ? {} : this.params;
if(this.options) {
params.data = this.options;
}
$(this.$el).select2(params);
}
},
destroyed: function () {
$(this.$el).off().select2('destroy')
}
}
</script>
but still getting this error i tried alot of things but not working please help me i can give you more detials if you needed i am using laravel ,gulp etc

Related

Error in mounted hook: "ReferenceError: posts is not defined in Vuejs

I'm newbie in Vuejs. I am try to learning to code vuejs for couple of hours until I get this error.I guess the problem is come from props to to Blade. Here is my code.
// Blade View
<div id="app">
<div :posts="{{ $posts }}"></div>
</div>
// Vue Template
<table striped hover :items="imageList">
<template slot="image" slot-scope="data">
<img :src="'storage/images' + data.item.image" alt="">
</template>
</table>
// Vue JS
<script>
export default {
props:['posts'],
data: function() {
return {
imageList: []
};
},
mounted() {
this.fetch_image_list();
},
methods: {
fetch_image_list() {
let items = [];
if (Array.isArray(posts.data) && posts.data.length) {
posts.data.forEach((image,key) => {
let currentImage = {
'id':post.id,
'name':post.name,
'image':post.img,
}
items.push(currentImage)
});
this.imageList = items;
}
}
}
}
</script>
You should use this when accessing your data (if you don't have another scope defined inside). And you're trying to access the properties of undefined object (post) in forEach loop.
methods: {
fetch_image_list() {
let items = [];
if (Array.isArray(this.posts.data) && this.posts.data.length) {
this.posts.data.forEach((post, key) => {
let currentImage = {
'id':post.id,
'name':post.name,
'image':post.img,
}
items.push(currentImage)
});
this.imageList = items
}
}
}

Vue: Push to array on event

I have two separate Vue components that need to talk to each other via an eventbus. Like:
form-component.Vue
import events from './events'
export default {
...
methods() {
sumbitForm() {
events.$emit('form-submitted', data)
}
}
...
}
other-component.Vue
import events from './events'
export default {
....
mounted() {
events.$on('form-submitted, data => {
this.list.push(data);
}
},
data() {
return {
list: []
}
}
....
}
But when the event is listened to 'this' is not referring to 'other-component' but to the actual eventbus 'events'.
How would I go about this problem?
It sounds to me like you're misreading the problem. An arrow function binds its context, and the context of that arrow function is correctly bound to the other-component because it is within a method, and methods are auto-bound to their components. The below example works as expected.
const events = new Vue();
Vue.component('formComponent', {
template: '<button #click="submitForm">Submit</button>',
methods: {
submitForm() {
events.$emit('form-submitted', {
foo: 1
});
}
}
});
Vue.component('otherComponent', {
template: '<div><div v-for="item in list">{{item}}</div></div>',
data() {
return {
list: []
}
},
mounted() {
events.$on('form-submitted', data => {
this.list.push(data);
});
}
});
new Vue({
el: '#app'
});
<script src="//unpkg.com/vue#latest/dist/vue.js"></script>
<div id="app">
<form-component></form-component>
<other-component></other-component>
</div>
One solution would be to copy your this in a variable outside and use that to access the component's data properties. For example, this should work:
import events from './events'
export default {
....
mounted() {
var that = this;
events.$on('form-submitted, function(data) {
that.list.push(data);
)
},
data() {
return {
list: []
}
}
....
}

Avoid adding reactive properties to a Vue instance or its root $data at runtime - declare it upfront in the data option.

I am a bit confused using VueJS2. I added a few variables to the data container for sending it to my API. That works fine but Vue is throwing me a warning/error message which I don't know how to solve:
Avoid adding reactive properties to a Vue instance or its root $data
at runtime - declare it upfront in the data option.
var app = new Vue({
el: '#app',
data: {
incidentReference: '',
streetName: '',
latitude: '',
longitude: '',
featureTypeId: 1,
archived: 0
},
computed: {
href() {
return '#' + this.name.toLowerCase().replace(/ /g, '-');
}
},
mounted: function () {
this.getIncidents();
},
methods: {
onSubmit() {
axios.post('/api/v1/incidents', this.$data)
.then(response => alert('Success'))
.catch(error => {
console.log(error.response);
})
},
getIncidents: function() {
console.log('getIncidents');
var self = this;
axios.get('/api/v1/incidents').then(function(response) {
// set data on vm
console.log(response.data);
var incidentsReceived = response.data.data.map(function (incident) {
return incident;
});
Vue.set(self, 'incidents', incidentsReceived);
});
}
}
});
You're creating a new reactive property on the response of your API
Vue.set(self, 'incidents', incidentsReceived);
Not sure if you misspelled property's name or forget to create that property. Just use an existing property on you data section
Vue.set(self, 'incidentReference', incidentsReceived); //change property name
or
data: {
incidents: null, //or create this property
},
In my case during unit testing using Jest, I was setting selected but didn't have on component so got this error.
wrapper.setData({
selected: recipients,
});
So created the property on component and then it's working fine.
In the context of Jest & Vue Test Utils consider declaring data in component:
const Component = {
// ..
data() { return { abc: 'abc'; } }
};
const wrapper = mount(Component, { /*..*/ });
instead of
const Component = { /*..*/ };
const wrapper = mount(Component, { /*..*/ });
wrapper.setData({ abc: 'abc' });
await wrapper.vm.$nextTick();

can't set select defaut value

temlate
<bm-offer-confirm inline-template>
<select v-model="selectedCard">
<option v-for="card in cards"
v-bind:value="card.id">#{{card.info}}</option>
</select>
</bm-offer-confirm>
in the component
module.exports = {
data() {
return {
selectedCard: 0,
cards: {},
}
}
created(){
Bus.$on('setCardsList', function (cards) {
self.cards = cards;
this.selectedCard = cards[0].id;
//alert(this.selectedCard) shows 2
});
}
if i set selectedCard: 2 in data() it's work correctly and option is selected, but in my example it does not work. selected value is empty(not checked), why? I can select option only manualuty.
How you fill the cards object ? Are you getting any exception in console ?
No, it's result of emited in other component
created() {
this.getCards();
},
methods: {
getCards() {
this.$http.get('/get-cards/')
.then(response => {
this.cards = response.data;
Bus.$emit('setCardsList', this.cards);
})
},
//The Bus is Vue object;
//window.Bus = new Vue();
omg, I fixed it
created(){
var self = this; //add self link
Bus.$on('setCardsList', function (cards) {
self.cards = cards;
self.selectedCard = cards[0].id; // before this.selectedCard = cards[0].id;
//alert(this.selectedCard) shows 2
});
}

Marionette - throws error on `removeRegions` how to solve it

In my app, i have the regions as header,content,footer - in which on the login page, I don't want to use the header, and footer. for that, on onRender i remove the regions what i don't want to be.
But I am getting an error saying: Cannot read property 'empty' of undefined.
here is my template : (i use jade )
div#wrapper
script(type='text/template', id="appTemplate")
div#header
div#content
div#footer
script(type='text/template', id="loginTemplate")
div this is login template
here is my layout.js:
socialApp.AppLayout = Backbone.Marionette.LayoutView.extend({
el:'#wrapper',
template:'#appTemplate',
regions: {
header : '#header',
content : '#content',
footer : '#footer'
},
onRender : function () {
this.removeRegion("header", "#header"); //i am removing header alone here.
}
});
here is my controller.js
socialApp.loginController = Marionette.Controller.extend({
_initialize:function(){
this.loginView = new loginView({model:new loginModel});
this.layout.onRender(); //calling onRender from here...
this.layout.content.show(this.loginView);
}
});
But it's all not working. any one help me the correct way please?
You should never call methods that are prefixed with on manually. Those are there for your code to react to given events, in this case that the view’s render method was invoked.
I would suggest that you instead of trying to remove and then later re-add regions, you create two different layouts. Then when your router hits the login route, you render LoginLayout into your App’s root region, and for other routes, the ‘normal’ layout. Here’s how I solved something similar:
app.js:
var App = new Marionette.Application;
App.addRegions({ root: '#acme' });
// Instantiate User model
App.addInitializer(function()
{
this.user = new UserModel;
});
// Render App layout
App.addInitializer(function()
{
this.layout = this.user.get('id') ? new ContentLayoutView({ identifier: 'content' }) : new UserLayoutView({ identifier: 'user' });
this.root.show(this.layout);
// And let the routers decide what goes in the content region of each layout
this.router = {
content: new ContentRouter,
user: new UserRouter
};
});
layout/content.js
var ContentLayout = Marionette.LayoutView.extend(
{
identifier: 'content',
template: ContentLayoutTemplate,
regions: {
content: '[data-region="content"]',
panelLeft: '[data-region="panel-left"]',
panelRight: '[data-region="panel-right"]'
},
initialize: function()
{
this.content.once('show', function(view)
{
this.panelLeft.show(new PanelLeftView);
this.panelRight.show(new PanelRightView);
}.bind(this));
}
});
layout/user.js
var UserLayout = Marionette.LayoutView.extend(
{
identifier: 'user',
template: UserLayoutTemplate,
regions: {
content: '[data-region="content"]'
}
});
router/content.js
var ContentRouter = Marionette.AppRouter.extend(
{
routes: {
'(/)': '...'
},
createLayout: function(callback)
{
if(App.root.currentView.options.identifier != 'content')
{
var layout = new ContentLayoutView({ identifier: 'content' });
this.region = layout.content;
this.listenTo(layout, 'show', callback);
App.root.show(layout);
}
else
{
this.region = App.root.currentView.content;
callback();
}
},
execute: function(callback, args)
{
if(App.user.get('id'))
{
this.createLayout(function()
{
callback.apply(this, args);
}.bind(this));
}
else
App.router.user.navigate('login', true);
}
});
router/user.js
var UserRouter = Marionette.AppRouter.extend(
{
routes: {
'login(/)': 'showLogin',
'logout(/)': 'showLogout'
},
createLayout: function(callback)
{
if(App.root.currentView.options.identifier != 'user')
{
var layout = new UserLayoutView({ identifier: 'user' });
this.region = layout.content;
this.listenTo(layout, 'show', callback);
App.root.show(layout);
}
else
{
this.region = App.root.currentView.content;
callback();
}
},
execute: function(callback, args)
{
this.createLayout(function()
{
callback.apply(this, args);
}.bind(this));
},
showLogin: function()
{
var LoginView = require('view/detail/login');
this.region.show(new LoginView);
},
showLogout: function()
{
var LogoutView = require('view/detail/logout');
this.region.show(new LogoutView);
}
});

Resources