现在碰到一个问题, 发布后的 nuxt3 项目, 如果我更新一个.html 文件或者修改了服务器上的 robots.txt, 都不会生效, 必须要在开发环境新增/修改文件,再重新 build 打包更新到服务器才可以, 这样搞好麻烦, 有没有真正意义上的静态文件夹, 类似于.netcore 的 wwwroot 的这种
]]>省流: device 提供了如const { isMobile } = useDevice()
的形式来判断设备类型。但需要注意的是,在nuxt build
模式中使用v-if
以及动态类名(如<div :class="{mobile: isMobile}">
)的形式均可生效,而在nuxt build
和nuxt generate
模式中仅v-if
生效,后者会有问题。
<template> <section> <div v-if="$device.isDesktop">Desktop</div> <div v-else-if="$device.isTablet">Tablet</div> <div v-else>Mobile</div> </section> </template>
dev
模式下都能正常工作<Dialog v-if="!isMobile" .../> <DialogM v-else .../> ... <Card :class="{mobile: isMobile}" .../>
nuxt generate
,发现访问时,使用第二种写法的组件一律采用了手机端的样式(配置项里默认 UA 是手机版的),无视 UA ,这才发现官方文档里并没提第二种写法,但它在dev
模式下确实能正常工作....没办法,现在只能尽力填坑。<Card :class="{mobile: isMobile}" .../>
改为<Card v-if="isMobile" class="mobile" .../> <Card v-else ...>
就行了,写法是有点傻,但也只能这样尽量找补了。自己写的后台接口
页面显示正常的,但是右键, 查看源代码后里面没有请求回来的数据呀!
这能 SEO ?
nuxt.config.ts 代码:
export default defineNuxtConfig({ app: { head: { charset: 'utf-8', viewport: 'width=device-width, initial-scale=1', } }, devtools: {enabled: false}, //关闭遥测数据 telemetry: false, modules: ['@pinia/nuxt'], css: [ "@/assets/style/style.css" //配置使用的样式 ], ssr:true, })
页面代码:
<template> <div id="body"> <div class="container"> <div id="main"> <article class="post" v-if="_length(row)>0"> <h1 class="center">{{row.title}}</h1> <ul class="post-meta"> <li> <time>{{dateDisplay(row.created_at)}}</time> </li> <li><a :href="row.url">默认分类</a> </li> <li><a>{{row.views}}</a> 阅读</li> <li><a href="#comments">评论</a></li> </ul> <div class="post-content" v-html="row.content"></div> <p class="tags">标签: <a v-for="tag in row.tag" :href="getTagUrl(tag)">{{tag}}</a></p> <div class="post-near"> <li class="post-left">没有了</li> <li class="post-right">没有了</li> </div> <div class="clearfix"></div> </article> </div> </div> </div> </template> <script setup lang="ts"> import {onMounted,ref} from "vue"; import {getArticleDetail} from "~/api/article"; import type {ApiResponse,ArticleItem} from "~/types/interface"; import {dateDisplay} from "~/utils/date"; import {_length} from "~/utils"; import { useRoute } from '#app'; const route = useRoute(); const params = route.params; const id = ref(params.id); const loading = ref(false); const row = ref<ArticleItem>(); onMounted(async()=>{ await fetchData(); }) const fetchData = async() =>{ try { loading.value = true; const data:ApiRespOnse= await getArticleDetail({id:id.value}); if(data.code!==0){ return Promise.reject(data.message); } row.value = data.data as ArticleItem; if(_length(row.value.url)===0){ row.value.url = '/archives/'+row.value.slug; } useHead({ title: row.value.title, meta: [ { name: 'description', content: '我的神奇网站。' } ], bodyAttrs: { class: 'test' }, script: [ { innerHTML: 'console.log(\'Hello world\')' } ] }) }catch (e) { loading.value = false; } } </script> <style scoped lang="less"> </style>
]]>项目当前的情况:
nuxt.config.js
内的相关配置为 ssr: false, target: "static", generate: 未配置
npm run generate
,启动命令npm start
。并没有做只拷贝 dist 目录等减少镜像体积的优化,所有文件原封不动塞到镜像里然后部署到 K8s想问一下这种情况下项目跑在何种模式下( ssr,ssg,spa )?
下面是问题发现的过程,有点长:
由于这个项目部署到 K8s 而不是 CDN ,最初我认为采用的是 SSR 模式。当时遇到个情况是每次 CI 在 build 阶段都要针对不同环境( dev,test,prod...)生成多个镜像,差别只是环境变量不同。我想直接利用 runtimeConfig 把这些变量放到 pod 里的话 CI 做一个镜像就够了。但是尝试失败。
后来我看了 nuxtjs 配置文件,意识到我理解错了,项目采用的应该是 SSG 方式,确实看 generate 日志也是生成了每个页面的文件,静态文件的话当然是无法从环境读取变量,只有 build 阶段替换了。
再后来我发现另外一个开发人员使用了 dynamic route(/post/_id 这样的路由,id 是动态变化的,无法在 build 时从数据库获取,而且 generate 也没配,之前已经开发的部分没用过动态路由)。我想 SSG 模式下动态路由会被忽略不生成,我就提醒他说可能页面没法用。但是现实打脸,部署后可以正常访问。
于是我看了访问页面时返回的 html ,发现所有页面都只有一个id="__nuxt"
节点,这种情况应该是 fallback 到 SPA 了吧,感觉是每个页面被单独做成了一个 SPA ?如果是这样的话 generate 就完全是多余的。
那么,npm start
启动 Nuxt 服务器的时候到底是如何处理的?会检查已经 generate 好的文件吗?
具体的叫 Ext.BoxComponent
extjs2.1 版
这样每次点击超链接就会新开一个基于 iframe 的 tab 原页面完全不受影响 也是丝般顺滑
真的 后悔了 因为 vue nuxt 浪费了太多时间
]]>