响应标头信息
- Content-Type 声明内容类型 ‘text/html’ charset=‘utf-8’ 设置编码
模板使用外部数据
- renderToString(app,{
title:‘数据’,
mate:<meta name="description" content="">
}) - 普通数据使用双括号 {{ title }}
- html文件使用三括号 {{{ mate }}}
Webpack配置
- 路径别名
reslove:{ alias:{ //路径 @ 指向src '@':reslove(''../src/') }, //省略扩展名 //按照从前往后的顺序以次解析 extensions:['.js','.vue','.json'] }
- 合并webpack配置信息
const { merge } = require('webpack-merge') const baseConfig = require('./webpack.base.config.js') //另外的webpack配置文件 module.exports = merge(baseConfig,{ ···配置信息 })
构建配置命令
- webpack.json文件中scripts中配置文件
- cross-env 包设置环境
- 多任务队列执行中间 && 例子: npm run build && npm run serve
同构渲染流程
- 服务端渲染
- 客户端请求 => 服务端路由匹配 => 通过renderer.renderToString方法将 Vue实例渲染为html =>通过createBundleRenderer产生 => 加载打包好的服务端Bundle.json文件 => entry 入口文件 => 入口文件中创建的 Vue实例进行渲染 => 加载进html,发送客户端
- 客户端渲染
- 通过createBundleRenderer加载打包好的客户端js文件 => 客户端激活
- 客户端激活
- Vue接管服务端发送的html,变由Vue动态管理的DOM
- data-server-rendered属性时代表HTML由服务端渲染,以激活模式加载
- 开发模式下 Vue推断客户端的虚拟DOM与服务端渲染DOM是否一致,否则退出混合模式重新从头渲染,生产模式下跳过次检测,影像性能
客户端打包好的json文件 publicPath:'' 文件地址 all:[] 客户端打包的资源文件,js文件以及map文件 initial:[] 客户端打包好的js文件、服务端渲染时自动引入 initial中的文件 async:[] 存储异步资源 modules:{ 'hash值':[引用的all中文件index] } 原始文件中每个模块加载的索引文件,hash是模块
HMR实现
- 第三方 chokidar模块监视文件 chokidar封装了 fs.watch和fs.watchFile文件
- require是有缓存的
- webpack-hot-middleware实现热更新
编写通用应用注意事项
- 服务端渲染只有 beforeCreate和created两个生命周期函数
- 避免在beforeCreate和created生命周期函数中使用定时器等代有副作用的代码,写了应该在brofreDestory和destoryed中销毁,服务端没有此生命周期函数,应将副作用代买写到beforeMount和mounted中
配置vueRouter
- vueRouter使用history模式,前后端都兼容,hash模式服务端渲染不兼容
数据预取
- 服务端渲染不支持响应式修改数据,可以通过vuex
- 服务端数据需要与客户端连接同,通过context.state
静态站点生成
Gridsome
- 基于Vue.js的静态网站生成器
静态网站生成器 JAMStack
- 使用一系列配置、模板以及数据,生成静态HTML文件以及相关资源的工具
- 这个功能叫做预渲染
- 生成网站不需要服务器
- 只需要放到支持静态资源的Web Server或者CDN上即可
静态网站优点
- 不需要专业服务器,只需有托管静态文件爱你的空间即可
- 不需要后台服务器的处理,只传输内容
- 没有后端程序的执行更加安全
常见静态网站生成器
- Jeky ( Ruby)
- Hexo ( Node)
- Hugo ( Golang)
- Gatsby ( Node/React)
- Gridsome ( Node/Vue)
- Next.js以及Nuxt.js也能生成静态网站,更多的使用服务端渲染
JAMStack
- JAMSack的JAM是JavaScript、API和Markup的首字母组合
- 本质是一种胖前端,通过调用各种API来实现更多的功能
- 也是一种前后端模式,只不过离得比较开,甚至前后端来自多个厂商
使用场景
- 不适合大量路由页面的应用
- 大量的数据会导致预渲染缓慢
- 不适合有大量动态内容的应用
Gridsome 配置文件
- siteName 网站标题名称
- siteDescription 设置mate属性中的seo搜索值
添加集合
- 通过后台查询的数据通过plugins将数据添加到GraphQL层,然后点击运行后的第三个网站进入GraphQL数据层,点击DOCS通过POST查询单个文章通过allpost查询所有文章
页面中查询GraphQL
- 多个查询在同一个query中写多个查询
- 在Pages以及Templates中使用查询,在Components中使用查询,与tempalte平级
- 同过 $page.名称.名称中
- 在页面中写好查询语句复制到组件中
- 打包时数据会直接打包进对应的静态文件中
- 详情见文档
渲染节点页面
- GraphQL中变量以$开头
id变量类型为ID,!表示不能为空
query($id:ID!){
}
Strapi
封装Vue组件库
CDD
- 自上而下
- 从组件级别开始,到页面级别结束
优点
- 组件在最大程度上被重用
- 并行开发,不同团队之间同时开发
- 可视化测试
处理组件边界情况
- r o o t 通 过 root 通过 root通过root获取vue根实例所存储的共享数据,小型项目中可以使用$root访问根实例,中大型项目推荐vuex
- p a r e n t 可 以 通 过 parent 可以通过 parent可以通过parent改变/获取父组件中的成员,可以替代property,property或取得数据不是响应式,应用复杂不容易维护,多层级维护嵌套深
- c h i l d r e n 是 个 数 组 , 获 取 子 组 件 成 员 , 需 要 索 引 获 取 , 可 读 性 不 高 , 如 果 需 要 获 取 所 有 子 组 件 中 的 成 员 推 荐 , 单 个 推 荐 children 是个数组,获取子组件成员,需要索引获取,可读性不高,如果需要获取所有子组件中的成员推荐,单个推荐 children是个数组,获取子组件成员,需要索引获取,可读性不高,如果需要获取所有子组件中的成员推荐,单个推荐ref
- r e f 如 果 是 普 通 的 h t m l 标 签 ref 如果是普通的html标签 ref如果是普通的html标签refs获取到的是DOM对象,如果是ref是在子组件上$refs获取到的是子组件对象
//子组件 myinput
<template>
<input v-model="value" type="text" ref="txt">
</template>
<script>
this.$refs.txt //获取到的是DOM对象
</script>
//父组件
<template>
<myinput ref="mytxt"></myinput>
</template>
<script>
this.$refs.mytxt //获取到的是子组件对象
</script>
- 依赖注入 provide&inject
- inject注入的值不允许改变,非响应式
- 依赖父组件,组件耦合高,重构困难
//父组件
<script>
export default {
provide(){ //注入数据
return{
title:this.title, //元素
handle:this.handle //方法
}
},
data(){
return{
title:'123456'
}
},
methods:{
handle(){
log(123123)
}
}
}
</script>
//子组件 && 子孙组件
<script>
export default{
//提取数据
inject:['title','handle']
}
</script>
$attrs & $listeners
- $attrs
- 把父组件中非prop属性绑定到内部组件
- 不会改变class和style,会和bong到最外层标签的class和style
- 不想继承父组件除了props外的属性通过inheritAttrs禁用
- 通过 v-bind="$attrs"把非prop属性设置在希望给的标签上
<template> <div> aaa在div上 <input v-bind="$attrs"> </div> </template> <script> export default{ props:['aaa'] inheritAttrs:false //禁用除了props外的属性 } </script>
- $listeners
- 把父组件中的DOM对象的原生事件绑定到内部组件
//父组件 myinput <template> <div> <myinput @focus="onFouns" @input="onIput" ></myinput> </div> <template> <script> export default{ methods{ onFouns(e){ log(e) },, onIput(e){ log(e) } } } </script> //子组件 <template> <div> <input v-on="$listeners"> </div> <template> <script> </script>
- 父组件给子组件传递属性
- 直接传递没有props接受会直接赋给子组件的根标签
- props有了之后要进行绑定,props不能绑定 style和class
快速原型开发
- Vue/cli提供了插件
- npm install -g @vue/cli-service-global //全局安装
- vue serve直接运行vue单文件
- vue serve 不设置参数默认寻找目录中的 main.js index.js App.vue app.vue
- 也可以加载指定文件 vue serve ./src/login.vue
组件开发
分类
- 第三方组件
- 基础组件
- 业务组件
Monorepo
- Multirpo(Multiple Repository)
- 每一个包对应一个项目
- Monorepo(Monolithic Repository)
- 一个项目仓库中管理多个模块/包
- 项目结构
- Monorepo类型项目目录结构
- 大多数开源项目采用
- packags中每个组件都是一个包
- 整个项目再是一个大包
项目
packages
组件
_test_ //组件测试文件夹
dist //组建打包文件夹
src //组件源码
.vue
index.js //组件入口文件
LICENSE //开源协议
package.json // 组件包依赖等
README.md // 组件文档
Storybook
- 可视化的组件展示平台
- 在隔离的开发环境中,以交互式的方式展示组件
- 独立开发组件
- 支持的框架
- React、React Native、Vue、Angular
- Ember、HTML、Svelte、Mithril、Riot
安装
- 自动安装
- npx -p @storybook/cli sb init --type vue //指定 vue框架
- yarn add vue
- vue yarn add vue-loader vue-template-compiler --dev
yarn workspces 工作区
- 多个packages中的组件依赖使用工作区后相同的依赖只会安装一次
- yarn有工作区npm没有
开启工作区
在项目根目录的package.json
"private":true, //必须设置,防止意外暴露内容
"workspaces":[
"./packages/*"
]
- 安装依赖
- 多个组件中相同的依赖会安装到项目根目录的node_modules中,不会单独安装到组件中
- 仅单个组件使用的依赖会安装到包的依赖中,不同版本的也是
- 根目录中直接安装依赖 yarn workspace 包名(package.json中的name) add 依赖名称
lerna
- Lerna是一个优化使用git和npm管理多包仓库的工作流工具
- 用于管理具有多个吧哦的JavaScript项目
- 他可以一键把代码提交到git和npm仓库
使用
-
.gitignore 中忽略 node_modules
-
git add . 修改文件添加暂缓区
-
git commit -m ‘’ 信息
-
npm config get registry 查看npm源
-
安装
- yarn global add lerna
-
初始化
- lerna init
-
发布
- lerna publish
单元测试
优点
- 提供描述组件行为的文档
- 节省手动测试的时间
- 减少研发新特性时产生的bug
- 改进设计
- 促进重构
依赖
- Vue Test Utils
- Jest
- vue-jest
- babel-jest