Vue v-bind and AJAX



我正试图从jQuery转向Vue 2.0,在大多数情况下,过渡感觉非常容易。

然而,当进行AJAX调用并与响应交互时,我处理错误了,我无法进入Vue做事的心态。

例如,我有一个"模态触发器",单击它会打开一个模态窗口,并对绑定到触发器的href进行AJAX调用,然后在模态中将html返回到v-html。当我想在模态中有@click事件时,我的问题就来了,显然它不起作用,因为Vue还没有注册它,这是有道理的。

在jQuery中,我可以说,例如$(document).on('click'…这样它就可以识别任何加载了AJAX的页面,我无法在Vue中找到类似的选项,我显然错误地处理了这种情况。

我花了几个小时寻找解决方案,我没有进一步的进展,任何有类似情况经验的人能否告诉我他们是如何克服问题的,或者为我指明处理类似问题的教程的方向。

提前谢谢。

我相信我已经通过使用"动态组件"-我构建了一个基本的例子,它基于按钮点击加载不同的组件,对php脚本进行AJAX调用,以更新新组件按钮触发的警报消息。

这是我的代码:

script.js

Vue.component('foo', {
'template' : '<button @click="aFooButton()">This is a foo button</button>',
data() {
return {
}
},
methods: {
aFooButton() {
alert(this.$parent.componentData);
}
}
})

Vue.component('bar', {
'template' : '<button @click="aBarButton()">This is a bar button</button>',
data() {
return {
}
},
methods: {
aBarButton() {
alert(this.$parent.componentData);
}
}
})

new Vue({
el : "#root",
data : {
component: null,
componentData: null
},
methods : {
makeFoo() {
axios.get('ajax/foo.php').then(response => this.componentData = response.data);
this.component = 'foo';
},
makeBar() {
axios.get('ajax/bar.php').then(response => this.componentData = response.data);
this.component = 'bar';
}
},
mounted() {
}

})

Vue.component('bar', {
'template' : '<button @click="aBarButton()">This is a bar button</button>',
data() {
return {
}
},
methods: {
aBarButton() {
alert(this.$parent.componentData);
}
}
})

new Vue({
el : "#root",
data : {
component: null,
componentData: null
},
methods : {
makeFoo() {
axios.get('ajax/foo.php').then(response => this.componentData = response.data);
this.component = 'foo';
},
makeBar() {
axios.get('ajax/bar.php').then(response => this.componentData = response.data);
this.component = 'bar';
}
},
mounted() {
}

})

index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Vue</title>
</head>
<body id="app">
<div id="root" class="container">
<div>
<component :is="component"></component>
</div>
<div>
<button @click="makeFoo()">Make foo</button>
<button @click="makeBar()">Make bar</button>
</div>
</div>

<script src="ajax/javascript/vue.js"></script>
<script src="ajax/javascript/axios.js"></script>
<script src="ajax/javascript/script.js"></script>
</body>
</html>

foo.php

<?php
header('Content-Type: application/json');
echo json_encode('This is some Foo information');
?>

bar.php

<?php
header('Content-Type: application/json');
echo json_encode('This is some Bar information');
?>

在我看来,这是一个很好的解决方案,有人能告诉我是否有任何理由不应该使用这种方法来解决我的问题吗?

(请注意,这是一个基本的例子,我通常会把我的组件放在单独的文件中等)

提前感谢

编辑:

进一步阅读,我发现";Vue路由器";这似乎提供了一个与我上面所取得的类似的解决方案——有人有这方面的经验吗?这是一个更好的选择吗?

编辑2:

我决定使用Vue路由器重新创建上面的代码,任何感兴趣的人的代码都是:

index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Vue</title>

</head>
<body id="app">
<div id="root" class="container">
<div>
<router-link to="/foo">Go to Foo</router-link>
<router-link to="/bar">Go to Bar</router-link>
</div>
<div>
<router-view></router-view>
</div>
</div>

<script src="router/javascript/vue.js"></script>
<script src="router/javascript/router.js"></script>
<script src="router/javascript/axios.js"></script>
<script src="router/javascript/script.js"></script>
</body>
</html>

script.js

const Foo = Vue.component('foo', {
'template' : '<button @click="aFooButton()">This is a foo button</button>',
data() {
return {
loading: false,
message: null,
error: null
}
},
created () {
// fetch the data when the view is created and the data is
// already being observed
this.fetchData()
},
watch: {
// call again the method if the route changes
'$route': 'fetchData'
},
methods: {
fetchData () {
this.error = this.post = null
this.loading = true
axios.get('async-ajax/foo.php').then((response) => {
this.message = response.data;
});
},
aFooButton() {
alert(this.message);
}

}
})

const Bar = Vue.component('bar', {
'template' : '<button @click="aBarButton()">This is a bar button</button>',
data() {
return {
loading: false,
message: null,
error: null
}
},
created () {
// fetch the data when the view is created and the data is
// already being observed
this.fetchData()
},
watch: {
// call again the method if the route changes
'$route': 'fetchData'
},
methods: {
fetchData () {
this.error = this.post = null
this.loading = true
axios.get('async-ajax/bar.php').then((response) => {
this.message = response.data;
});
},
aBarButton() {
alert(this.message);
}

}

})
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
const router = new VueRouter({
routes: routes
})
new Vue({
el : "#root",
router: router,

})

根据我的经验,Vue路由器更适合单页应用程序,它会更新浏览器中的URL等,因为我觉得动态组件更适合我的个人需求。我很想听听其他人的意见和经历。

您需要条件渲染。关键是,模板不是有条件的,数据是有条件的。所以@click实际上总是在你的模板中,但随着数据的变化,你会有不同的视图,甚至在你的视图中有不同的用户交互行为。

  • 您想要一个按钮,但仅当某些条件flag为true时,因此在data选项中,flag最初为false,但您通过AJAX调用从服务器加载真实状态,该调用可能会将flag设置为true,以便按钮显示。模板可能类似于<button v-if="flag" @click="clicked"></button>

  • 你总是想要一个按钮,但点击它并不总是有作用(例如显示警报),所以clicked中有<button @click="clicked"></button>if(this.flag) {/*do something*/},而flag是由AJAX加载的,就像上面一样。

最新更新