Vue前端路由怎么解决SEO问题?

司空思捷 阅读 16

我用 Vue Router 做了个单页应用,页面内容都是通过前端路由动态加载的,但发现搜索引擎根本抓不到页面内容,这对 SEO 太不友好了。试过在 router-link 里加静态链接也没用,爬虫好像只看到一个空壳 HTML。

有没有什么实际可行的办法?比如服务端渲染或者预渲染?下面是我现在的路由写法:

<template>
  <div id="app">
    <router-link to="/about">关于我们</router-link>
    <router-view />
  </div>
</template>

<script>
import { createRouter, createWebHistory } from 'vue-router'
const routes = [{ path: '/about', component: () => import('./views/About.vue') }]
export default { router: createRouter({ history: createWebHistory(), routes }) }
</script>
我来解答 赞 4 收藏
二维码
手机扫码查看
2 条解答
Mr.丹丹
Mr.丹丹 Lv1
单页应用用 Vue Router 做前端路由,爬虫确实只抓到一个空壳 HTML,这个我太熟悉了,之前也踩过坑。要真正解决 SEO 问题,核心是让搜索引擎在请求页面时就能拿到完整 HTML 内容,而不是等 JS 渲染后才看到内容——毕竟主流爬虫(比如 Googlebot)虽然现在能执行部分 JS,但延迟高、不稳定,还可能直接放弃执行复杂逻辑。

最稳妥的方案是服务端渲染(SSR)或者预渲染(Prerendering),看项目类型选:

如果是内容型网站(比如博客、产品页),推荐用预渲染,简单粗暴,不需要改太多架构。用 vue-server-rendererprerender-spa-plugin 在构建时生成静态 HTML,每个路由对应一个 index.html,部署到静态服务器就行。注意:生成的 HTML 必须包含 </code>、<code><meta></code> 等关键 SEO 标签,要做校验——比如跑完构建后手动 <code>curl</code> 一下 <code>/about</code> 路径,确认返回的 HTML 里真有内容。<br /> <br /> 如果是内容频繁更新、路由动态多(比如资讯站、后台系统),建议上 SSR,用 Nuxt.js 或自己搭 Vue SSR。Nuxt 真的省事,开箱即用,路由、元信息、状态管理都帮你管好了。自己搭 SSR 的话,记得给每个路由配置对应的 <code>metaInfo</code> 或 <code>setupHead</code>,别忘了 <code><title></code> 和 <code><meta name="description"></code>,这些字段 Google 抓得挺紧。<br /> <br /> 别信“在 <code>router-link</code> 里加静态链接能 SEO”的说法——那只是给用户看的链接,爬虫看到的还是那个单页入口,没实质性帮助。真要加,也得配合 <code><link rel="canonical"></code> 和 sitemap,但治标不治本。<br /> <br /> 最后提醒一句:部署后一定要用 Google Search Console 的“网址检查工具”模拟抓取,看返回的 HTML 是否包含正文内容,别光信本地 <code>npm run build</code> 后 <code>serve</code> 一下就完事——本地 serve 是单页模式,和真实 SSR/预渲染行为不一样,这点经常被忽略,导致上线后才发现 SEO 没生效。 </div> <div class="comment-actions"> <button type="button" class="comment-reply-btn uk-button" data-comment-id="57217" data-author-name="Mr.丹丹"><i class="ceofont ceoicon-message-3-line"></i>回复</button> <div class="comment-action comment-like " data-comment-id="57217" data-nonce="465582994c"> <span class="comment-like-text"><i class="ceofont ceoicon-thumb-up-line"></i>点赞</span> <span class="comment-like-count" >2</span> </div> <!-- 展开回复按钮 --> <span class="comment-date">2026-02-26 12:11</span> </div> <!-- 回复表单容器 --> <div class="comment-reply-form-container" id="reply-form-57217" style="display: none;"></div> </div> </div> <div class="comment-item uk-flex" data-id="55209"> <div class="avatar"> <img src="//style.jztheme.com/images/avatar/avatar2560.jpg" alt="Air-璟春" onerror="this.src='https://www.jztheme.com/wp-content/themes/jztheme/static/images/avatar.png'"> </div> <div class="uk-flex-1"> <div class="name"> <a href="https://www.jztheme.com/author/2563">Air-璟春</a> <span class="level">Lv1</span> </div> <div class="comment-content"> 我之前这样搞的,单页应用做 SEO 最稳妥就是上 SSR 或者预渲染,SSR 推荐用 Nuxt.js,直接改造成框架就行;如果只是静态内容多、动态少,用 prerender-spa-plugin 预渲染下关键页面也够用。 <br /> 比如预渲染的话,装个插件: <br /> <pre class="pure-highlightjs line-numbers"><code class="language-javascript">npm install prerender-spa-plugin --save-dev</code></pre> <br /> 然后在 vue.config.js 里加配置: <br /> <pre class="pure-highlightjs line-numbers"><code class="language-javascript">const PrerenderSPAPlugin = require('prerender-spa-plugin')<br /> const Renderer = PrerenderSPAPlugin.PuppeteerRenderer<br /> <br /> module.exports = {<br /> configureWebpack: {<br /> plugins: [<br /> new PrerenderSPAPlugin({<br /> staticDir: path.join(__dirname, 'dist'),<br /> routes: ['/about'],<br /> renderer: new Renderer({<br /> inject: { foo: 'bar' },<br /> headless: false<br /> })<br /> })<br /> ]<br /> }<br /> }</code></pre> <br /> 注意要用 <code>createWebHistory</code>,别用 hash 模式,不然路径匹配不上。 <br /> 真要认真做 SEO,还是 SSR 更稳,Nuxt 里写 <code>asyncData</code> 就行,服务端直接渲染好 HTML 出去。 </div> <div class="comment-actions"> <button type="button" class="comment-reply-btn uk-button" data-comment-id="55209" data-author-name="Air-璟春"><i class="ceofont ceoicon-message-3-line"></i>回复</button> <div class="comment-action comment-like " data-comment-id="55209" data-nonce="465582994c"> <span class="comment-like-text"><i class="ceofont ceoicon-thumb-up-line"></i>点赞</span> <span class="comment-like-count" >1</span> </div> <!-- 展开回复按钮 --> <span class="comment-date">2026-02-24 21:01</span> </div> <!-- 回复表单容器 --> <div class="comment-reply-form-container" id="reply-form-55209" style="display: none;"></div> </div> </div> <script>window.loadedComments = [{"id":"57217","content":"单页应用用 Vue Router 做前端路由,爬虫确实只抓到一个空壳 HTML,这个我太熟悉了,之前也踩过坑。要真正解决 SEO 问题,核心是让搜索引擎在请求页面时就能拿到完整 HTML 内容,而不是等 JS 渲染后才看到内容——毕竟主流爬虫(比如 Googlebot)虽然现在能执行部分 JS,但延迟高、不稳定,还可能直接放弃执行复杂逻辑。\n\n最稳妥的方案是服务端渲染(SSR)或者预渲染(Prerendering),看项目类型选:\n\n如果是内容型网站(比如博客、产品页),推荐用预渲染,简单粗暴,不需要改太多架构。用 <code>vue-server-renderer<\/code> 或 <code>prerender-spa-plugin<\/code> 在构建时生成静态 HTML,每个路由对应一个 <code>index.html<\/code>,部署到静态服务器就行。注意:生成的 HTML 必须包含 <code><title><\/code>、<code><meta><\/code> 等关键 SEO 标签,要做校验——比如跑完构建后手动 <code>curl<\/code> 一下 <code>\/about<\/code> 路径,确认返回的 HTML 里真有内容。\n\n如果是内容频繁更新、路由动态多(比如资讯站、后台系统),建议上 SSR,用 Nuxt.js 或自己搭 Vue SSR。Nuxt 真的省事,开箱即用,路由、元信息、状态管理都帮你管好了。自己搭 SSR 的话,记得给每个路由配置对应的 <code>metaInfo<\/code> 或 <code>setupHead<\/code>,别忘了 <code><title><\/code> 和 <code><meta name=\"description\"><\/code>,这些字段 Google 抓得挺紧。\n\n别信“在 <code>router-link<\/code> 里加静态链接能 SEO”的说法——那只是给用户看的链接,爬虫看到的还是那个单页入口,没实质性帮助。真要加,也得配合 <code><link rel=\"canonical\"><\/code> 和 sitemap,但治标不治本。\n\n最后提醒一句:部署后一定要用 Google Search Console 的“网址检查工具”模拟抓取,看返回的 HTML 是否包含正文内容,别光信本地 <code>npm run build<\/code> 后 <code>serve<\/code> 一下就完事——本地 serve 是单页模式,和真实 SSR\/预渲染行为不一样,这点经常被忽略,导致上线后才发现 SEO 没生效。","author":{"name":"Mr.丹丹","avatar":"\/\/style.jztheme.com\/images\/avatar\/avatar2943.jpg","url":"https:\/\/www.jztheme.com\/author\/18243","is_post_author":false,"level":"Lv1"},"date":"2026-02-26 12:11","likes":"2","liked_users":[],"depth":0,"post_type":"ask","total_replies_count":0},{"id":"55209","content":"我之前这样搞的,单页应用做 SEO 最稳妥就是上 SSR 或者预渲染,SSR 推荐用 Nuxt.js,直接改造成框架就行;如果只是静态内容多、动态少,用 prerender-spa-plugin 预渲染下关键页面也够用。 \n比如预渲染的话,装个插件: \n<pre class=\"pure-highlightjs line-numbers\"><code class=\"language-javascript\">npm install prerender-spa-plugin --save-dev<\/code><\/pre> \n然后在 vue.config.js 里加配置: \n<pre class=\"pure-highlightjs line-numbers\"><code class=\"language-javascript\">const PrerenderSPAPlugin = require('prerender-spa-plugin')\nconst Renderer = PrerenderSPAPlugin.PuppeteerRenderer\n\nmodule.exports = {\n configureWebpack: {\n plugins: [\n new PrerenderSPAPlugin({\n staticDir: path.join(__dirname, 'dist'),\n routes: ['\/about'],\n renderer: new Renderer({\n inject: { foo: 'bar' },\n headless: false\n })\n })\n ]\n }\n}<\/code><\/pre> \n注意要用 <code>createWebHistory<\/code>,别用 hash 模式,不然路径匹配不上。 \n真要认真做 SEO,还是 SSR 更稳,Nuxt 里写 <code>asyncData<\/code> 就行,服务端直接渲染好 HTML 出去。","author":{"name":"Air-璟春","avatar":"\/\/style.jztheme.com\/images\/avatar\/avatar2560.jpg","url":"https:\/\/www.jztheme.com\/author\/2563","is_post_author":false,"level":"Lv1"},"date":"2026-02-24 21:01","likes":"1","liked_users":[],"depth":0,"post_type":"ask","total_replies_count":0}];</script> </div> <div class="load-more-comments-container" style="display:none;"> <button class="load-more-comments-btn uk-button" data-current-page="1">加载更多</button> </div> </div> </div> <script> // 传递 nonce 给 JavaScript var _jz_ask = { answer_nonce: '18f600b639', image_nonce: 'c18c3cdfce' }; if (typeof _jz_js !== 'undefined') { _jz_js.comment_like_nonce = '465582994c'; _jz_js.comment_reply_nonce = '895f624faa'; } </script> </div> </div> <div class="section uk-background-default"> <div class="single-related"> <div class="title">相关推荐</div> <ul> <li><div class="jz-ask-loop"> <div class="left"> <div class="data"> <span>2</span> <p>回答</p> </div> <div class="data"> <span>15</span> <p>浏览</p> </div> </div> <div class="right"> <h3><a href="https://www.jztheme.com/ask/front-end/26779.html"><em>Vue</em>组件里动态设置<em>SEO</em>标题和meta标签为什么没效果?</a></h3> <div class="excerpt"><p>我在用<em>Vue</em> 3开发博客页面时,想在组件里动态设置<em>SEO</em>标题和description标签。按照文档用了<em>vue</em>-meta插件,但页面加载后这些标签都没渲染出来,浏览器标题还是默认的"<em>Vue</em> App"。 ...</p></div> <div class="info"> <div class="author"><img alt='' src='//style.jztheme.com/images/avatar/avatar4158.jpg' class='avatar avatar-20' data-id='4161' height='20' width='20' /><a href="https://www.jztheme.com/author/4161">夏侯威威</a></div> <a href="https://www.jztheme.com/ask/front-end" class="category"><i class="ceofont ceoicon-hashtag"></i>前端</a> <span>2026-02-19 12:31:25</span> </div> </div> </div></li><li><div class="jz-ask-loop"> <div class="left"> <div class="data"> <span>2</span> <p>回答</p> </div> <div class="data"> <span>20</span> <p>浏览</p> </div> </div> <div class="right"> <h3><a href="https://www.jztheme.com/ask/framework/24511.html"><em>Vue</em> Router动态<em>路由</em>跳转后组件不更新<em>怎么</em>办?</a></h3> <div class="excerpt"><p>在用<em>Vue</em>3+<em>Vue</em> Router做动态<em>路由</em>时遇到个<em>问题</em>,当通过router.push('/user/'+id)跳转同一路径不同参数的页面,组件内容没重新渲染。试过在onBeforeMount里请求数...</p></div> <div class="info"> <div class="author"><img alt='' src='//style.jztheme.com/images/avatar/avatar3385.jpg' class='avatar avatar-20' data-id='23784' height='20' width='20' /><a href="https://www.jztheme.com/author/23784">UP主~志敏</a></div> <a href="https://www.jztheme.com/ask/framework" class="category"><i class="ceofont ceoicon-hashtag"></i>框架</a> <span>2026-02-13 21:58:24</span> </div> </div> </div></li><li><div class="jz-ask-loop"> <div class="left"> <div class="data"> <span>2</span> <p>回答</p> </div> <div class="data"> <span>27</span> <p>浏览</p> </div> </div> <div class="right"> <h3><a href="https://www.jztheme.com/ask/front-end/24391.html"><em>Vue</em>3<em>路由</em>面包屑<em>怎么</em>动态显示父级路径?</a></h3> <div class="excerpt"><p>我在用<em>Vue</em>3+<em>Vue</em> Router做面包屑导航时遇到了<em>问题</em>。项目是嵌套<em>路由</em>结构,比如访问/articles/123时,面包屑应该显示「首页 > 文章列表 > 文章详情」,但实际只显示了当...</p></div> <div class="info"> <div class="author"><img alt='' src='//style.jztheme.com/images/avatar/avatar3250.jpg' class='avatar avatar-20' data-id='33847' height='20' width='20' /><a href="https://www.jztheme.com/author/33847">UI爱菊</a></div> <a href="https://www.jztheme.com/ask/front-end" class="category"><i class="ceofont ceoicon-hashtag"></i>前端</a> <span>2026-02-13 15:49:30</span> </div> </div> </div></li><li><div class="jz-ask-loop"> <div class="left"> <div class="data"> <span>1</span> <p>回答</p> </div> <div class="data"> <span>28</span> <p>浏览</p> </div> </div> <div class="right"> <h3><a href="https://www.jztheme.com/ask/front-end/27743.html">微<em>前端</em>子应用卸载时组件没销毁,<em>怎么</em><em>解决</em>?</a></h3> <div class="excerpt"><p>我在用 qiankun 搭建微<em>前端</em>项目,主应用加载 <em>Vue</em> 子应用没<em>问题</em>,但切换<em>路由</em>卸载子应用时,发现子应用的组件没有被销毁,生命周期钩子 beforeDestroy 也没触发。是不是我哪里没配对? ...</p></div> <div class="info"> <div class="author"><img alt='' src='//style.jztheme.com/images/avatar/avatar4428.jpg' class='avatar avatar-20' data-id='24827' height='20' width='20' /><a href="https://www.jztheme.com/author/24827">兴敏 Dev</a></div> <a href="https://www.jztheme.com/ask/front-end" class="category"><i class="ceofont ceoicon-hashtag"></i>前端</a> <span>2026-02-25 13:31:22</span> </div> </div> </div></li><li><div class="jz-ask-loop"> <div class="left"> <div class="data"> <span>2</span> <p>回答</p> </div> <div class="data"> <span>11</span> <p>浏览</p> </div> </div> <div class="right"> <h3><a href="https://www.jztheme.com/ask/front-end/27408.html"><em>Vue</em> Router 的<em>路由</em>元信息<em>怎么</em>在组件里获取不到?</a></h3> <div class="excerpt"><p>我在用 <em>Vue</em> 3 + <em>Vue</em> Router 4,想通过<em>路由</em>的 meta 字段传点权限信息,但在组件里用 $route.meta 却是空的,明明<em>路由</em>配置里写了啊。 我试过在 setup 里用 useR...</p></div> <div class="info"> <div class="author"><img alt='' src='//style.jztheme.com/images/avatar/avatar1251.jpg' class='avatar avatar-20' data-id='16551' height='20' width='20' /><a href="https://www.jztheme.com/author/16551">玉翠 Dev</a></div> <a href="https://www.jztheme.com/ask/front-end" class="category"><i class="ceofont ceoicon-hashtag"></i>前端</a> <span>2026-02-24 18:16:19</span> </div> </div> </div></li><li><div class="jz-ask-loop"> <div class="left"> <div class="data"> <span>1</span> <p>回答</p> </div> <div class="data"> <span>47</span> <p>浏览</p> </div> </div> <div class="right"> <h3><a href="https://www.jztheme.com/ask/front-end/25990.html"><em>Vue</em> Router鉴权时动态组件提前渲染<em>怎么</em>办?</a></h3> <div class="excerpt"><p>大家好,我在用<em>Vue</em>3 + <em>Vue</em> Router做<em>路由</em>鉴权时遇到个<em>问题</em>:当使用动态导入组件和beforeEach守卫检查token时,未登录用户还是能短暂看到页面内容再跳转登录页。比如访问/dashb...</p></div> <div class="info"> <div class="author"><img alt='' src='//style.jztheme.com/images/avatar/avatar897.jpg' class='avatar avatar-20' data-id='11098' height='20' width='20' /><a href="https://www.jztheme.com/author/11098">❤雨涵</a></div> <a href="https://www.jztheme.com/ask/front-end" class="category"><i class="ceofont ceoicon-hashtag"></i>前端</a> <span>2026-02-17 18:49:26</span> </div> </div> </div></li><li><div class="jz-ask-loop"> <div class="left"> <div class="data"> <span>2</span> <p>回答</p> </div> <div class="data"> <span>37</span> <p>浏览</p> </div> </div> <div class="right"> <h3><a href="https://www.jztheme.com/ask/interaction/25407.html"><em>Vue</em>表单提交时创建和更新逻辑<em>怎么</em>区分?</a></h3> <div class="excerpt"><p>在用<em>Vue</em>做CRUD时遇到了<em>问题</em>,同一个表单既用来创建新数据又用来更新现有数据。但提交时无论<em>怎么</em>改,更新操作总是触发创建接口。 我尝试在data里用isEditing标记状态,然后根据这个值切换表单标...</p></div> <div class="info"> <div class="author"><img alt='' src='//style.jztheme.com/images/avatar/avatar4690.jpg' class='avatar avatar-20' data-id='4693' height='20' width='20' /><a href="https://www.jztheme.com/author/4693">Des.克样</a></div> <a href="https://www.jztheme.com/ask/interaction" class="category"><i class="ceofont ceoicon-hashtag"></i>交互</a> <span>2026-02-16 12:27:29</span> </div> </div> </div></li><li><div class="jz-ask-loop"> <div class="left"> <div class="data"> <span>2</span> <p>回答</p> </div> <div class="data"> <span>44</span> <p>浏览</p> </div> </div> <div class="right"> <h3><a href="https://www.jztheme.com/ask/optimize/24374.html">HTTPS配置后<em>SEO</em>工具提示存在混合内容错误<em>怎么</em>办?</a></h3> <div class="excerpt"><p>最近给网站配置了HTTPS,但<em>SEO</em>检测工具总提示存在混合内容错误。我已经检查过所有资源链接了,但<em>问题</em>还是没<em>解决</em>: .header-logo { background: url(http://exam...</p></div> <div class="info"> <div class="author"><img alt='' src='//style.jztheme.com/images/avatar/avatar1882.jpg' class='avatar avatar-20' data-id='27380' height='20' width='20' /><a href="https://www.jztheme.com/author/27380">轩辕爱红</a></div> <a href="https://www.jztheme.com/ask/optimize" class="category"><i class="ceofont ceoicon-hashtag"></i>优化</a> <span>2026-02-13 14:44:28</span> </div> </div> </div></li><li><div class="jz-ask-loop"> <div class="left"> <div class="data"> <span>2</span> <p>回答</p> </div> <div class="data"> <span>19</span> <p>浏览</p> </div> </div> <div class="right"> <h3><a href="https://www.jztheme.com/ask/front-end/22979.html">微<em>前端</em>中多个<em>Vue</em>子应用如何安全共享<em>Vue</em>x状态而不冲突?</a></h3> <div class="excerpt"><p>我在用Single-SPA搭建微<em>前端</em>时遇到<em>问题</em>:有两个<em>Vue</em>子应用需要共享用户登录状态,尝试在父应用通过<em>Vue</em>x持久化存储,但发现状态会被另一个子应用覆盖,这是为什么呢? 我在父应用store.js设...</p></div> <div class="info"> <div class="author"><img alt='' src='//style.jztheme.com/images/avatar/avatar4599.jpg' class='avatar avatar-20' data-id='9701' height='20' width='20' /><a href="https://www.jztheme.com/author/9701">百里毓琳</a></div> <a href="https://www.jztheme.com/ask/front-end" class="category"><i class="ceofont ceoicon-hashtag"></i>前端</a> <span>2026-02-10 16:54:24</span> </div> </div> </div></li><li><div class="jz-ask-loop"> <div class="left"> <div class="data"> <span>2</span> <p>回答</p> </div> <div class="data"> <span>19</span> <p>浏览</p> </div> </div> <div class="right"> <h3><a href="https://www.jztheme.com/ask/framework/22738.html">微<em>前端</em>应用隔离时,两个子应用的<em>Vue</em>实例为什么会共享同一个$root?</a></h3> <div class="excerpt"><p>我在用single-spa搭建微<em>前端</em>时遇到奇怪<em>问题</em>,两个子应用都用了<em>Vue</em>3,但它们的组件通过getCurrentInstance()获取到的$root竟然是同一个实例! 场景是这样的:主应用注册了两...</p></div> <div class="info"> <div class="author"><img alt='' src='//style.jztheme.com/images/avatar/avatar1790.jpg' class='avatar avatar-20' data-id='1793' height='20' width='20' /><a href="https://www.jztheme.com/author/1793">Good“智越</a></div> <a href="https://www.jztheme.com/ask/framework" class="category"><i class="ceofont ceoicon-hashtag"></i>框架</a> <span>2026-02-10 05:05:25</span> </div> </div> </div></li> </ul> </div> </div> </div> <footer class="uk-footer uk-background-default"> Copyright © 2026 JZTHEME All rights reserved<a href="https://www.jztheme.com/sitemap.xml" target="_blank">网站地图</a><a href="https://beian.miit.gov.cn/" target="_blank" rel="noreferrer nofollow">桂ICP备2022001918号-9</a> </footer> </article> <aside class="uk-width-1-1 uk-width-1-5@s"> <div class="jz-ask-sidebar" uk-sticky="end: !.jz-ask-single-default; offset: 100"> <div class="images uk-background-default"> <a href="https://www.jztheme.com/ask/front-end/27471.html" class="uk-cover-container"> <img src="https://style.jztheme.com/images/2026/02/jztheme_image_27471.png" alt="Vue前端路由怎么解决SEO问题?" uk-cover> </a> </div> <div class="article-author uk-background-default"> <div class="author"> <img alt='' src='//style.jztheme.com/images/avatar/avatar422.jpg' class='avatar avatar-60' data-id='10623' height='60' width='60' /> <div class="info"> <a href="https://www.jztheme.com/author/10623" class="name">司空思捷<span class="level">Lv1</span></a> <div class="extra"> <span uk-tooltip="title:前端设计师; pos: bottom" tabindex="0">职业</span> </div> </div> </div> <div class="data"> <span><em>1</em>问题</span> <span><em>2445</em>人气</span> <span><em>1379</em>粉丝</span> <span><em>76</em>关注</span> </div> <div class="description"> 我只要你陪着我只对我笑,我只要你吻我一个,只逗我一人,我就是不放弃。 </div> <div class="interaction"> <button type="button" class="uk-follow-btn uk-button btn-primary" data-user="10623"><i class="ceofont ceoicon-add-line"></i>关注</button><button type="button" class="uk-message-btn uk-button" data-user="10623"><i class="ceofont ceoicon-mail-send-line"></i>私信</button> </div> <div class="recent"> <div class="title">Ta的问题</div> <ul> <li> <a href="https://www.jztheme.com/ask/front-end/27471.html" title="Vue前端路由怎么解决SEO问题?" class="uk-text-truncate">Vue前端路由怎么解决SEO问题?</a> <span>16 阅读</span> </li> </ul> </div> </div> <div class="latest-ask uk-background-default"> <div class="title">最新问题</div> <ul> <li> <a href="https://www.jztheme.com/ask/framework/30078.html" title="useEffect 为什么在组件首次渲染时就执行了?" class="uk-text-truncate">useEffect 为什么在组件首次渲染时就执行了?</a> <span>1 阅读</span> </li> <li> <a href="https://www.jztheme.com/ask/tool/30071.html" title="Vite 中如何正确处理 CSS 的 @import 路径问题?" class="uk-text-truncate">Vite 中如何正确处理 CSS 的 @import 路径问题?</a> <span>1 阅读</span> </li> <li> <a href="https://www.jztheme.com/ask/app/30068.html" title="刘海屏下页面内容被遮挡怎么解决?" class="uk-text-truncate">刘海屏下页面内容被遮挡怎么解决?</a> <span>1 阅读</span> </li> <li> <a href="https://www.jztheme.com/ask/app/30066.html" title="云测试平台怎么解决真机兼容性问题?" class="uk-text-truncate">云测试平台怎么解决真机兼容性问题?</a> <span>3 阅读</span> </li> <li> <a href="https://www.jztheme.com/ask/front-end/30063.html" title="Turbopack 为什么无法正确处理我的 HTML 入口文件?" class="uk-text-truncate">Turbopack 为什么无法正确处理我的 HTML 入口文件?</a> <span>2 阅读</span> </li> <li> <a href="https://www.jztheme.com/ask/component/30060.html" title="Ant Design Upload上传后怎么拿到文件的base64编码?" class="uk-text-truncate">Ant Design Upload上传后怎么拿到文件的base64编码?</a> <span>2 阅读</span> </li> <li> <a href="https://www.jztheme.com/ask/interaction/30056.html" title="PixiJS里怎么让精灵平滑移动到指定位置?" class="uk-text-truncate">PixiJS里怎么让精灵平滑移动到指定位置?</a> <span>1 阅读</span> </li> <li> <a href="https://www.jztheme.com/ask/front-end/30053.html" title="为什么 :before 伪元素在 JS 动态添加的元素上不生效?" class="uk-text-truncate">为什么 :before 伪元素在 JS 动态添加的元素上不生效?</a> <span>2 阅读</span> </li> <li> <a href="https://www.jztheme.com/ask/tool/30050.html" title="VSCode Remote连接后React组件不热更新怎么办?" class="uk-text-truncate">VSCode Remote连接后React组件不热更新怎么办?</a> <span>1 阅读</span> </li> <li> <a href="https://www.jztheme.com/ask/component/30048.html" title="断点监听在组件里为啥不生效?" class="uk-text-truncate">断点监听在组件里为啥不生效?</a> <span>2 阅读</span> </li> </ul> </div> </div> </aside> </div> </main> <!--手机菜单--> <div class="uk-app-cat"> <ul> <li><a href="https://www.jztheme.com"><i class="ceofont ceoicon-home-smile-line"></i>首页</a></li> <li> <button class="uk-button" type="button"><i class="ceofont ceoicon-apps-line"></i>菜单</button> <div class="list" uk-drop="mode: click;pos: bottom-center"> <div class="title">问答菜单</div> <ul> <li><a href="https://www.jztheme.com/ask">全部</a></li> <li><a href="https://www.jztheme.com/ask/front-end">前端</a></li> <li><a href="https://www.jztheme.com/ask/framework">框架</a></li> <li><a href="https://www.jztheme.com/ask/component">组件</a></li> <li><a href="https://www.jztheme.com/ask/optimize">优化</a></li> <li><a href="https://www.jztheme.com/ask/interaction">交互</a></li> <li><a href="https://www.jztheme.com/ask/tool">工具</a></li> <li><a href="https://www.jztheme.com/ask/app">移动</a></li> <li><a href="https://www.jztheme.com/ask/safety">安全</a></li> <li><a href="https://www.jztheme.com/ask/follow">关注</a></li> </ul> </div> </li> <li><a href="#navbar-login" uk-toggle><i class="ceofont ceoicon-user-6-line"></i>我的</a></li> </ul> </div></div> <div id="navbar-login" class="uk-flex-top" uk-modal> <div class="uk-navbar-login uk-modal-dialog uk-margin-auto-vertical"> <div class="top"> <button class="uk-modal-close-default uk-modal-close" type="button" uk-close><i class="ceofont ceoicon-close-line"></i></button> <div class="title"> <a href="https://www.jztheme.com" alt="JZTHEME"> <img src="/logo.png" alt="JZTHEME" /> </a> <p>Hi~欢迎来到 JZTHEME 即刻开启你的创意之旅</p> </div> <form action="" method="POST" id="login-form" class="form login-weixin"> <div class="uk-inline uk-width-1-1 uk-margin-small-bottom"> <span class="uk-form-icon"><i class="ceofont ceoicon-smartphone-line"></i></span> <input class="uk-input" type="text" name="user_mobile" id="user_mobile" placeholder="请输入手机号" required="required"> </div> <div class="uk-inline uk-width-1-1"> <div class="uk-grid-10" uk-grid> <div class="uk-width-3-5"> <span class="uk-form-icon"><i class="ceofont ceoicon-newspaper-line"></i></span> <input class="uk-input" type="text" name="captcha" id="captcha" placeholder="请输入验证码" value=""> </div> <div class="uk-width-2-5"> <script>var is_sms_login=true</script> <button class="send_captcha_mobile mid dark uk-button" type="button" data-smstype="login" data-nonce="0fa0d78f12">获取验证码</button> </div> </div> </div> <div class="jztheme-tips uk-margin uk-text-danger"></div> <input type="hidden" name="action" value="zongcai_login_sms"> <button class="login-button mid dark uk-button">立即登录</button> </form> <div class="social"> <span>更多登录方式</span> <div class="type"> <a href="javascript:;" class="mid qq half qq_login_button ceo_qq_login" uk-tooltip="QQ登录"><i class="ceofont ceoicon-qq-fill"></i>QQ登录</a> <a href="https://www.jztheme.com/oauth/mpweixin" class="mpweixin_login_button mid weixin half" uk-tooltip="关注微信公众号登录"><i class="ceofont ceoicon-wechat-fill"></i>微信登录</a> </div> </div> </div> <div class="bottom"> <div class="info"> 注册登录即表示同意 《<a href="/about/terms" target="_blank">服务条款</a>》 和 《<a href="/about/agreement" target="_blank">隐私协议</a>》 </div> </div> </div> </div> <script> function is_in_weixin() { return "micromessenger" == navigator.userAgent.toLowerCase().match(/MicroMessenger/i) } $(".login-form .mpweixin_login_button,.login-form .mpweixin_login_button").on("click", function(e) { setTimeout(function (){ UIkit.modal('#navbar-login').show(); },500) }); $(document).on("click", ".mpweixin_login_button", function(e) { e.preventDefault(); var t = $(this) , a = t.html(); if (is_in_weixin()) return window.location.href = t.attr("href"), !0; $.post(jztheme.ajaxurl, { action: "get_mpweixin_qr" }, function(e) { if (1 == e.status) { $("#navbar-login").find('form').html('<img class="login-weixin-img" src="' + e.ticket_img + '"><p class="login-weixin-p">请使用微信扫码关注登录</p>'); $("#navbar-register").find('form').html('<img class="login-weixin-img" src="' + e.ticket_img + '"><p class="login-weixin-p">请使用微信扫码关注登录</p>'); var n = setInterval(function() { $.post(jztheme.ajaxurl, { action: "check_mpweixin_qr", scene_id: e.scene_id }, function(e) { 1 == e.status && (clearInterval(n), UIkit.notification('扫码成功,即将登录', { status: 'success' }), window.location.reload()) }) }, 5e3) } else alert(e.ticket_img); t.html(a) }) }); </script> <script>var verify_sms_send = 0</script> <script>var verify_jz_login = 0</script> <!-- 移动端加载效果 --> <div class="jz-page-loader" id="jz-page-loader"> <div class="loader-content"> <div class="uk-effect-loader"> <span class="bar"></span> <span class="bar"></span> <span class="bar"></span> </div> </div> </div> <div class="jz-follow"> <a href="javascript:void(0);" class="jz-return" id="jz-return-btn"> <i class="ceofont ceoicon-arrow-go-back-line"></i> </a> <a href="#header" class="jz-upward" uk-scroll> <i class="ceofont ceoicon-download-line"></i> </a> </div> <div id="uk-app-navbar" uk-offcanvas="overlay: true"> <div class="uk-offcanvas-bar"> <div class="uk-app-nav"> <button class="uk-offcanvas-close" type="button" uk-close></button> <div class="nav"> <div class="top"> <div class="logo"> <a href="https://www.jztheme.com"> <img src="https://www.jztheme.com/logo.png" alt="JZTHEME"> </a> </div> <div class="search"> <form method="get" class="uk-form jz-search-form" action="https://www.jztheme.com"> <div class="search-type"> <input type="hidden" name="search_type" id="search_type" value="elements"> <div class="selected-type" id="selected_type"> <span class="type-text">元素</span> <i class="ceofont ceoicon-arrow-down-s-line"></i> </div> <div class="type-dropdown" id="type_dropdown"> <div class="type-option" data-type="elements" data-text="元素">元素</div> <div class="type-option" data-type="tools" data-text="工具">工具</div> <div class="type-option" data-type="blog" data-text="博客">博客</div> <div class="type-option" data-type="ask" data-text="问答">问答</div> </div> </div> <input type="search" placeholder="输入关键字搜索" autocomplete="off" value="" name="s" required="required" class="uk-input"> <button class="uk-button" type="submit"><i class="ceofont ceoicon-search-2-line"></i></button> </form> </div> <ul> <li><a href="https://www.jztheme.com"><i class="ceofont ceoicon-home-smile-line"></i>首页</a></li> <li><a href="https://www.jztheme.com/elements"><i class="ceofont ceoicon-code-box-line"></i>元素</a></li> <li><a href="https://www.jztheme.com/css"><i class="ceofont ceoicon-css3-line"></i>CSS生成器</a></li> <li><a href="https://www.jztheme.com/tools"><i class="ceofont ceoicon-tools-line"></i>工具</a></li> <li><a href="https://www.jztheme.com/blog"><i class="ceofont ceoicon-pages-line"></i>博客</a></li> <li><a href="https://www.jztheme.com/ask"><i class="ceofont ceoicon-questionnaire-line"></i>问答</a></li> <li><a href="https://www.jztheme.com/note"><i class="ceofont ceoicon-chat-1-line"></i>笔记</a></li> </ul> </div> <div class="bottom"> <a href="#navbar-login" uk-toggle>登录/注册</a> </div> </div> </div> </div> </div> <script type="speculationrules"> {"prefetch":[{"source":"document","where":{"and":[{"href_matches":"/*"},{"not":{"href_matches":["/wp-*.php","/wp-admin/*","/images/*","/wp-content/*","/wp-content/plugins/*","/wp-content/themes/jztheme/*","/*\\?(.+)"]}},{"not":{"selector_matches":"a[rel~=\"nofollow\"]"}},{"not":{"selector_matches":".no-prefetch, .no-prefetch a"}}]},"eagerness":"conservative"}]} </script> <script>var jz_like_nonce = "7c2bcaf5c8";</script><script type="text/javascript" src="https://www.jztheme.com/wp-content/plugins/Pure-Highlightjs/assets/pure-highlight.js" id="pure-highlightjs-js"></script> <script type="text/javascript" src="https://www.jztheme.com/wp-content/plugins/Pure-Highlightjs/highlight/prism.js" id="Prism-js-js"></script> <script type="text/javascript" id="ajax-js-extra"> /* <![CDATA[ */ var jztheme = {"ajaxurl":"https://www.jztheme.com/wp-admin/admin-ajax.php"}; var jz_feedback_ajax = {"nonce":"ae59c143b1"}; var jz_poster_ajax = {"nonce":"57cfe53058","post_id":"27471"}; var _jz_js = {"ajaxurl":"https://www.jztheme.com/wp-admin/admin-ajax.php","theme_url":"https://www.jztheme.com/wp-content/themes/jztheme","login_url":"/user/login","register_url":"/user/register","message_url":"https://www.jztheme.com/user/message","followed_btn":"\u5df2\u5173\u6ce8","follow_btn":"\u5173\u6ce8","webp":"","is_user_logged_in":"","current_user_id":"0","load_more_author_content_nonce":"ad38a80200"}; var _jz_js = {"ajaxurl":"https://www.jztheme.com/wp-admin/admin-ajax.php","theme_url":"https://www.jztheme.com/wp-content/themes/jztheme","login_url":"/user/login","register_url":"/user/register","message_url":"https://www.jztheme.com/user/message","followed_btn":"\u5df2\u5173\u6ce8","follow_btn":"\u5173\u6ce8","webp":"","is_user_logged_in":"","current_user_id":"0","comment_reply_nonce":"895f624faa","comment_like_nonce":"465582994c"}; //# sourceURL=ajax-js-extra /* ]]> */ </script> <script type="text/javascript" src="https://www.jztheme.com/wp-content/themes/jztheme/static/js/ajax.js" id="ajax-js"></script> <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/tinymce@6.8.2/tinymce.min.js" id="tinymce-js"></script> <script type="text/javascript" src="https://www.jztheme.com/wp-content/themes/jztheme/static/js/ask-answer.js" id="ask-answer-js"></script> <script type="text/javascript" src="https://www.jztheme.com/wp-content/themes/jztheme/static/js/interaction.js" id="interaction-js"></script> <script> console.log("71/0.70344"); </script> <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https'){ bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body> </html> <!-- Performance optimized by Redis Object Cache. Learn more: https://wprediscache.com -->