陈塘庄做网站公司,软件外包多少钱,建设网站需要的ftp资源,wordpress 图片自动下载文件Vue2Nuxt2 从 0 到1 搭建官网~ Vue3Nuxt3 从0到1搭建官网项目 安装 Nuxt3#xff0c;创建项目初始化的 package.json项目结构初始化项目pages 文件下创建index.vue引入sass修改 app.vue 文件查看效果 配置公共的css、metaassets下的cssreset.scss 重置文件common.scss 配置nux…Vue2Nuxt2 从 0 到1 搭建官网~ Vue3Nuxt3 从0到1搭建官网项目 安装 Nuxt3创建项目初始化的 package.json项目结构初始化项目pages 文件下创建index.vue引入sass修改 app.vue 文件查看效果 配置公共的css、metaassets下的cssreset.scss 重置文件common.scss 配置nuxt.config.ts现在的package.json查看效果 创建新页面pages目录结构components 创建组件Header 组件Footer 组件引入组件组件效果 多语音系统引入i18n新建lang文件夹入口文件index.js 中英js文件 对比合并后的JSON图 i18n.config.tsnuxt.config.ts修改index.vue 文件 查看效果中文效果英文效果 动态切换语言 想开发一个官网并且支持SEO搜索当然离不开我们的 Nuxt Nuxt2 我们刚刚可以熟练运用现在有出现了Nuxt3那通过本篇文章让我们一起了解一下。
安装 Nuxt3创建项目
安装nuxt3 需要node v18.10.0以上大家记得查看自己的node版本。
升级node可以参考使用nvm 切换不同node版本~
// node v18.10.0
// npx nuxilatest init project-namenpx nuxilatest init nuxt3-democd nuxt3-demo
初始化的 package.json
这是项目刚创建后的package.json文件
{name: nuxt3-demo,private: true,type: module,scripts: {dev: nuxt dev,build: nuxt build,generate: nuxt generate,preview: nuxt preview,postinstall: nuxt prepare},dependencies: {nuxt: 3.8.2,vue: 3.3.10,vue-router: 4.2.5}
}
项目结构
├── app.vue // 主文件
├── assets // 静态资源
├── components // 公共vue组件
├── composables // 将你的Vue组合式函数自动导入到你的应用程序中
├── error.vue // 路由匹配不到时
├── i18n.config.ts // 语言切换配置文件
├── lang // 语言JSON
├── nuxt.config.ts // nuxt 配置文件
├── package.json
├── pages // pages文件夹下面的页面名默认为 路由地址
├── plugins // 公共插件
├── public // 提供网站的静态资源
├── server
├── tsconfig.json
└── yarn.lock // 包含了应用程序的所有依赖项和脚本初始化项目
我们首先创建一个首页将项目运行起来这样一会儿讲到SEO、语音切换时方便查看效果
pages 文件下创建index.vue
templatediv classhome-wrapNuxt3--这是我们的首页/div
/templatescript
export default {}
/scriptstyle langscss scoped
.home-wrap{height: 500px;display: flex;justify-content: center;align-items: center;font-size: 50px;
}
/style我们发现页面出现如下错误提示我们需要引入 sass )
引入sass
// 如果下载失败。记得比对package.json 中依赖的版本号
// node_modules 和 yarn.lock 记得也删除一下
yarn add string-width7.1.0 sass1.69.5 sass-loader13.3.2 --save修改 app.vue 文件
templatedivNuxtPage //div
/template
查看效果 配置公共的css、meta
在我们的项目中UI风格肯定是有规范统一的因此我们可以将 css 重置文件、公共的css文件以及Meta提前引入
assets下的css
在assets 文件夹下我们可以创建css样式、img图片、fonts字体库等文件夹
reset.scss 重置文件
因为UI主体区域为1200px因此body 我们设置了最大宽度是1350px这样主体区域两侧有一点占位空间使内容不至于紧贴设备边界
/* CSS reset */
// /assets/css/reset.scsshtml,body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td {margin:0;padding:0;
}body{font-family:思源黑体,Microsoft YaHei,微软雅黑,Arial,sans-serif;font-size: 14px;color: #333;min-width: 1350px;
}
*{-webkit-text-size-adjust: none;
}
*,*:after,*:before{box-sizing:border-box;margin: 0;padding:0;
}
table {border-collapse:separate;border-spacing:0;
}
fieldset,img {border:0;
}
img{display: block;-webkit-user-drag: none;
}
img[src],img:not([src]){opacity: 0;border:none;visibility: hidden;max-width: none;
}
address,caption,cite,code,dfn,th,var {font-style:normal;font-weight:normal;
}
ol,ul ,li{list-style:none;
}
caption,th {text-align:left;
}
h1,h2,h3,h4,h5,h6 {font-size:100%;font-weight:normal;
}
abbr,acronym { border:0;
}
a{text-decoration:none;
}/* 解决兼容而加的样式 */
a, img {-webkit-touch-callout: none; /*禁止长按链接与图片弹出菜单*/}
a,button,input{-webkit-tap-highlight-color:rgba(255,0,0,0);}
img{display: block;
}
button,input,optgroup,select,textarea {outline:none;/*-webkit-appearance:none; /*去掉webkit默认的表单样式*/}a,button,input,optgroup,select,textarea {-webkit-tap-highlight-color:rgba(0,0,0,0); /*去掉a、input和button点击时的蓝色外边框和灰色半透明背景*/
}input:-ms-input-placeholder{color:#b3b7c0;}
input::-webkit-input-placeholder{color:#b3b7c0;}
input:-moz-placeholder{color:#b3b7c0;}
input::-moz-placeholder{color:#b3b7c0;}
common.scss
/* CSS common */
// 这里大家可以写一些公共的css样式我这里主要是举例
// /assets/css/common.scss.g-border{position: relative;}
.g-border1{position: relative;}
.g-border:after{content:;position: absolute;bottom:0;width:100%;height:1px;background:#e8e8e8;overflow: hidden;left:0;transform:translate(0%,0) scale(1,0.5);}
.g-border1::before{content:;position: absolute;top:0;width:100%;height:1px;background:#e8e8e8;overflow: hidden;left:0;transform:translate(0%,0) scale(1,0.5);}.g-border-on::before,.g-border-on:after{background: #dcdcdc!important;
}.g-text-ove2{display: -webkit-box;-webkit-box-orient: vertical; -webkit-line-clamp: 2;overflow: hidden;}
.g-text-ove1{overflow: hidden;text-overflow:ellipsis;white-space: nowrap;}
配置nuxt.config.ts
// 熟悉我的小伙伴可能注意到我非常喜欢在项目中使用 address哈哈哈
yarn add address2.0.1 --save// https://nuxt.com/docs/api/configuration/nuxt-config
const address require(address)
const localhost address.ip() || localhostexport default defineNuxtConfig({ssr:true,app:{head: {meta: [{ charset: utf-8 },{ name: viewport, content: widthdevice-width, initial-scale1 },{ hid: viewport, name: viewport, content:width1350, user-scalableno,viewport-fitcover},{ hid: description, name: description, content: CSDN 作者拿回忆下酒介绍Vue3Nuxt3 从0到1搭建官网项目SEO搜索、中英文切换、图片懒加载的dome },{ hid: keywords, name: keywords, content: Vue3Nuxt3CSDN 拿回忆下酒 },{ name: format-detection, content: telephoneno }],link:[{rel:icon,type:image/x-icon,href:/favicon.ico}]},},css: [/assets/css/reset.scss,// 公共class/assets/css/common.scss],devtools: { enabled: true,ssr:false},devServer:{host: localhost,port:8303}
})
现在的package.json
防止小伙伴下错版本号咱们确定一下 现在的依赖包的版本号
大家也可以复制一下内容将node_modules 和 yarn.lock 删除重新执行 yarn install
{name: nuxt3-demo,private: true,type: module,scripts: {dev: nuxt dev --open,build: nuxt build,generate: nuxt generate,preview: nuxt preview,postinstall: nuxt prepare},dependencies: {nuxt/devtools: latest,nuxtjs/i18n: 8.0.0,address: 2.0.1,nuxt: 3.8.2,sass: 1.69.5,sass-loader: 13.3.2,string-width: 7.1.0,vue: 3.3.10,vue-router: 4.2.5}
}
查看效果
我们可以看到 IP、端口、meta、css 已经都改变了
创建新页面
创建新页面演示目录结构、路由跳转、多页面TDK配置等等
pages目录结构
我们在pages文件夹下新建 首页(index)、关于我们(about)、订单(product/order)、管家(product/steward)等页面用来演示 目录结构 和 路由 的 对应关系
// pages 目录结构├── nuxt.config.ts
├── package.json
├── pages
│ ├── abouut.vue
│ ├── index.vue
│ └── product
│ ├── order.vue
│ └── steward.vue
components 创建组件
components/ 目录是你放置所有 Vue 组件的地方。我们可以把公共组件放到这里
Header 组件
templatesection classc-head-wrap div classcontent-boxdiv classhead-boxsection classmain g-width-box g-cen-ydiv classlogo-box 演示logo!-- img classimg src/assets/img/logo-top.png / --/divdiv classnav-btn-box div classg-disdivv-for(m, i) in navArr:keyiclassbtnrefbtnIdclickrouterFn(m):class[isPageFn(m,i)]h6{{ m.name }}/h6div v-showm.children classchildren-boxdiv classitem v-for(n,ind) in m.children :keyi-ind click.stoprouterFn(n){{ n.name }}/div/div/div/divdiv classborder :styleisStyle/div/div/section/div/div/section
/template
script setup
import { ref } from vue;
const router useRouter()
const route useRoute()const navArr ref([{ path: /,name:首页 },{ path: /product, name:产品业务,children:[{ path: /product/order, name:订单},{ path: /product/steward, name:管家}]},{ path: /about, name:关于我们 }
]);let btnId ref(null)
let isStyle ref()const routerFn (e) {if(e.children) return router.push(e.path)
};const isPageFn (e,ind){let async falseif(route.path e.path){async true} else if(e.children){async !!e.children.filter(m m.path route.path).length}return async ? on:
}/script
style langscss scoped
.c-head-wrap{min-width: 1350px;position: absolute;left: 0;width: 100%;z-index: 22;
}.content-box{width: 100%;height: 70px;background: transparent;border-bottom: 1px solid #E0E4E8;
}
.main{height: 70px;
}
.logo-box{height: 100%;display: flex;align-items: center;margin-right: 102px;font-size: 20px;font-weight: 500;
}
.nav-btn-box{flex: 1;position: relative;.border{width: 72px;height: 2px;background: #0044FF;position: absolute;bottom: 0;transition: left 0.28s;opacity: 0;}.btn{font-weight: 500;font-size: 18px;color: #4F587F;line-height: 70px;padding: 0 18px;cursor: pointer;position: relative;font-weight: 400;z-index: 2;.on{color: #0044FF;position: relative;}:hover{.children-box{display: block;}}}
}.children-box{display: none;position: absolute;background-image: linear-gradient(197deg, rgba(246,246,246,1) , rgba(246,246,246,.65));backdrop-filter: blur(5px);box-shadow: 0 20px 40px 0 rgba(74,91,130,.16);border: 2px solid #fff;min-width: 100%;left: 50%;top: 70px;line-height: 50px;text-align: center;white-space: nowrap;transform: translate(-50%,0);font-size: 16px;font-weight: 400;color: #4F587F;z-index: 2;.item{border-bottom: 1px solid #E0E4E8;padding: 0 14px;:last-child{border-bottom: 0;}.on,:hover{color: #0044FF;}}
}/style
Footer 组件
templatediv classfooter-box div classbox g-width-boxdiv classleftdiv classicon演示logo/divdiv classphone咨询电话86-136xxxx8899/divdiv classbtn-box g-cen-yspan版权 © 演示xxxx科技有限公司/spani/ia hrefhttps://beian.miit.gov.cn/ target_blank classbtn京ICP备2010xxxx88号/ai/ia hrefhttps://beian.mps.gov.cn/#/query/webSearch?code1010xxxxx3434 target_blank classbtn sprite-btnimg classsprite srcassets/img/sprite.png/span京公网安备1010xxxxx3434号/span/a/div/divdiv classright/div/div/div
/templatestyle langscss scoped
.footer-box{height: 200px;background: #242933;.box{display: flex;justify-content:space-between;padding-top: 40px;.left{font-size: 14px;.icon{height: 32px;display: block;margin-bottom: 40px;color:#fff;font-size: 30px;}.phone{line-height: 22px;color: #FFFFFF;}.btn-box{line-height: 24px;color:#878FB4 ;i{height: 14px;width: 2px;background: #878FB4 ;margin: 0 10px;}.btn{color:#878FB4 ;font-size: 14px;cursor: pointer;:hover{color: #fff;}}.sprite-btn{display: flex;align-items: center;}.sprite{width: 16px;height: 17px;margin-right: 5px;}}}.right{display: flex;flex-direction:column; align-items: center;.qrcode1{width: 100px;height: 100px;}.txt{line-height: 32px;font-size: 12rpx;color: #E9EDFF;text-align: center;}}}
}
/style引入组件
官网一般header头部、footer底部都是复用的因此我们在app.vue文件中引用它们
// app.vue
templatedivHeader /NuxtPage /Footer //div
/template
组件效果 多语音系统
现在好多公司的官网都是多语言因此我们一起了解一下 i18n
引入i18n
yarn add nuxtjs/i18n8.0.0 --save新建lang文件夹
这是一个自创建的文件夹用来存放 语言切换 需要用到的数据我们来了解一下它的目录结构
├── nuxt.config.ts
├── i18n.config.ts
├── lang
│ ├── cn
│ │ ├── about.js
│ │ ├── home.js
│ │ ├── index.js // 入口文件
│ │ ├── order.js
│ │ └── steward.js
│ └── en
│ ├── about.js
│ ├── home.js
│ ├── index.js // 入口文件
│ ├── order.js
│ └── steward.js入口文件index.js
index.js 的代码是一致的主要作用是 将同一种语言下的文件合并到一起 我以其中一个为例
// 获取同一目录下 的 js 文件
const files import.meta.globEager(./*.js);const modules Object.keys(files).reduce((prev, cur) { // 获取js 文件的 文件名 并转 大写 这里很重要// 这里 大写的文件名是日后 dom 中日后替换的关键字let key cur.split(/)[1].split(.)[0].toUpperCase()// 将内容合并在一起为了方便理解下面有合并后的JSON图return {...prev,...{[key]:files[cur]?.default}}
}, {});export default {...modules};中英js文件 对比
每个js文件JSON结构都是一致的我们以home、about 为例对比一下
// cn/home.js
export default {b1: {title: 我们的首页,txt: 这是一段尝试json结构可以任意定义只要保持统一规范即可}
}// en/home.js
export default {b1: {title: Our homepage,txt: China\s leading fintech platform for automobiles empowering supply chain ecosystem partners. }
}***********************
// cn/about.js
export default {b1: {title: 关于我们}
}// en/about.js
export default {b1: {title: About Us}
}
合并后的JSON图 i18n.config.ts
import en from ./lang/en/index.js
import cn from ./lang/cn/index.jsexport default defineI18nConfig(() ({legacy: false, // 是否兼容之前fallbackLocale: cn, // 区配不到的语言就用enmessages: {en,cn}
}))
nuxt.config.ts
export default defineNuxtConfig({...modules:[nuxtjs/i18n],i18n: {strategy: prefix_and_default, // 添加路由前缀的方式locales: [en, cn], //配置语种defaultLocale: cn, // 默认语种vueI18n: ./i18n.config.ts, // 通过vueI18n配置},...})
修改index.vue 文件
我们以index.vue 文件为例主要看 $t(HOME.b1.title) 部分HOME 便是当时 lang中的文件名
templatediv classhome-wrapNuxt3--{{ $t(HOME.b1.title) }}/div
/templatescript setup
export default {}
/scriptstyle langscss scoped
.home-wrap{min-height: calc(100vh - 200px);display: flex;justify-content: center;align-items: center;font-size: 50px;
}
/style查看效果
中英文切换主要是通过不同的路由进行区分的大家注意看浏览器URL地址
中文效果 英文效果 动态切换语言
我们虽然实现了语言替换但是官网中并没有实现语言动态切换的功能因此我们需要进一步完善首先我们需要引入pinia
yarn add pinia/nuxt0.5.1 pinia2.0.23 --save文章正在努力完善中。。。。。