您必须使用单独的 Vue 实例,以防您不想要 vue-router..
但它会导致一些内存泄漏一些问题所以对一些这个..
当您在单击选项卡时发出 ajax 请求时,您必须首先销毁当前的 Vue 实例..然后将数据添加到 dom
let app = new Vue({
el: '#app',
})
// doo other stuff
$.ajax({
// ajax settings
success: function(data){
// here you should destroy the Old Vue instance otherwise it will make issues
app.$destroy()
$('body').html(data);
}
})
我建议你制作一个小的 javascript 插件..
单击链接时,它将获取链接的 url 执行 ajax 请求,并在每次请求时将数据提供给页面,它将触发回调..您破坏旧的新实例..
对于某种加载器,您可以在 ajax 请求之前使用另一个回调来显示页面加载器或其他东西..
我在我的一个项目中使用了这种技术。我用 jquery ajax 制作了一个插件...
在这里……
import $ from 'jquery';
import anime from 'animejs';
export let Loader = (function(window , document , undefined){
class Loader{
constructor(options = null){
this.options = Object.assign({ pageProgressBar : false , pageProgressBarDuraion: 2000 } , options);
this.functions = [];
this.xhr = null;
this.routes = this.options.routes || [];
window.addEventListener('load' , this.init.bind(this));
}
init(){
if(this.options.container)
this.$container = $(this.options.container).length ? $(this.options.container) : $(document.body)
else
this.$container = $(document.body)
this.functions['popstate'] = this.onPopState.bind(this);
window.addEventListener('popstate' , this.functions['popstate'] );
this.functions['handleLinks'] = this.handleLinks.bind(this);
window.addEventListener('click' , this.functions['handleLinks']);
}
pushHistory(type , url){
var state = {url : url , type : type};
window.history.pushState(state , '' , url);
}
onPopState(e){
var state = e.state;
if(state == null)
return true;
this.loadUrl(state.url)
}
handleLinks(e){
if(!e.target.matches('[ajax-link]'))
return ;
e.preventDefault();
var url = e.target.href;
var self = this;
this.loadUrl(url).then(function(){
self.pushHistory('get' , url);
});
}
load(url)
{
let self = this;
return new Promise(function(resolve , reject){
self.loadUrl(url).then(function(){
self.pushHistory('get' , url);
resolve();
});
});
}
loadUrl(url){
var isError = true;
if(this.xhr)
{
isError = false;
if(this.options.onAbort)
this.options.onAbort();
this.xhr.abort();
if(this.options.pageProgressBar)
restartProgressBar();
this.xhr = null;
}
var route = this.getMatchingRoute(url);
if(route)
{
if(route.beforeLoad)
route.beforeLoad();
}
if(this.beforeLoading)
this.beforeLoading();
var self = this;
return new Promise(function(resolve , reject){
self.xhr = $.ajax({
url : url,
type: 'get',
cache : false,
beforeSend (xhr){
if(self.options.onLoading)
self.options.onLoading(xhr);
if(self.options.pageProgressBar)
startProgressBar( self.options.pageProgressBarDuration );
},
success (data){
self.$container.html(data);
self.xhr = null;
resolve();
if(route && route.afterLoad)
route.afterLoad();
if(self.options.onLoaded)
self.options.onLoaded(data);
if(self.options.pageProgressBar)
endProgressBar();
},
error (response){
if(response.response)
window.location = url;
},
});
});
}
reload(){
this.loadUrl(window.location.href);
}
getMatchingRoute(url){
if(this.routes)
{
for(let i = 0; i< this.routes.length ; i++)
{
var route = this.routes[i];
if(url.indexOf(route.route) >= 0 ){
return route;
}
};
}
return null;
}
destory(){
window.removeEventListener('popstate' , this.functions['popstate'] );
}
}
return Loader;
// Provate progressbar methods
var $pageProgressBar = null;
function restartProgressBar(){
$pageProgressBar.remove();
anime.remove($pageProgressBar[0]);
}
function startProgressBar( duration = 3000){
$pageProgressBar = $('<div>').addClass('page-progressbar')
$('body').append($pageProgressBar)
anime({
targets: $pageProgressBar[0],
width: '70%',
easing : 'easeInOutQuad',
duration : 3000
});
}
function endProgressBar(){
anime.remove($pageProgressBar[0]);
var $prog = $('.page-progressbar');
$prog.css({ width: '100%' , transition :".35s all" , 'webkit-transition' : ".35s all" });
setTimeout(()=>{
$prog.css({ opacity: '0'});
setTimeout( () => $pageProgressBar[0].remove() , 200);
},350);
}
}(window , document , undefined));
它有一些进度条和其他可以删除的东西来修改它
现在你要做的就是
window.Loader = new Loader({
// tell it the tag you want to put data in
container :"#app-data",
})
然后将ajax-link 属性添加到您的任何链接中,它的选项卡链接
它将拉取 url 并将内容放入您指定的容器中
还有一些回调
您可以添加Loader.beforeLoading = function(){
app.$destroy();
}
就是这样