我是 vue js 的新手,并尝试将它与 Bootstrap 模式一起使用以查看更多数据。我的场景是一个包含多条记录的表和一个按钮,用于在 Bootstrap 模式中查看已单击记录的详细信息。单击第一个按钮后,它会缓存并且不会更新它,同时为不同的详细信息选择另一个按钮。
有人看到我做错了什么吗?
(它是 Laravel、jQuery 和 VueJS 的组合)
HTML 表格:
<table class="table table-striped">
<thead>
<tr>
<th>E-mail address</th>
<th>Status</th>
<th>Sent at</th>
<th>Expires in</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td class="v-align-middle">
john@doe.example
</td>
<td class="v-align-middle">
<span class="label label-default">
pending
</span>
</td>
<td class="v-align-middle">
2017-06-05 17:59:15
</td>
<td class="v-align-middle">
29 days
</td>
<td>
<div class="btn-group pull-right">
<a href="#" class="btn btn-default" data-toggle="modal" data-target="#inviteDetailsModal" data-email="john@doe.example">
<i class="fa fa-eye"></i>
</a>
</div>
</td>
</tr>
<tr>
<td class="v-align-middle">
jane@doe.example
</td>
<td class="v-align-middle">
<span class="label label-default">
pending
</span>
</td>
<td class="v-align-middle">
2017-06-05 13:27:25
</td>
<td class="v-align-middle">
29 days
</td>
<td>
<div class="btn-group pull-right">
<a href="#" class="btn btn-default" data-toggle="modal" data-target="#inviteDetailsModal" data-email="jane@doe.example">
<i class="fa fa-eye"></i>
</a>
</div>
</td>
</tr>
</tbody>
JavaScript:
$('[data-target="#inviteDetailsModal"]').on('click', function () {
let email = $(this).data('email'),
baseUrl = $('html').data('base');
Vue.component('invite-details', {
data: function () {
return {
email: null,
token: null,
logs: [],
expires: null
}
},
methods: {
update: function (data) {
this.email = data['email'];
this.token = data['token'];
this.logs = data['logs'];
this.expires = data['expires'];
},
fetchData: function () {
this.$http.get(baseUrl + '/system/invites/' + email + '/details')
.then(response => {
this.update(response.body);
}, response => {
console.log('whoops something went wrong');
});
}
},
mounted: function () {
this.$el.addEventListener('shown.bs.modal', this.fetchData());
},
beforeDestroy: function () {
this.$el.removeEventListener('shown.bs.modal', this.fetchData());
}
});
new Vue({
el: '#inviteDetailsModal'
});
});
Bootstrap 模式:
<div class="modal fade slide-up" id="inviteDetailsModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content-wrapper">
<invite-details inline-template>
<div class="modal-content" id="details">
<div class="modal-header clearfix text-left">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">
<i class="pg-close fs-14"></i>
</button>
<h5>
Invite details for <span class="semi-bold">@{{ email }}</span>
</h5>
<p class="p-b-10">
<span data-tooltip="true" data-placement="bottom" title="token">
<em>@{{ token }}</em>
</span>
</p>
</div>
<div class="modal-body">
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th>Sent at</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr v-for="log in logs">
<td>@{{ log.number }}</td>
<td>@{{ log.sentAt }}</td>
<td>@{{ log.status }}</td>
</tr>
</tbody>
</table>
</div>
<div class="modal-footer text-center">
<span class="hint-text">
<em>expires in <strong>@{{ expires }}</strong> days</em>
</span>
</div>
</div>
</invite-details>
</div>
</div>
最佳答案
好吧,我深入挖掘以使其正常工作并付出了额外的努力,因为你提到你是 VueJS 的新手。我在你的代码中认出了我以前的自己,你以 JQuery 的心态进入 VueJS ;-)
在删除完整代码之前的几个快速注释:
使用表数据库行的整数 ID 在任何地方引用用户。 这样,当电子邮件更新时,您仍然知道它在 前端。通过检查代码,我发现电子邮件可以更改 (因为它是一个可更新的
data
属性,但它也用于 你的GET
请求:baseUrl + '/system/invites/' + email + '/details'
随后,您可以使用此 ID 轻松生成唯一实例 你的模式 :-) 这就是你想要使用 VueJS 的方式!
由于您在多个地方使用相同的数据,请查看 用于商店的 Vuex。乍一看可能令人望而生畏,但曾经很棒 你要掌握它。在您的情况下,相同的数据集将是 用于原始表格和模态。如果有更新, 一切都在更新!
使用 Vuex,您可以从任何地方触发更新。现在的数据 每次单击眼睛按钮时都会更新。然而,这是 非常老套,因为我已经将按钮作为模态模板的一部分, 每次点击它都会调用
fetchData()
(检查 安慰)。理想情况下,您要做的是使用 Vuex 并生成 一切都来自单点真实数据集。目前,如果 modal的数据更新了,原来的表没有。使用 VueJS 创建您自己的模态框同样容易。的好处 这在您的代码中的开销较小,因为您可以使用
v-if
, 所以 除非实际需要,否则不会加载到 DOM 中。并判断 从您当前的代码中,将单击详细信息按钮 偶尔。如果您还没有安装 VueJS 调试器: https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd , 它将帮助您“看到”幕后情况。
好了,现在开始写代码了!首先,将此行添加到您的 app.js
文件:
import JaimyTable from './components/stackoverflow/JaimyTable.vue'
在 var app = new Vue({
的正上方线。并将其添加到您的组件中,因此您最终会得到如下内容:
import JaimyTable from './components/stackoverflow/JaimyTable.vue'
var app = new Vue({
components: {
JaimyTable,
},
});
这是 JaimyTable.vue 文件:
<template>
<div class="container">
<table class="table table-striped">
<thead>
<tr>
<th>E-mail address</th>
<th>Status</th>
<th>Sent at</th>
<th>Expires in</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td class="v-align-middle">
john@doe.example
</td>
<td class="v-align-middle">
<span class="label label-default">
pending
</span>
</td>
<td class="v-align-middle">
2017-06-05 17:59:15
</td>
<td class="v-align-middle">
29 days
</td>
<td>
<div class="btn-group pull-right">
<jaimy-modal id="1"></jaimy-modal>
</div>
</td>
</tr>
<tr>
<td class="v-align-middle">
jane@doe.example
</td>
<td class="v-align-middle">
<span class="label label-default">
pending
</span>
</td>
<td class="v-align-middle">
2017-06-05 13:27:25
</td>
<td class="v-align-middle">
29 days
</td>
<td>
<div class="btn-group pull-right">
<jaimy-modal id="2"></jaimy-modal>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
import JaimyModal from './JaimyModal.vue'
export default {
components: { JaimyModal },
props: [],
mixins: [],
data: function () {
return {
//
}
},
computed: {
computed_variable() {
return '';
}
},
created() {
//
},
mounted() {
//
},
methods: {
//
},
watch: {
//
}
}
</script>
请注意 <jaimy-modal id="1"></jaimy-modal>
线。您可能想使用 v-for
生成所有 <tr>
行自动 :) 确保 id=
对应于你数据库中的ID。
现在为 JaimyModal.vue
所有魔法发生的地方:
<template>
<div>
<a href="#" class="btn btn-default" data-toggle="modal" :data-target="'#inviteDetailsModal' + id" @click="fetchData()">
<i class="fa fa-eye"></i>
</a>
<div class="modal fade slide-up" :id="'inviteDetailsModal' + id" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content-wrapper">
<div class="modal-content" id="details">
<div class="modal-header clearfix text-left">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">
<i class="pg-close fs-14"></i>
</button>
<h5>
Invite details for <span class="semi-bold">{{ email }}</span>
</h5>
<p class="p-b-10">
<span data-tooltip="true" data-placement="bottom" title="token">
<em>{{ token }}</em>
</span>
</p>
</div>
<div class="modal-body">
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th>Sent at</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr v-for="log in logs">
<td>{{ log.number }}</td>
<td>{{ log.sentAt }}</td>
<td>{{ log.status }}</td>
</tr>
</tbody>
</table>
</div>
<div class="modal-footer text-center">
<span class="hint-text">
<em>expires in <strong>{{ expires }}</strong> days</em>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['id'],
data: function () {
return {
email: null,
token: null,
logs: [],
expires: null,
baseUrl: 'https://yourbaseurl.com',
}
},
mounted: function () {
//
},
methods: {
update: function (data) {
this.email = data['email'];
this.token = data['token'];
this.logs = data['logs'];
this.expires = data['expires'];
},
fetchData: function () {
console.log('data fetched');
// Commented out for local purposes
// this.$http.get(this.baseUrl + '/system/invites/' + this.email + '/details')
// .then(response => {
// this.update(response.body);
// }, response => {
// console.log('whoops something went wrong');
// });
// Dummy data
this.update({
email: 'test@test ' + this.id + '.com',
token: 'token123123asdsasdasdasd',
logs: [
{
number: 1,
sentAt: '2017-01-01',
status: 'Ok',
},
{
number: 2,
sentAt: '2017-02-01',
status: 'Failed',
},
],
expires: '2017-10-01'
});
}
},
}
</script>
这里重要的是要注意 :data-target="'#inviteDetailsModal' + id"
按钮中的部分,其中数字对应于 prop 的 id。通过使用 :
您将其设为一个表达式,它解析为一个唯一引用。
如您所见,设置与之前完全不同。模态是表格行的嵌套组件。一旦您开始将组件视为外观和功能的重复部分,但其中包含独特的数据,事情就会很快点击。将其视为 Laravel 中的模型。
在长时间被告知需要将设计 (CSS)、标记 (HTML) 和功能 (JS) 分开之后,将它们全部放在一个文件中是很奇怪的。但是拥抱它,你会爱上 VueJS :D
然后看看 Vuex!第二个你得到多个使用和操作同一个数据集的组件,这是天赐之物!
哦,最后:当你开始考虑使用 fn.trigger 之类的东西时,你就错误地接近了 VueJS。请记住这一点 :) 它具有您使用该页面所需的所有工具,而且还有一些!
编码愉快!
关于javascript - Bootstrap 模式不使用 vue js v2 双向绑定(bind)更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44371290/