Vue.js – two different components on same route

Vue.js – two different components on same route

I’m trying to figure out how to have 2 different components on same route with Vue.
Main page or login page, depends if user is authenticated.
Maybe im missing something in documentation, but i cant and cant figure it out. Is it even possible?
Thx

Solutions/Answers:

Solution 1:

use auth param in router map:

router.map({
  '/home': {
    component: Home,
     auth: true
  },
  '/login': {
   component: Login
  },
  '/something': {
    component: Something,
    auth: true
  },
})

and then check before each transition:

router.beforeEach(function (transition) {
  if (transition.to.auth && !auth.user.authenticated) {
    transition.redirect('/login')
  } else {
    transition.next()
  }
})

Solution 2:

So you need dynamic components.

in whichever Vue is a parent to these components use a computed property that returns the name of component you want to use, based on the authenticated state:

//- in your js
//  insert into the vue instance definition, assuming you have an authencation 
//  property somewhere, eg session.isAuthenticated
... 
components: {
  MainComponent,
  LoginComponent
},
computed: {
  useComponent () {
    return session.isAuthenticated ? 'MainComponent' : 'LoginComponent'
  }
}
...

//- in your template html
<component :is='useComponent' />

http://vuejs.org/guide/components.html#Dynamic-Components

References

Use summernote with vuejs

Use summernote with vuejs

I try to create todo list with next features:

sortable items
WYSIWYG editor in each item
each changes in item’s editor store in todos model

I made 1 and 2 but can’t make 3. I can only change a title of the first task in tasks array
This is my code
app.js
Vue.directive(‘summernote’, {
bind: function() {
this.editor = $(this.el).summernote({
airMode: true,
disableDragAndDrop: true,
popover: {
air: [
[‘style’, [‘bold’, ‘italic’, ‘underline’, ‘clear’]]
]
},
callbacks: {
onChange: function(contents, $editable) {
vm.tasks[0].title = contents;
}
}
});
}
});

var vm = new Vue({
el: ‘#todos’,

ready: function (value) {
Sortable.create(this.$el.firstChild, {
draggable: ‘li’,
animation: 500,
onUpdate: function(e) {
var oldPosition = e.item.getAttribute(‘data-id’);
var newPosition = this.toArray().indexOf(oldPosition);
vm.tasks.splice(newPosition, 0, vm.tasks.splice(oldPosition, 1)[0]);
}
});
},

data: {
tasks: [
{ title: ‘First task’, done: true },
{ title: ‘Second task’, done: true },
{ title: ‘Third task’, done: false }
],
newTask: ”,
editTask: null
},

methods: {
addTask (e) {
e.preventDefault();
this.tasks.push({ title: this.newTask, done: false });
this.newTask = ”;
},

removeTask (index) {
this.tasks.splice(index, 1);
}
}
})

index.html


  • {{ task.title }}

    ×


{{tasks | json}}
{{editor}}

How can I edit and save in each item summernote’s content? This is working example

Solutions/Answers:

Solution 1:

I think the preferred approach would be to build a component (or use an existing one), which would have props, etc. However, it turns out that there is an internal property of this inside the directive that you can use: _scope. It is documented (well, mentioned at least) in the terminal directive example.

Your bind function becomes:

bind: function() {
  const scope = this._scope;
  this.editor = $(this.el).summernote({
    airMode: true,
    disableDragAndDrop: true,
    popover: {
      air: [
        ['style', ['bold', 'italic', 'underline', 'clear']]
      ]
    },
    callbacks: {
      onChange: function(contents, $editable) {
        scope.task.title = contents;
      }
    }
  });
}

References