如何在.NET 6 Razor Pages中用_Layout.cshtml无刷新加载页面?
在.NET 6 Razor Pages中实现导航无刷新更新主内容区
步骤1:给主内容区域添加唯一ID
打开_Layout.cshtml,找到渲染页面主体的@RenderBody()代码,把它包裹在带唯一ID的容器里,方便JS精准定位替换内容:
<div id="main-content" class="container mt-4"> @RenderBody() </div>
步骤2:改造导航链接
把顶部导航和你要添加的侧边导航链接,都改成支持AJAX触发的样式:
- 保留
href属性(用于SEO和无JS场景降级) - 添加
ajax-link类,方便JS批量监听点击事件 - 用
data-page属性存储目标页面的路由路径(和Razor Pages的路由对应)
示例顶部导航改造:
<ul class="navbar-nav me-auto mb-2 mb-lg-0"> <li class="nav-item"> <a class="nav-link ajax-link" href="/" data-page="/Index">Home</a> </li> <li class="nav-item"> <a class="nav-link ajax-link" href="/Privacy" data-page="/Privacy">Privacy</a> </li> </ul>
示例侧边导航(你计划添加的):
<div class="col-md-3 sidebar"> <div class="list-group"> <a href="/Products" class="list-group-item ajax-link" data-page="/Products">产品列表</a> <a href="/Orders" class="list-group-item ajax-link" data-page="/Orders">订单管理</a> </div> </div>
步骤3:添加无刷新加载的JS逻辑
在_Layout.cshtml的</body>标签前添加原生JS代码,无需依赖jQuery,实现核心无刷新功能:
<script> document.addEventListener('DOMContentLoaded', function() { const mainContent = document.getElementById('main-content'); const ajaxLinks = document.querySelectorAll('.ajax-link'); // 处理导航链接点击 ajaxLinks.forEach(link => { link.addEventListener('click', function(e) { e.preventDefault(); // 阻止默认页面跳转 const targetUrl = this.dataset.page; // Fetch请求目标页面 fetch(targetUrl) .then(res => res.text()) .then(html => { // 临时DOM解析页面内容 const tempContainer = document.createElement('div'); tempContainer.innerHTML = html; // 替换主内容区域 mainContent.innerHTML = tempContainer.querySelector('#main-content').innerHTML; // 更新页面标题 document.title = tempContainer.querySelector('title').textContent; // 更新地址栏,支持浏览器前进后退 history.pushState(null, '', targetUrl); // 执行目标页面的专属脚本(解决AJAX加载后脚本不生效问题) const pageScripts = tempContainer.querySelector('#page-scripts'); if (pageScripts) { pageScripts.querySelectorAll('script').forEach(script => { const newScript = document.createElement('script'); script.src ? newScript.src = script.src : newScript.textContent = script.textContent; document.body.appendChild(newScript); setTimeout(() => newScript.remove(), 0); }); } }) .catch(err => console.error('页面加载失败:', err)); }); }); // 处理浏览器前进后退 window.addEventListener('popstate', function() { fetch(window.location.pathname) .then(res => res.text()) .then(html => { const tempContainer = document.createElement('div'); tempContainer.innerHTML = html; mainContent.innerHTML = tempContainer.querySelector('#main-content').innerHTML; document.title = tempContainer.querySelector('title').textContent; }); }); }); </script>
步骤4:适配页面内脚本(可选)
如果你的Razor页面有@section Scripts里的自定义脚本,AJAX加载后默认不会执行,需要把脚本放到指定容器里。修改每个页面的Scripts区域:
@section Scripts { <div id="page-scripts"> <script> // 这里写页面专属脚本,比如初始化表格、绑定事件等 console.log('隐私页面脚本执行了'); </script> </div> }
注意事项
- 确保
data-page里的路径和Razor Pages的路由一致(比如/Privacy对应Privacy.cshtml) - 带权限验证的页面,Fetch请求会自动携带Cookie,无需额外配置
- 如果页面有大量复杂交互,也可以考虑嵌入Blazor组件,但上述方案更轻量,无需改动项目核心结构
内容的提问来源于stack exchange,提问作者killerbunnyattack
相关产品推荐
相关产品推荐

