简体   繁体   中英

Vue.js routing no method handled

I get some trouble with Vue.js and his routing system. I made an example here .

Why the method is correctly attach when I use a template (see Foo) and why not when I use an el (see Bar) ?

Here his the code:

index.js

var Foo = Vue.extend({
    template: '<p v-on:click.prevent="foo">This is foo!</p>',

  methods: {
      foo: function(){
        alert('YEAH')
      }
    }
})

var Bar = Vue.extend({
    el: function(){
      return '#bar'
    },

    methods: {
      bar: function(){
        alert('YEAH')
      }
    }
})

var App = Vue.extend({})

var router = new VueRouter()

router.map({
    '/foo': {
        component: Foo
    },
    '/bar': {
        component: Bar
    }
})

router.start(App, '#app')

index.html

<div id="app">
  <h1>Hello App!</h1>
  <p>
    <!-- use v-link directive for navigation. -->
    <a v-link="{ path: '/foo' }">Go to Foo</a>
    <a v-link="{ path: '/bar' }">Go to Bar</a>
  </p>
  <div id="bar" v-bind:class="$route.path == '/bar' ? '' : 'hidden'">
    <p v-on:click.prevent="bar">This is bar!</p>
  </div>
  <!-- use router-view element as route outlet -->
  <router-view></router-view>
</div>

You misunderstood the el purpose. When you pass el to component it tells Vue on which element to mount itself

Note that the provided element merely serves as a mounting point; it will be replaced if a template is also provided, unless replace is set to false. The resolved element will be accessible as vm.$el.

Actually you have no template inside #bar that Vue could compile and that's why you have no output. Also using el inside another Vue's el (in your case #app ) is a bad idea. The v-on:click.prevent="bar" bit is compiled in parent's ( App instance) scope, and since App has no bar method you get a warning.

Better solution: http://codepen.io/anon/pen/zqWKrg

Notice that now each component has it's own template and you can clearly see scope of each component: #app is compiled in App scope, #foo is compiled in Foo scope and #bar is compiled in Bar scope.

  1. you should use template: '#bar' instead of el: '#bar' the el option is not a selector for the template.

    var Bar = Vue.extend({ template: '#bar',

     methods: { bar: function(){ alert('YEAH') } } 

    })

  2. You (ab)used a regular HTML element in the Apps main template as a sub-template for a component - that's not something you should do.

Its also the reason the click event is not working: the content of that div, including the click event, is evaluated by the App component, not the Bar component. And the App component has no "bar" method.

Hence the error in the console:

[Vue warn]: v-on:click="bar" expects a function value, got undefined

The template should look like this:

<script type="x-template" id="bar">
  <div>
    <p v-on:click.prevent="bar">This is bar!</p>
  </div>
</script>

<!-- or with HTML5 template tag: -->
<template id="bar">
  <div>
    <p v-on:click.prevent="bar">This is bar!</p>
  </div>
</template>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM