VueJS和vue-router:使用v-link时视图数据不会更新

时间:2015-10-06 17:04:53

标签: javascript vue.js

我正在尝试使用vue-router' v-link在VueJS组件之间建立链接。单击链接时,URL会更新,但除非手动刷新页面,否则视图数据不会更新。

此示例的某些上下文:Tour有许多Tour Objects,Tour Objects需要链接到上一个/下一个Tour Objects。

这里是代表旅游对象的路线:

'/tours/:tourId/objects/:objectId': {
    name: 'tourObject',
    component: tourObjectComponent
}

完整示例:



var App = Vue.extend({});

var tourObjectData = [
    { id: "1", name: "Object A" },
    { id: "2", name: "Object B" },
    { id: "3", name: "Object C" },
    { id: "4", name: "Object D" },
    { id: "5", name: "Object E" },
];

var tourComponent = Vue.extend({
    template: '#tourComponent',
    data: function() {
    	return {
        	objects: [],
        };
    },
    created: function() {
    	this.objects = tourObjectData;
    },
});

var tourObjectComponent = Vue.extend({
	template: '#tourObjectComponent',
    data: function() {
    	return {
            currIndex: null,
        	currObject: {},
            prevObject: {},
            nextObject: {},
        };
    },
    created: function() {
        this.currIndex = this.getCurrIndex();
    	this.currObject = this.getCurrObject();
        this.prevObject = this.getPrevObject();
        this.nextObject = this.getNextObject();
    },
    methods: {
        
        // Get current object index within tour objects
        getCurrIndex: function() {
            for (var i = 0; i < tourObjectData.length; i++) {
            	if (tourObjectData[i].id === this.$route.params.objectId) {
                	return i;
                }
            }
        },
        
        // Get current object
    	getCurrObject: function() {
            return tourObjectData[this.currIndex];
        },
        
        // Get previous object
        getPrevObject: function() {
			var prevIndex = this.currIndex > 0 ? 
                this.currIndex - 1 : 
            	tourObjectData.length - 1;
            
            return tourObjectData[prevIndex];
        },
        
        // Get next object
        getNextObject: function() {
            var nextIndex = this.currIndex < tourObjectData.length - 1 ?
                this.currIndex + 1 : 0;
            
            return tourObjectData[nextIndex];
        },
    },
});

var router = new VueRouter();

router.redirect({
    
    // Start on Tour 1
	'/': '/tours/1'
});

router.map({
    
    // Tour
	'/tours/:tourId': {
    	name: 'tour',
        component: tourComponent
    },
    
    // Object within tour
    '/tours/:tourId/objects/:objectId': {
    	name: 'tourObject',
        component: tourObjectComponent
    }
});

router.start(App, '#app');
&#13;
<script src="https://cdn.jsdelivr.net/vue/0.12.10/vue.js"></script>
<script src="https://rawgit.com/vuejs/vue-router/dev/dist/vue-router.js"></script>

<script type="x-template" id="tourComponent">
    <h1>Tour</h1>
    <ul>
        <li v-repeat="objects">
            <a v-link="{name: 'tourObject', params: {tourId: 1, objectId: id}}">{{name}}</a>
        </li>
    </ul>
</script>

<script type="x-template" id="tourObjectComponent">
    <a v-link="{name: 'tour', params: {tourId: 1}}">Back to Tour</a>
    <h1>{{currObject.name}}</h1>
    <ul>
        <li><a v-link="{name: 'tourObject', params: {tourId: 1, objectId: prevObject.id}}">Previous Tour Object: {{prevObject.name}}</a></li>
        <li><a v-link="{name: 'tourObject', params: {tourId: 1, objectId: nextObject.id}}">Next Tour Object: {{nextObject.name}}</a></li>
    </ul>
</script>

<div id="app">
    <router-view></router-view>
</div>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:2)

对于vuejs ^ 2,您可以观察路线并触发这样的更改(在我的情况下,我的用户路线中有用户名参数):

watch:{
    '$route' (to, from) {
        if (to.params.username !== from.params.username) {
            //update whatever
        }
   }
},
来自文档

Dynamic Route Matching

答案 1 :(得分:0)

来自doc,(以及gitter频道上@svevil的帮助):

route: {
    data(transition) {
        transition.next(DataObjectForCurrentRoute);
    }
}

此外,您可以使用computed属性,如下所示:

var App = Vue.extend({});

var tourObjectData = [
    { id: "1", name: "Object A" },
    { id: "2", name: "Object B" },
    { id: "3", name: "Object C" },
    { id: "4", name: "Object D" },
    { id: "5", name: "Object E" },
];

var tourComponent = Vue.extend({
    template: '#tourComponent',
    data: function() {
      return {
        };
    },
    computed: {
      objects: function() {
          return tourObjectData;
      }
    },
});

var tourObjectComponent = Vue.extend({
  template: '#tourObjectComponent',
    data: function() {
      return {
            currIndex: null,
          currObject: {},
            prevObject: {},
            nextObject: {},
        };
    },
    computed: {
      currIndex: function() { 
        for (var i = 0; i < tourObjectData.length; i++) {
          if (tourObjectData[i].id === this.$route.params.objectId) {
            return i;
          }
        };
      },
      currObject: function() { 
        return tourObjectData[this.currIndex];
      },
      prevObject: function() { 
        var prevIndex = this.currIndex > 0 ? 
          this.currIndex - 1 : 
          tourObjectData.length - 1;
        
        return tourObjectData[prevIndex]; 
      },
      nextObject: function() { 
        var nextIndex = this.currIndex < tourObjectData.length - 1 ?
            this.currIndex + 1 : 0;
        
        return tourObjectData[nextIndex]; 
      },
    },
});

var router = new VueRouter();

router.redirect({
    
    // Start on Tour 1
  '/': '/tours/1'
});

router.map({
    
    // Tour
  '/tours/:tourId': {
      name: 'tour',
        component: tourComponent
    },
    
    // Object within tour
    '/tours/:tourId/objects/:objectId': {
      name: 'tourObject',
        component: tourObjectComponent
    }
});

router.start(App, '#app');
<script src="https://cdn.jsdelivr.net/vue/0.12.10/vue.js"></script>
<script src="https://rawgit.com/vuejs/vue-router/dev/dist/vue-router.js"></script>

<script type="x-template" id="tourComponent">
    <h1>Tour</h1>
    <ul>
        <li v-repeat="objects">
            <a v-link="{name: 'tourObject', params: {tourId: 1, objectId: id}}">{{name}}</a>
        </li>
    </ul>
</script>

<script type="x-template" id="tourObjectComponent">
    <a v-link="{name: 'tour', params: {tourId: 1}}">Back to Tour</a>
    <h1>{{currObject.name}}</h1>
    <ul>
        <li><a v-link="{name: 'tourObject', params: {tourId: 1, objectId: prevObject.id}}">Previous Tour Object: {{prevObject.name}}</a></li>
        <li><a v-link="{name: 'tourObject', params: {tourId: 1, objectId: nextObject.id}}">Next Tour Object: {{nextObject.name}}</a></li>
    </ul>
</script>

<div id="app">
    <router-view></router-view>
</div>