vue调试工具步骤:
1.远程克隆仓库
2.安装依赖包
3.构建
4.打开谷歌页面
5.选中开发者模式
6.加载已解压的扩展,选择shells/chrome
父组件的数据传递给子组件, 只要父组件的数据变化了,自动重新向下流动, 进而子组件会进行更新数据
所以父组件的数据应该交给父组件修改
数据来源
data: 自己的数据可以随便更改
props: 传进来的数据不允许更改, 或者不建议更改 : 防止多个子组件进行数据交错
修改简单数据类型会报错
修改复杂数据类型,修改地址报错, 如果不改地址,修改对象的属性,不会报错,但是不符合单项数据流
通过 e v e n t 设 置 event设置 event设置 事件对象 进行设置
如果是简单数据类型, 子组件修改了,vue能检测到
如果是复杂数据类型, 子组件修改父组件出过来的值,不会报错 ,
解决办法 : 表单双向数据绑定
解决办法一 :
不能用v-model进行与数据绑定
用 : checked = 'item.flag' 进行数据绑定
通过事件对象$event 事件对象 进行传递, 同时在函数中 function (e){e.target.checked}
同伙
解决办法二 :
将父组件接收过来的数据通过json.parse(json.stringify(arr))转成一个新的数组或者对象
组件内部通过props接收传递过来的值
Vue.component('el-header', {
props: ['title'],
template: '{
{title}}'
父组件通过属性将值传递给子组件
<el-header title='来自父组件中的数据'></el-header> //传递静态数值,一般不用
<el-header :title='title'></el-header> //传递变量 动态绑定属性值
1.可以进行传递多个值.
2.如果么有进行传值, 而子组件使用这个数值, 会出现undefined
命名规则
在prop中使用驼峰形式,在模板中需要使用短横线形式 , 字符串形式的模板没有限制,可以使用个驼峰形式
传值规则: 不加 : 传递的是string类型数据, 加冒号是正常数据
如果传递number数据类型, 传递的都是字符串
:title='12' //number 区分类型
title='12' //string 不区分类型
注意: 父子组件传值, 数据是异步请求, 有可能数据渲染时, 报错 v-if=isReady
原因: 异步请求时, 数据还没有获取到, 但是此处已经渲染到节点了
解决方案: 在父组件需要传递数据的节点加上 v-if=isReady (isReady)默认为false, 异步请求获取数据后,isready赋值为true
子组件向父组件传递的值不是双向绑定的
目的:通过子组件触发事件影响父组件中的数据 或者父组件传递过来的数据,比如通过子组件中的按钮点击放大父组件整个盒子的背景色
父组件监听子组件事件
本质是监听子组件触发的事件, 同时父组件根据这个事件进行触发相应的函数,这样避免了子组件直接操作父组件传递的数据
尽管数据vue允许子组件去修改父组件数据, 但是在业务中,子组件应该尽量避免依赖父组件中的数据, 更不应该去主动修改他的数据, 以为这样使得父子组件紧耦合, 只看父组件, 很难理解父组件的状态, 因为他可能被任意组件修改,
理想情况:
只有组件自己能修改他的状态, 父子组件最好还是通过props 和$emit来进行通讯
$emit(自定义事件名, 值) 子组件想父组件传递值 ,//好像只能传递一个值, 如果想要传递多个值, 可以用数组或则对象的方式进行传递 ,事件名全部小写
this.$$emit(事件名, 参数1, 参数2,参数3……) //函数里面写
$event 接收子组件传递的值
模板中传值 :
子组件设置 @click='$emit(enlarge-text')
页面中设置
父组件定义change函数
方法值设置$emit
子组件通过自定义事件进行传值
<button v-on:click="$emit('enlarge-text', 0.1)"> //这是直接写在模板里面
Enlarge text
</button>
父组件通过设置$event接收参数
页面中设置 <son-slot @enlarge='change($event)'> //通过在事件里面写$event进行值的获取 方法里面注意后面的$event不写
函数种设置 change:function(value1, value2, value3 , value4....){
} value就是$event的形参
案例 : 父组件定义这个事件的时候, 可以是函数方法 changeFont 也可以是 data中的数据 fontSize
<!-- <el-header :msg="msg" @enlarge="changeFont"></el-header> --> 方法都是用v-on 或者是 @
<el-header :msg="msg" v-on:enlarge="fontSize += $event"></el-header>
单独的事件中心管理组件间的通信
单独的创建一个vue事件对象
var evetnhub = new Vue()
触发事件 进行参数传递 methods
evetnhub.$emit('子组件事件名称', 传参1) //触发兄第组件事件 ,向事件中心传递信息
监听事件与销毁事件 事件的监听写在mounted函数里面
evetnhtb.$on('子组件事件名称', (接收参数1)=> {
}) //监听事件事件中心中的变化 执行相关函数, this指向当前vue实例 本子组件
event.$off('add-todo')
事件注册点击相关
点击子组件click 触发senddata函数, 函数里面有emit,触发emit的change-state事件, 同时页面父元素上有change-state事件 该事件的执行函数为 fn1
单项数据流
删除功能 :
父组件根据id值进行删除list数据 ,父组件注册事件接收参数
增加功能 : 用v-model进行双向数据绑定, 注册键盘回车事件
修改状态 : v-model双向数据绑定,但是并没有遵循单项数据流
数据持久化 : 如果是axios版本发送ajax不需要进行数据持久化
watch : {
list: {
deep: true;
handler(newValue) {
localStroage.setItem('todos-data' , json.stringify((newvalue)))
}
}
数据获取 :
created: function (){}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YEBtxbke-1604141484224)(C:\Users\22359\AppData\Roaming\Typora\typora-user-images\1600936632623.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lGVbZMqV-1604141484231)(C:\Users\22359\AppData\Roaming\Typora\typora-user-images\image-20200925175147455.png)]
在子组件标签之间传递内容
里面的请输入正确的手机号码 , 请输入用户名, 不是写死的, 用插槽
为甚要用插槽 :
通过父传子, 自定义型较差, 通过插槽可以进行自由定制内容
作用:
用于实现组件的内容分发 ,自由定制任意结构, 用slot标签进行接收内容
错误提示
// 组件插槽
Vue.component('el-header', {
template: `
error:
`,
})
template: 向子组件中传递多个标签, template并不会渲染到页面
一般插槽
插槽默认 { {msg}} 直接值slot使用
注意:
vue-2.6版本中, v-slot指令取代了slot 与slot-scope,但是v-slot使用时, 需要在template标签上使用,不能在普通标签上使用
template通过v-slot指令绑定插槽, v-slot:header, header不加引号 不是等于号进行绑定数据
slot=‘header’ 是通过属性进行绑定 . 所以是=号, 不是 :
向子组件传递自定义标签名的插槽 ,通过name属性绑定,即将标签换成插槽传递给子组件
标签中传递的内容根据传递的slot属性进行传递, 子组件根据name进行匹配,没有匹配到的根据作为默认插槽使用
只能标注一个标签, 如果需要多个标签的话, 用template包裹,template并不会渲染到页面
<el-header>
<p>默认信息</p>
<p slot="header">这是title信息</p>
<p slot="footer">这是footer信息</p>
</el-header>
template: `
//默认插槽
`,
})
如果子组件中有数据, 希望在父模板分发内容是使用, 可以使用作用域插槽
给插槽添加属性的方式, 给父模板传值,
给插槽,添加属性的方式传值
所有添加的属性 , 都会被收集到一个对象中, {yes:’确认’., no; ‘ 取消’, moneny : 100}
在template中, 通过=即可接受子组件传递过来的数据,这样可以操作子组件传递过来的数据
如果子组件向模板传递过来的数据命名和vue实例中的数据名相同, 在模板中, 会使用子组件的数据
模板的范围属于谁,使用的就是谁的变量 比如子组件里面的模板, 其实模板使用的变量是不是组件的, 而是vue实例
所以插槽里面如果有点击事件的方法写在vue实例里面, 而不是写在子组件里面
作用域插槽使用场景
表格模板中,delelte操作时不固定的, 也可能是add,所以需要设置template进行自定义,防止把子组件写死
但是点击delete或者add时,需要发送id,进行ajax操作,所以子组件向插槽传值
注意:template 插槽的名称不要重复,否则下面的插槽会覆盖上面的插槽,
插槽里面如果需要操作数据,添加方法,需要将插槽写在tmeplate所在位置, 而不是插入的子组件mo模板的范围属于谁,用的就是谁的变量
Document
父组件传递的插槽 通过=号解释
{
{ obj.friend }}
子组件模板传递的数据 直接在slot进行传递数据
插槽的几种形式 v-slot只能在template中写
有标签的插槽
模板插槽
传递数据的插槽
单页应用程序spa
多页应用程序
每次点击都会重新刷新页面
单页应用程序
优点 :
每次只需要获取必要的数据,减少请求体积, 减轻服务器压力
缺点: 开发成本高(需要学习路由)
不利于seo搜索引擎优化----用户搜索时搜索不到: 解决方案: 利用node中 ssr进行服务端渲染
3.路由
-
路由基本概念:
路由是浏览器url中的哈希值,(#hash) 与展示视图内容(组件)之间的对应规则
简单来说: 路由就是一套映射规则(一对一的对应规则),有开发人员制定规则
当rul中的哈希值(#hash)值发生改变之后, 路由会根据制定好的规则,展示对应的视图内容(组件)
-
为什么要学习路由
渐进式--->vue-vue-router(管理组件之间的跳转)
在webapp中,经常会出现通过一个页面来展示和管理整个应用的功能
spa往往是功能复杂的应用, 为零有效管理所有视图内容, 前段路由出现
vue中的路由 : 是hash和component的对应关系,一个哈希值对应一个组件
点击链接, url是上的hash会发生变化, 在在检测到变化的时候切换对应的组件,就实现了路由的使用,同时由于通过hash的方式是不跳转页面的,所以实现了spa单页面应用程序
1.哈希值 hash
浏览器地址栏#后面的名字 文件本页面通过href跳转, 只是点击之后修改地址栏的哈希值
vue-router就是利用这个原理 :
利用锚点跳转. 通过改变地址栏的hash值, 将来可以切换对应的组件
2.router语法
步骤1: 设置基本项 router:router
下载 npm i vue-router
引包 (先引入vue包到html页面) 以为router依赖于vue
使用,创建路由实例 cosnt router new VueRouter()
将当前的路由实例挂载到vue实例中, 建立联系 router:router
步骤3: 配置路由规则
定义路由组件
cosnt router = new VueRouter({
router代表路由实例对象
routes: [{
path:'', compontent:''},{
}]
//routes代表路由规则(路线集合) 一条路由规则就是一个对象 格式 : {path:路径,compontent:组件的配置对象}
可以将compontent在外面定义
})
步骤3: 添加路由填充位router-view,对应的组件展示位置
路由填充位(也叫做路由占位符)
将来通过路由规则匹配到的组件, 将会被渲染到router-view所在的位置
<router-view></router-view>
步骤4: 添加路由链接router-link ,点击切换组件
<router-link>是vue中提供的标签, 默认会被渲染成a标签
to属性默认会被渲染成href属性
to属性的值默认会被渲染成#开头的hash地址 ,用于指定要跳转的路由地址
注意: 后面的本来是<a href='#top'> 但是为了区分 vue设置成了#/需要添加/ ,同时又将#自动取消了 ,在url中vue自动添加了#/
<router-link to='/uesr'>user</router-link>
<router-link to='/register'> 点击更换组件b<router-link>
3.router-link使用
-
router-link-exact-active精确匹配 类名
-
router-link-ative模糊匹配 类名
两种方式在匹配时会加上相应的类名
router-link-exact-active to里面配置的hash值路径必须完全一样才会加上类,给这个a标签加上这个类名
router-link-active to里面配置的hash值路径开头只要包含就能进行匹配
<router-link to="/Detail/fsadfsad">detail</router-link>
导航链接 : 实际渲染出来就是a标签,
2.必须配置to属性, 用于指定跳转的路由
4.相关设置
1.重定向:
path:'/', 如果用户访问的/ 进行重定向,,重新设置路由路径,匹配组件
{path:'/', redirect:'/default'}
第二种方式 通过component设置重定向
{path:'/', component:User}
2.设置自定义类名 ,默认高亮的类名是可以定制的
当点击的router-link中设置的to路径与地址栏上完全一样是,就会添加这个类名
linkActiveClass:'current' 模糊匹配
linkExactActiveClass:'current'
to里面写完整路径
5.嵌套路由
注意: 子路由进行嵌套时设置重定向, 尽量使用redirect设置路径, 如果设置component 添加类名的时候添加不上
重定向进行设置显示分类页
子分类下的/需要取消
如果path中相对路径,会自动将父路由的path拼接在前面
children: []
6.编程式导航
核心: 通过js的方式进行跳转路由,叫做编程式导航,比如点击button进行跳转
之前学的是用a标签进行跳转路由,写href进行跳转,声明式导航
this.$router.push(‘hash地址’)
this.$router.go(1) 在浏览历史中前进, -1为在浏览历史中后退
注意:前进只有在后退之后才能进行前进,因为是历史记录中的后退
例如 : 通过js跳转 如localcation.href = 'www.baidu.com'
vue中通过js的方式进行跳转, 但是vue中不是local,因为local跳转的是整个页面
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T4CYLdle-1604141484237)(C:\Users\22359\AppData\Roaming\Typora\typora-user-images\image-20200927195856593.png)]
-
语法 :
-
this.$router.push(路由路径)
例如"
<button @click='jump'>
methods: {
jump() {
this.$router.push('/user')
或者
router.push('/user')
}
}
this.$router 完全等价于 router 就是唯一的router实例
7.动态路由匹配
渲染商品1 渲染商品2 ...... 多个额商品只需要准备一个模板, 里面的参数变化就行了,比如点击京东手机列表, 显示的都是同一个格式的页面thi
this.$route 当前路由的相关信息, 比如参数, 路径
如果要获取当前的路由的相关信息,用this.$route
用watch进行监视this.$route 每次只要路由变化了, 地址也变了, 就会有一个新的this.$route(不用深度监视)
但是created函数里面都是同一个route参数, 以为组件是同一个组件,点击切换的时候组件并没有被销毁或重建, created仅仅执行了一次, 所以都是同一个值
watch: {
$route(newvalue){ }
}
商品1
商品2
商品3
商品4
商品5
routes: [{ path: '/shop/:id', component: Item }],
动态路由参数获取 this.$route watch监视路由变化
只要想拿当前的路由的路径或者参数,就找this. r o u t e route route
route 一条路由规则 , 一个对象{
path:'/user',compontent:User}
this.$route当前的路由的相关信息,比如路径,参数
fullpath : url地址栏中数据的完整信息,包含查询参数
path #后面的不包含含查询参数的路径
query 解析后得到的查询参数对象 ?username=张丹娜&pass=123解析成对象之后的
params 可以获取动态路由参数 /shop/1后面的1
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-djbFVtoN-1604141484245)(C:\Users\22359\AppData\Roaming\Typora\typora-user-images\image-20200927174343805.png)]
8.router区分
this.$router指向router实例
app.$router指向router实例
router.push 指向router实例
问题: 后面的开发环境当中,每一个模块都是独立的,存放到单独的文件中, 互相之间不能访问到router变量.vue中把router实例给每创建出来的组件绑定了$router,这样都能进行访问到router
routes: 配置路由规则时写的, 多个路由规则, routes:[]
route 一条路由规则
9.命名路由
为了方便表示路由的路径, 可以给路由规则起一个别名, 即为‘命名路由’
属性绑定 通过: to
命名路由的方式直接在router-link中进行传递参数
路由规则设置:
routes: [{
path: '/shop/:id', name: 'mingming', component: Item }],
声明式导航 路由链接设置 注意写 冒号
<router-link :to='{name:'mingming', params:{id:123}}'>
编程是导航链接设置
router.push({
name:'mingming',params:{
id:124}})
自定指令
案例:autofocus在vue中不能使用, 因为部分浏览器不兼容, vue屏蔽了
应用场景: 通用的dom操作时,使用自定义指令
前置知识:
created: 一般发送初始化渲染数据
mounted:可以进行dom操作
如果进行的通用的dom操作, 并且可能多个页面都需要获取焦点, 推荐将focus封装到自定义指令中
1.分类 :
全局指令
局部指令
全局指令语法
定义指令:
Vue.directive(指令名,配置对象)
对象里面可以配置5个钩子函数
函数一: inserted(el)
指令所在的元素被插入到页面中时,这个函数触发
el代表被插入的元素
使用指令:
v-指令名
局部指令语法
directives: {
focus: {
inserted(el) {}
}
}
2.五个钩子函数
注意 自定义指令的钩子里面没有vue实例, this指向window
-
bind(){} 指令和所在的元素,绑定时触发,在bind一般进行初始化,bind一般只触发一次,在这里获取不到el元素内容,无法插入元素
-
inserted(){} 绑定后,元素被插入页面中时触发,*可以进行操作dom.dom已经渲染上去了
-
update(){} 当指令的值更新时触发,速度比componentUpdated快一点
如v-demo='info'
-
componentUpdated(){} 指令所在的元素(组件),dom更新完成后触发
-
unbind 实例销毁时触发, vm.$destory
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VNDZ1wM0-1604141484249)(C:\Users\22359\AppData\Roaming\Typora\typora-user-images\image-20200928153744619.png)]
参数
el 指令所在的元素
v-on:click.stop.prevent='fn1'
binding--------------------------------------- 包含了设置的参数
name指令名 on
value指令值 fn1
modifiers 修饰符对象形式 指令显示loading加载中效果 stop prevent
自定义指令的简写
条件: bind和update逻辑 必 须 必须 必须完全一致
要求比较严格
普通写法
bind(el, binding) {
}
uprate(el,binding){
}
如果bind 和 update逻辑完全一致, 可以简写
Vue.directive('指令名', 处理函数) 表示同时处理bind, update
2. vue-动画
1.转场动画
概念 : 中间过渡动画,控制元素侠士隐藏,配合v-if使用
当通过if进隐藏显示的时候,平常写的时候没有这个设置
v-enter在元素即将进入页面的时候添加
v-enter-to 在元素完全进入页面时添加这个类
v-enter-active在元素进入页面的动画过程中
v-leave在元素即将离开页面时
v-leave-to在元素完全离开页面
v-leave-active在元素离开页面的过程中
2.translation可以设置name属性
transsition name='fade' 当前给元素添加的动画的类名前缀就变成
fade-enter
fade-enter-to
......
3.animation动画
步骤: 使用transition将需要使用动画的元素包裹
包裹了元素,元素就有了动态切换的6个类 v-enter v-enter-to v-enter-active v-leave v-leave-to v-leave-active
animation from to
举例
@keyframes bounce {
0% {
transform : scale(0)
}
50%{
transform:scale(3)
100%{
transform:scale(1)
}
}
animation form to 在动画中, 设置好了,动画的开始, 动画结束的模式
.v-enter-acitve {
animation
}
3.vuex
1.概念
- 集中式状态管理工具,用于组件之间传递数据
- 将组件之间共享的数据放在vuex中管理
- vuex中的数据是响应式的, 如果a组件的数据修改
vuex的特点
集中式,响应式
vuex 和localstroage区别
- vuex是响应式的,localstroage不是,vuex中的数据,组件a中的数据会自动改变, 而localstorage需要自己主动获取, 才能达到更新
如何正确使用vuex
- 如果项目小,不需要使用vuex,用了可能会增加项目难度
- 只有在写项目的时候, 发现组件通讯多, 组件之间的关系复杂,项目已经无法继续开发, 此时使用vuex
- 如果是组件共享的数据才放在vuex里面
2.vuex基本使用
- 引入vuex.js文件
- 通过vuex创建一个仓库 const store = new VuexStore()
- 挂载到app根实例上,通过this.$store.state…获取值,设置值
3.vuex中的严格模式
const store= new Vuex.store({
strict:true,
state:{
}
}
-
添加严格模式后不能在mutation外面修改state中的数据
addData () {
this.$store.dispatch('addAsync', {
tagName: this.tagName })
}
========================================
// 异步添加
// context ≈ store
addAsync(context, payload){
//1. 异步
setTimeout(()=>{
// 2. 提交
context.commit('add',payload)
},1000)
}
}
## 4.actions
vuex 可以正确的监听 mutations ,但是 异步的除外,-- mutations 里面不能放异步的,否则监听有问题
mutations : 同步 + 修改数据
actions : 异步 + 提交同步
## 5.mapState(数据映射)
**mapState映射 vuex中的数据放在组件中的computed中**
1. 引入vuex里面的辅助函数 `import {mapState}from 'vuex'`
2. 组件的computed中
```js
computed: {
...mapState(['list']) //获取list数据
}
3.如果组件中的data中的数据和mapState中冲突了,可以改名,对象形式
computed : {
...mapState: ({
"item" : list})
}
6.mapGetters(映射数据)
- import {mapGetters} from ‘vuex’
- computed
computed: {
...mapGetters(['isShow'])
}
- 自定义名称,如果发生和组件中的数据重名
computed : {
...mapGetters({
isShow1: isShow
})
}
7.mapMutations(映射方法)
放在方法里面
- import {mapMutations} from ‘vuex’
- methods
methods: {
...mapMutations(['delData'])
}
- 调用 this.delData ,del中的名字和methods中重名.会发生最大调用栈溢出
- 重新起名
methods: {
...mapMutations:({'d':delData})
}
8.mapActions(映射异步)
- import {mapActions} from’vuex’
- methods
methods: {
...mapActions(['addAsync'])
...mapActions({
'add1': addAsync})
}
9.指定页面跳转
需求:
- 进入home页面,就把home页面缓存
- 离开home到tablist页面里面,把home页面从缓存中移除
- 移入其他页面,再次进入home页面, 再次把home页面缓存
步骤
- 定义include数据
- 将cacheList:[‘home’, ‘search’]放在vuex中,使用vue管理cachaList
- 配置vuex, 安装vuex, 创建store文件夹,index.js文件
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.store({
state: {
cacheList:['search']
}
mutations: {
//增加: 比如home添加到cachelist
cache(state,payload){
if(state.cacheList.includes('payloa.name')) {
state.cacheList.push(payload.name)
}
}
//删除 : 删除home
uncache(state,payload){
if(state.cacheList.includes(payload.name) {
state.cache=state.cacheList.filter(v=>!=payload.name)
}
}
}
})
- app.vue设置keepalive标签
<keep-alive :include="cacheList">
import {
mapState} form 'vuex'
computed:{
...mapState(['chaList'])
}
- 在home中的beforeRouterLeave设置beforeRouterEnter和beforeRouterLeave守卫,
已进入home页面就将home缓存起来
beforeRouterEnter(from. to , next){
//在此中获取不到vue实例对象 this.$store.commit('cache'),,因为此时组件还没有创 建,守卫执行前. 组件实例没有创建
//解决办法: import sotre from 'store/index.js
store.commit("cache")
next()
}
- beforeRouterEnter中判断from判断上一个路由信息对象是否talist, 如果是, 调用vuex中的删除home函数
离开home页面去tablist页面不要缓存,从home从cache中移除,移除之后会再次创建,不能只在进入时判断,因为离开时会销毁'
if(to.path==='tablist'){
this.$store.commit('uncache')
}
- beforeRouterLeave中添加home
4.项目上线打包
1.打包步骤
- yarn build 只需要给dist文件交给后台
- 在dist文件夹里面开启一个本地服务器,模拟一下:live-server
2.打包前的准备工作
- 关闭console.log,将log方法重写,在main.js的顶端进行重写
console.log=()=>{
} //设置什么都不写,
- 更换基准地址开发阶段
1.开发阶段基准地址 : http://localhost:3000
2.发布阶段基准地址: http://baidu.com.
process.env 获取环境参数
axios.defaults.baseURL=process.env.NODE_ENV==='development' ? ' http://localhost:3000' : ' http://baidu.com'
- 注意:每次修改了代码,开发环境刷新一下进行,发布环境需要重新打一个包
- 如果ebusy忙碌中. 说明正在使用, 找到终端, 把live-server断开,两次ctrl c
3.工程化webpack设置
1.模块化规范
1.传统开发模式的主要问题
-
命名冲突: 多个js文件之间如果存在重名变量,会发生变量覆盖
-
文件依赖: js文件之间无法实现相互引用解决方法: 模块化 2.模块化概念
解决方法: 模块化
2.模块化概念
模块化就是单独把一个功能封装到一个模块(文件)中,模块之间相互隔离, 但是可以通过一个特定的接口将内部成员,也可以依赖别的模块
模块化开发的好处: 方便代码的重用,从而提升开发效率,并且方便后期的维护
3.服务器端模块化规范
浏览器端
amd 模块化 require.js
cmd模块化 Sea.js
4.服务器端模块化规范
commonJS 只用于服务器端
1. 模块分为 单文件模块, 与包,
2.模块成员导出: module.exports和exports
模块成员导入 : require('模块标识符')
5.通用模块化规范
每一个js文件都是一个独立的模块
导入模块成员使用import关键字
暴露模块成员使用export关键字
6.导入导出
导出方式一 : export {
name, falg}
导出方式二 : export var num= 7899;
import {
name, flag} from './mmm.js'
非自定义导出方式, 导入时候需要与导出的名称完全一样
导出函数 : export function fn1 () {
return num2 +num1)
自定义导出 default在同一个模块里面只能只一个, 不能是多个
export default num
import 自定义名称 from './mmm.js'
2.webpack用法
1.webpack概念
基于js的静态模块打包器
- 打包的说明
打包目的: 将多个文件压缩成一个文件, 减少请求的次数,减轻服务器压力
-
webpack能做什么
-
语法转换:
1. 将less/sass/stylus 转换成css
2. typescript(ts)转换成js $ts中有非常严格的类型检测$
3. es6转换成es5/es3 比如imrt
-
将多个文件合并成一个文件
如果项目要上线, 一定要先打包压缩,后上线
-
可以起一个开发时的服务器,可以做到保存时自动刷新浏览器
自动开启浏览器
自动监视文件费
自动刷新浏览器
-
在webpack中,一切的静态资源都是模块
静态资源: 不需要后端额外处理的文件内容
.php .asp .jsp 这些不能浏览器直接解析的,需要服务器进行解析的
静态资源: html ,js css png jpg jpeg...
只要是模块,可以当成模块导入,使用模块语法 require('./a.js') require('./1.png') require('./1.css')
2.yarn的使用
下载地址
https://yarn.bootcss.com/docs/install/#windows-stable
yarn与npm类似, 都是包管理工具, 可以下载包, 管理包
1.初始化 yarn init / yarn init -y 新建一个package.json文件
2.装包 yarn add 包名
3.删除包 yarn remove 包名
4.安装依赖 yarn yarn install
5.全局安装 (了解, 一般不用, 全局安装一般用npm)
yarn global add json-server
yarn global remove json-server
3.打包步骤
以后使用对着官网面对着博客配文件,
步骤:
创建目录
src 存放源代码 , 里面有main.js, 整个打包的入口文件,姜凯从这个文件开始打包
dist: 存放打包后的文件
yarn 安装依赖
-
yarn init
-
yarn add webpack webpack-cli -D
--save 简写 -S 默认值, 装包时,不写默认添加 npm i vue -S 等于npm i
将包记录成项目依赖
--save-dev 简写- D
npm i webpack -D 等于 npm i webpack --save-dev
将包记录成开发依赖,这个包只是开发过程中依赖的包
-
在package,json中配置scripts
seripts: {
"build": "webpack ./src/main.js -o ./dist/bundle.js"
}
-
运行npm run build打包或者 yarn build
指定开发模式 –module=develoment
打包会跳出警告 : mode有两种模式,默认生产模式
production 生产模式(生产环境)----将来上线的环境(压缩版本)
development 开发模式----现在开发过程的环境(未压缩,便于查看源码)
设置指定模式 ==将其打包成开发版本
seripts: {
"build": "webpack ./src/main.js -o ./dist/bundle.js --module=development"
}
-
后面文件在src里面的main.js或者index.js入口文件中引入
npm中- - save 和- -save-dev的区别
1--save简写成-S , 将安装包作为项目的依赖,(目前为默认值)
早起npm安装包的时候, 必须加上--save才会添加到package.json项目依赖中去
2. --save-dev 简写-D : 将安装包作为开发阶段的依赖
#tips
dependences: 项目依赖, 项目上线也要用的
devDependencles:开发依赖, 只有在开发中使用, 上线是不要用的
注意点: yarn add jquery -D; yarn只认识-D
3package.json配置scrips命令,配置自己的命令
第一步 配置命令
"scripts": {
命令名字:命令内容,
"pp": "yarn add vue"
}
第二部 执行命令
npm run 命令名字
npm run pp /yarn pp
第三部 ==特殊的命令: 如果npm要执行的是start或者是stop,可以省略run==
"scripts": {
命令名字:命令内容,
"start": "yarn add vue"
}
第四部 运行命令 npm start / yarn start
工作中都是配置start 运行.app.js脚本文件
webpack配置到配置文件中
- 配置配置文件
- 设置自动dev插件
- 自动复制html文件插件
生产环境: 上线的环境,代码需要压缩合并处理的production
开发环境:还在开发中, 代码一般不压缩的(可以查看源代码)development
-
1.创建一个新目录: dist src/main.js
配置命令到配置文件中:直接在pack中配置不了太多 代码乱太难看==
同时在webpack目录里面创建webpack.config.js文件
2.初始化 : yarn init -y
3.安装依赖包
yarn add webpack webpack-cli -D
4.配置scripts
--config webpack.config.js这个配置文件名为默认值,不加默认也会找这个文件
scripts: {"build":"webpack --config webpack.config.js"}
scripts: {"build":"webpack"} 默认会找当前目录下的webpack.config.js js文件
5.提供webpack.config.js文件位置在webpack文件夹下,和package.json同级
参考文档: https://webpack.docschina.org/concepts/#入口-entry-
解释:
这个文件是webpack的配置文件, 将来webpack打包时,会加载当前文件
按照配置的规则进行打包
webpack ./src/main.js -o ./dist/bundle.js --mode=development设置开发环境
webpack.config.js代码设置步骤
const webpack = require('webpack')
// webpack是基于modejs的工具
// 打包设置的绝对路径
const path = require('path')
module.exports = {
// 设置模块导出
// 1.配置打包入口文件, 从哪个文件开始打包----------------
entry: './src/main.js',
// 2.配置打包出口,打包到哪里去,文档中规定,出口文件必须使用绝对路径,需要引入path文件,设置绝对路径-----
output: {
// 路径
path: path.join(__dirname, './dist'),
// 打包后生成自定义的文件名 js前民不能写/ 写了就变成了相对路径
filename: 'js/bundle.js',
},
//3.模式设置:确定是开发者模式或者生产环境 -上线环境
mode: 'development',
}
备注: 假定在main.js中导入一个aa.js,多个文件需要打包,webpack会打包成一个文件,可以节约请求的次数,仅仅会请求一次
require('./aa.js')
log("这是main模块")
基于webpack实现隔行变色
-
新建public/index.html文件编写代码
-
public文件夹
文件夹中放置index.html文件, 将来indehtml中不会戏太多内容, 都是通过vue组件来渲染
-
index.html内部引入dist/bundle.js文件夹.书写代码特别注意:如果不使用插件的话, 多余的文件任然在dist文件中
<div id="app">
<!-- ul>li{
我是第$个li}*10 -->
<ul>
<li>我是第1个li</li>
<li>我是第2个li</li>
<li>我是第3个li</li>
<li>我是第4个li</li>
<li>我是第5个li</li>
<li>我是第6个li</li>
<li>我是第7个li</li>
<li>我是第8个li</li>
<li>我是第9个li</li>
</ul>
</div>
<script src="../dist/bundle.js"></script>
</body>
</html>
-
在src文件的main.js文件中引入jquery文件,使用jquey隔行变色
main.js中书写代码
安装jquery : yarn add jquery yarn add moment
// 需求: 通过jquery实现隔行变色
const $ = require('jquery')
const moment = require('moment')
$(function() {
$('#app li:nth-child(odd)').css('color', 'red')
$('#app li:nth-child(even)').css('color', 'green')
$('#app li:last-child').text(moment().format('YYYY年MM月DD日'))
})
.自动生成html -html-webpack-plugin插件
目前我们都是在index.html中国手动移入打包后的资源,这种引入方式是有缺点的比如:
文件依赖问题: 假如webpack配置中的输出文件名修改了, 需要及时在index.html同步修改
1.下载
yarn add html-webpack-plugin -D
2.在webpack.config.js
文件中引入这个模块
// 插件: 自动生成 html 的插件, 可以自动引入打包后的文件
const HtmlWebpackPlugin = require('html-webpack-plugin')
//写在module.exports里面
plugins: [new HtmlWebpackPlugin({
template: './public/index.html'})],
3.配置好了之后`public目录的index.html文件`就不需要打包后的js或者css文件了,会被插件生成html引入
4.设置之后,插件会将设置的index.html复制一份到dist文件夹下,并且将设置的之前根据文件打包入口文件出口文件路径filename的路径,
根据设置的路径,将其bundle.js引入dist文件夹下html中
webpack-dev-server插件自动刷新
1.下载
yarn add webpack-dev-server -D
2.配置scripts,在webpack.json文件中设置
scripts: {
"build":"webpack --config webpack.config.js"//这个文件是之前配置的,用于设置配置文件的,创建一个config文件
"dev": "webpack-dev-server --config webpack.config.js"
}
3.在webpack.config.js的module中配置
配置开发服务器的配置
devServer: {
port:3000,//端口号
open: true,//自动打开浏览器
}
webpack中处理css文件
webpack-loaders的配置
webpack默认只认识js文件和json文件, 但是webpack可以使用loader
来加载预处理文件, 允许webpack也可以打包js文件之外的资源
所以webpack如果想要处理其他文件类型,记得要先配置对应的loader
需求 :去掉小圆点,新建css目录
1.安装依赖,同时在main.js文件中引入index.css文件
sytl-loader和css-loader都安装到设置开发环境里面
yarn add style-loader css-loader -D
2.配置
module: {
rules: [
{
// 正则表达式, 用于匹配所有的文件
test: /\.css$/,
// 先用scc-loader让webpack能够识别css文件内容
// 在用style-loader将样式,以动态创建style的方式添加到页面中
use: ['style-loader', 'css-loader'],
},
],
},
webpack分离css文件
上面的操作 是css和js文件混杂在一起了, 将css放到了style标签中,和html一起加载了一个文件请求次数是少了
但是如果css文件太大的话,也不是太好, 需要将css分离出来
-
有一个插件,mini-css-extract-plugin
, 这个插件支持webpack4.x
-
还有一个插件extract-text-webpack-plugin 这个插件对webpack3.x的版本支持, 被webpack4.x废弃了
1.安装依赖包
yarn add mini-css-extract-plugin -D
2.在webpack.config.js
文件中,引入这个模块
引入分离css文件的模块
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
3.配置loaders 覆盖原来的**一定要覆盖原来的css解析设置**
// 模块加载
module: {
// loader的规则
rules: [
// 配置 css 文件的解析
{
test: /\.css$/,
use: [ // 根据官方文档写的,注意'css-loader'的书写位置
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath:'../', //路径相当于将dist 中main.js文件的上一级 创建一个文件
},
},
'css-loader'
]
},
],
}
4.配置插件
// 定义打包好的文件的存放路径和文件名
new MiniCssExtractPlugin({
filename:'css/index.css' //相当于之前publicpath中写的../上一级路径创建一个css文件目录下/index.css
})
5.设置完成之后就变成了link引入的模式
webpack less文件处理
1.下载依赖包
注意: 解析less文件需要识别 less 语法, 所以除了 less-loader
需要额外下载 less
包
less-loader: 将less转换成 css
yarn add less less-loader -D
2.配置
// 配置 less 文件的解析
{
test: /\.less$/,
use: [
// 分离出 css 内容
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath:'../',
},
},
'css-loader',
'less-loader'
]
}
webpack中处理图片-url-loader
webapck不识别图片,此时需要转换图片中的loader,来处理图片的问题, 主要用到
url-loader 和file-loader
注意: url-loader中的部分功能要用到file-loader,要下载两个模块
配置图片的加载规则:
``
1.下载两个依赖包
yarn add url-loader file-loader -D
2.配置loader
如果不配置图片, 图片将被处理成base64字符串的格式, 好处: 节约请求的次数,注意:一般推进将小图片转成base64
图片转成base64, 体积会增大30%左右,
所以: 如果是小图片 直接转, 如果是大图片需要单独处理
{
test: /\.(png|jpg|gif|jpeg)$/i,
use: [
{
loader: 'url-loader',
options: {
//超过8k 单独引入,不到8k, 转base64
limit: 8192, // 8*1024b 即为8kb
},
},
],
},
配置图片输出的打包目录
默认是直接输出到了 dist 根目录, 可以通过 options 进行配置
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
// 超过 8k 就不转 base64, 小于 8k 才转字符串
limit: 8 * 1024,
// 配置输出的文件名
name: '[name].[ext]',
// 配置静态资源的引用路径
publicPath: "../images/",
// 配置输出的文件目录
outputPath: "images/"
}
}
]
}
webpack配置字体图标
webpack 配置字体图标 - url-loader
在main.js中设置加载require加载字体图标的css文件
require('./icon.css')
// 处理字体图标的解析
{
test: /\.(eot|svg|ttf|woff|woff2)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8 * 1024,
// 配置输出的文件名
name: '[name].[ext]',
// 配置静态资源的引用路径
publicPath: "../fonts/",
// 配置输出的文件目录
outputPath: "fonts/"
}
}
]
}
webpack清除dist目录的插件
使用clean-webpack-plugin插件,在每次打包前清除dist文件夹
安装依赖包
yarn add clean-webpack-plugin -D
在webpack.config.js文件中运行
// 其他代码
// 导入清除插件
const {
CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
// 其他配置
plugins: [
// ....
// 调用清除打包目录插件
new CleanWebpackPlugin()
]
};
webpack开发服务器处理语法兼容
webpack使用babel处理高版本的js语法
babel的介绍: 用于处理高版本js语法的兼容性
yarn add -D babel-loader @babel/core @babel/preset-env
配置规则
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
},
]
}
webpack.config.js总体设置参考
// 这个文件是webpack的配置文件, 将来webpack打包时, 会加载当前文件
// 按照配置的规则进行打包
// webpack ./src/main.js -o ./dist/bundle.js --mode=development
// 错误:
// 1. 漏装包, 装错包(包名写错)
// 2. 配置单词, 逗号
// 插件: 自动生成 html 的插件, 可以自动引入打包后的文件
const HtmlWebpackPlugin = require('html-webpack-plugin')
// 引入分离 css 文件的 模块
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
// 导入清除插件
const {
CleanWebpackPlugin } = require('clean-webpack-plugin');
const path = require('path')
// webpack是一个基于nodejs的打包工具
module.exports = {
// 1. 配置打包入口文件, 从哪个文件开始打包
entry: './src/main.js',
// 2. 配置打包出口, 打包到哪里去
output: {
// 打包到哪个目录
path: path.join(__dirname, './dist'),
// 打包后生成的文件名
filename: 'js/bundle.js'
},
// 3. 配置打包的模式 production development
mode: 'development',
// 4. 模块的加载配置
module: {
// 规则
rules: [
// 1. 配置css加载的规则
{
// 匹配所有 .css 后缀的文件, 进行处理 i: ignore 忽略
test: /\.css$/i,
// 配置加载的loader
// 处理的顺序, 从后往前
// 1. css-loader 先处理, 让webpack具备了解析css, 读取css文件的能力
// 2. style-loader 后处理, 将读取得到的css, 以 js 动态创建style标签的方式, 作用于页面
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../'
}
},
'css-loader'
]
},
// 2. 配置less加载的规则
{
// 匹配 .less 后缀的文件
test: /\.less$/i,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../'
}
},
'css-loader',
'less-loader'
]
},
// 3. 配置图片加载的规则
// 默认不配置, 图片将被处理的base64字符串的格式, 好处: 节约请求的次数
// 注意: 一般推荐将小图片转base64, 节约请求, 如果是大图片, 请单独请求处理
// 图片 转 base64 => 会比原有的体积 增大 30% 左右
// 所以:
// 1. 如果是小图片, 转base64
// 2. 如果是大图片, 单独引入处理
{
test: /\.(png|jpg|gif|jpeg)$/i,
use: [
{
loader: 'url-loader',
options: {
// 超过 8k, 单独引入, 不到 8k, 转base64
limit: 8 * 1024,
// 配置输出的文件名
name: '[name].[ext]',
// 配置静态资源的引用路径
// 例如: 从index.css 出发, 找图片, ../images/xx.gif
publicPath: "../images/",
// 配置输出的文件目录
outputPath: "images/"
}
}
]
},
// 4. 配置对于字体图标的加载
{
test: /\.(eot|svg|ttf|woff|woff2)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 8 * 1024,
name: '[name].[ext]',
publicPath: "../fonts/",
outputPath: "fonts/"
}
}
]
},
// 5. 配置babel, 将新版本的es6语法 => es5/es3 浏览器兼容的语法
// 正则中的 ?, 表示可以出现 0 次 或 1次
// .js
{
test: /\.js$/,
// exclude 排除, 设置排除项, 哪些目录是不需要进行解析编译的
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
},
// 5. 配置插件
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html' }),
// 定义打包好的文件的存放路径和文件名
new MiniCssExtractPlugin({
filename: 'css/index.css'
}),
// 调用清除打包目录插件
new CleanWebpackPlugin()
],
// 6. 配置开发服务器的配置
devServer: {
open: true, // 自动打开
port: 3000 // 端口号
}
}
// 脚手架 => vue-cli 自动生成 webpack 配置
// publicPath 决定了静态资源文件的加载路径, 不要乱改
总体设置路线
- 创建dist src less css js 文件
- 清除dist目录的插件,每次重新生成会删除之前的插件
- webpack-dev-server插件自动刷新设置
- 自动生成html -html-webpack-plugin插件
- 设置css插件 设置css插件分离设置
- 设置less插件
- 设置fonts插件 注意 fonts需要在main.js文件中引入 font.的css文件
- 设置es6语法兼容babel插件
生产环境开发环境分离
生产环境与开发环境刚好相反, 开发环境在本地运行, 生产环境在服务器端,给用户使用的代码, 因此两者的构建目标很大, 比如打包后的文件要在生产环境中要尽可能的小, 逻辑代码分离吗优化静态资源,(压缩图片等)
因此,开发环境和生产环境不能共用一份webpack配置文件, 需要分别指定
但是两个环境还是有很多配置是可以共用的吗比如entry output module等, 因此 可以把公共部分的配置抽离出来, 放到一个单独文件,然后进行合并, 可以使用webpack-merge
工具进行合并
config文件夹: 放当文件 config只能使用旧版本语法 src中使用新版本语法,以为有babel
- webpack.base.js 这个文件专门用于存放公用的配置
- webpack.dev.js专门存放开发环境文件,不压缩的
- webpack.pro.js上线打包的文件,
通用里面不用设置mode
dev导入基础配置对象: cosnt base =require(‘./webpck.bbase.js’)
导
yarn add webpack-merage -D
//使用合并webapck配置的插件
const {
merge} = require('wbpack-merage')
//merage(合并对象)
build对应生产环境上线
dev对应开发环境设置
开始拆分webpack.config.js
文件, 拆分以后,这个文件就不要了
新建config
文件夹
-webpack-demo
-config //存放配置文件的文件夹
-webpack.base.js //公共配置
-webpack.dev.js//开发环境的配置
-webpack.pro.js.//开发环境的配置
-//其他文件
4.es6 模块化
前言
require module.exports ===>es5
import export (浏览器和node都不支持),新语法都被webpack解析才能运行
解决: 在之前的js中一直没有模块系统的, 前辈们提出了commonjs规范,amd规范
amd淘汰 cmd淘汰
标准化模块化语法=>es6模块化语法通用的模块化解决方案=>import导入=>export导出
一个模块就是一个独立的文件,该文件内部的所有变量, 外部无法获取,如果希望外部能够读物模块内部的某个变量, 就必须使用export关键字输出该变量,
es6新增了两个命令: export import , export命令用于规定模块的对外接口, import命令用于输入其他模块提供的功能
1模块导入导出
导出的数据只能获取不能设置
导入后相当于const 变量名, 不能重复设置
1.精确导出:
导出多个值一一对应
可以根据需求进行导入导出,按需导入,导出时导出的方法使用的当前的模块的变量或者数据,是否能够获取到
export funcion (){
}
export cosnt num =11
export cosnt arr =[]
export obj js
export {
num1 , name1 ,age}
import{
num1 ,name1 , age} from ‘./a.js’
- export{name1 , age1 , obj , arr } ,一般放在最后
- export tellStory
- import {name1, age1 , obj , arr } from ‘./a.js’
2. 默认导出:
导出一个值
export default
指定默认输出, 只能导出一个值, import无需知道变量名,就可以直接使用
export default 值 (将这个值,作为了当前模块的导出)
export default num
import 自定义变量名 from './a.js'
3.import ‘./index.js’导出
4.兼容和说明
只能在src文件里面写es6语法
5.webpack处理Vue组件
1.vue单文件组件的介绍
single-file components (单文件组件) 文件扩展名为.vue文件,需要安装vetur插件, 以前顶一个组件非常麻烦, 需要写template模板, 在里面写模板字符串, 但是有了单文件组件就不需要再写
单文件组件文档
优势:
- 完成语法高亮
- comoonjs模块
- 组件作用域的css
新建项目只需要复制之前的config package.json
新建pupblic文件目录,创建index.html文件
yarn安装依赖包
yarn dev启动
yarn add -D vue-loader vue-template-compiler
// webpack.base.js
const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {
module: {
rules: [
// ... 其它规则
{
test: /\.vue$/,
loader: 'vue-loader'
}
]
},
plugins: [
// 请确保引入这个插件!
new VueLoaderPlugin()
]
}
inex.html设置
<div id='app'>
不写任何结构代码
div>
不需要引入任何的包,将来html-webpack-plugin会自动打包
要引入任何的包,将来html-webpack-plugin会自动打包
在src中创建App.vue文件
src 中componets组件是通用的组件 ,可以全局注册 也可以局部注册 使用时注册当成标签使用
src中views是页面性质的组件,使用与跳转切换的, 需要配合路由使用的,一般都是大写
src中router放置路由规则
单文件组件
组件结构写在template麻烦 , 没哟提示, 默认导出方式默认写法忽略了样式
创建vue文件
<template>
</template>
<script>
export default {
return {
}}
</script>
<style>
</style>
创建views 文件夹, 存放Home.vue组件, 和Login组件 , 创建路由实例
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import Home from './views/Home.vue'
import Login from './views/Login.vue'
Vue.use(VueRouter) //都要使用
const router = new VueRouter({
routes: [
{
path: '/home', component: Home },
{
path: '/login', component: Login }
]
})
new Vue({
el: '#app',
// render函数用于渲染一个组件作为根组件(固定写法)
render (createElement) {
// 把App组件作为根组件
return createElement(App)
},
router
})
抽取路由代码 :将路由功能从main.js中抽取出来
新建router/index.js
文件
// 配置所有的路由的功能
// 模块化环境开发
import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from '../components/Login.vue'
import Home from '../components/Home.vue'
Vue.use(VueRouter)
const router = new VueRouter({
routes: [
{
path: '/login', component: Login },
{
path: '/home', component: Home}
]
})
export default router
修改main.js文件
import Vue from 'vue'
import App from './App.vue'
import router from './router'
new Vue({
el: '#app',
// render函数用于渲染一个组件作为根组件(固定写法)
render (createElement) {
// 把App组件作为根组件
return createElement(App)
},
router
})
6.vue-cli脚手架
概念 :命令行界面,俗称脚手架.只需要在命令行输入命令 就可以自动生成配置文件宣贯设置,
作用: 快速生成开发环境,以及对应的webpack配置,开箱即用
查看公司使用npm还是yarn,否则公司下载资源有冲突
1.步骤
1.全局安装脚手架
npm install -g @vue/cli
# OR
yarn global add @vue/cli
查看版本
vue --version 或者 vue -v
问题1:查看是否添加淘宝镜像
npm get registry
问题2:安装淘宝镜像
npm config set https://registry.npm.taobao.org/
注意上面安装的是vuecli3版本, 如果需要按照vuecli2方式初始化项目是不可以的,
问题3
报错 : 无法加载文件 C:\Users\Administrator\AppData\Roaming\npm\vue.ps1,因为在此系统中禁止执行脚本
方法1 :
- 打开 powerShell 用管理员身份运行 (很重要)
- 输入命令: set-ExecutionPolicy RemoteSigned
- 输入 A
- 再输入 vue -V (搞定)
方法2 : 找到本地路径删除 ps1文件删除
- C:\Users\xxxxx\AppData\Roaming\npm
2.创建一个项目
命令
vue create vue-demo
-
提示1:选择preset
? Please pick a preset: (Use arrow keys) 请选择一个 preset
default (babel, eslint) 默认设置
> `Manually select features` 手动设置 ( √ )2
提示2: 选择用户技术栈
空格是切换选中, 回车是完成
? Check the features needed for your project: 勾选你项目中用到的技术
(*) `Babel` `babel es6=>es5`
( ) TypeScript
( ) Progressive Web App (PWA) Support
(*) `Router` `路由 vue-router`
( ) Vuex
>(*) `CSS Pre-processors` `预编译 less`
( ) Linter / Formatter
( ) Unit Testing
( ) E2E Testing
- 提示3 : 是否使用history模式
? Use history mode for router? (Requires proper server setup for index fallback in production) (Y/n) ==> `输入 n`
? 是否使用 路由的 `histtory` 模式
- history模式 => 不带#
- hash模式 => 带# ( √ )
- 提示4 : 预编译
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): (Use arrow keys) 选择一个预编译css的方法
Sass/SCSS (with dart-sass)
Sass/SCSS (with node-sass)
> `Less` ( √ ) 根据你选择的 vue-cli 会下载合适的包和loader
Stylus
-
提示5 : 配置文件安置在何处
? Where do you prefer placing config for Babel, ESLint, etc.? (Use arrow keys)
Babel 和 ESLint 等等 配置文件放在哪里??
In dedicated config files 单独一个文件
> `In package.json` 都放在 package.json (√)
-
提示6 : 是否保存你的选择为一个 preset
Save this as a preset for future projects? (y/N) 是否保存你的选择作为一个preset
1. 输入 n => 不保存
2. 输入 y => 保存预设 并命名
Save preset as: xmg
预设保存在本地文件 : C:\Users\xxx用户名\.vuerc
- 提示7 : 安装成功,运行项目
� Successfully created project vue-demo.
� Get started with the following commands:
$ cd vue-demo
$ npm run serve
2.rem适配
1.安装rem适配插件,以后开发以375为标准
npm i lib-flexible
作用:根据屏幕添加fontsize
2.main.js引入rem插件
import 'lib-flexible'
3.安装postcss-px2rem
npm i postcss-px2rem
//作用:自动将px转换成rem
4.在vue.config.js中添加rem转换配置文件,配置完成之后重新启动
注意 remUnit
到公司怎么干
1.首先查看公司原型图 ,如果原型图是750,就是75,如果是375就是37.5
2.看到的设计图上的尺寸是多少px,就写多少px,rem会自动适配
//添加配置文件remUnit,如果公司设计稿是375就设置37.5,如果公司设计稿为750,就设置成75, 设计稿的1/10
3.登录功能
1.创建组件,先创建两个组件页面 Login.vue /Register.vue
‘ 组 件 = > 页 面 组 件 ( v i e w s / p a g e s ) 公 共 组 件 ( c o m p o n e n t s ) ‘ `组件=>页面组件(views/pages) 公共组件(components)` ‘组件=>页面组件(views/pages)公共组件(components)‘
页面组件都是通过路由控制显示的
公共组件都是通过全局注册,局部注册控制显示的
import VueRouter from 'vue-router'
Vue.use('VueRouter')
const router =new VueRouter({
routes:[]})
//导出
export default router
2.设置路由规则
- 引入页面login组件
- 设置router出口—–
- 配置路由规则,设置重定向redirect
3.封装components组件
- 头部组件封装HmHeader.vue
- 全局注册组件使用(main.js)
import Hmheader from '../component/HmHeader.vue'
Vue.component('hm-header', HmHeader)
- 在login中使用公共组件
在登录页登录
在注册页 注册
在hm-header添加 插槽是父组件向子组件传值
-
设置样式flex
-
封装logo组件
-
处理登录封装同时设置插槽
-
处理输入框
-
关于封装组件设置的步骤
创建
注册
使用
细化
4.scoped
作用: 由于是单页面应用, 会出现样式共享,解决组件中样式共享的问题,是当前组件的样式只对当前组件内的标签其效果
操作: 在当前组件里style里面添加scoped 添加之后会在属性样式
给vant 组件的类名设置样式时发现不起作用
原理
添加scoped之后 ,结构会添加data-v-xxx属性
样式通过属性选择器 h1[data-v-xxx]找到匹配的标签添加样式
在组件的根节点上添加 data-v -xxx 而设置的那个类在组件的内部, 没有这个属性,
.div [dta-v-xxx] {
margin:10px} //设置scoped之后, 样式变成了这种样式
深度作用选择器: 给引入的组件内部设置自定义样式
如果是css : >>>
如果是less sass : /deep/ 或者 ::v-deep .li
ul>>> .li{ margin:0px }
>>> .li
[data-v-xxx] .van-tabs_nav {margin:0px} 先父级属性为data-v-xxx , 再找组件里面的.li
总结: 以后组件中的标签scoped需要添加 ,如果是标签是没有任何影响的, 如果是组件内部设置样式, 需要设置深度样式选择器
5.vant -ui库
所有文档安装步骤进行从官网设置安装
1.安装vant
npm i vant Z
//在main.js引入vant组件
2.引入vant组件
设置自动按需引入
全局引入 不推荐
按需引入需要添加插件
安装babel插件npm i babel-plugin-import -D
配置插件 在更目录下babel.config.js中添加配置
根目录文件设置之后需要重启
注意数据名称后面添加注释
\
触底加载注意事项
- 获取数据的最小总高度需要大于页面长度
- finished , pageIndex 第几页,初始化 ,
- 数据初始化
- 设置设置下拉刷新时,和切换标签 时需要设置loading =true, 然后再调用获取数据的函数
- 切换标签式, 如果触底会触发onload事件, immediate-check 只在组件初始化时触发一次,即为点击进行页面
首先设置不触底加载, 但是设置的不触底加载为组件生成的时候不进行触底加载,
切换标签页后, vant会认为是滚动事件,会自动检测底部距离, 进行触底加载, 如果不需要可以设置成loading=false
4.登录按钮绑定登录事件, 父传子
方法1:
父传子注册事件, 同时button组件设置点击事件, this.$emit('click')
方法2:native修饰符 父传子的语法糖
直接在组件上使用@click.native
5.设置点击登录校验,向后台发送数据,进行校验
组件弹窗使用toast组件, 在组件中使用this.$toast('提示内容')
在main.js中使用Toast('提示内容')
登录是否成功以data中的statuscoede为准, 不是status
-
vant组件中list组件的使用
load-触底触发事件
offset -设置触底的距离,
immediate-check 是否立即检测, 如果初始数据内容不足一个屏幕大小 , 需要设置此参数,进行自动检查, 因为不足屏幕大小, 不能触发页面滚动, 也就不能检查时候触底
v-model=‘loading ’:用于指加载状态, 如果没有此数据, 满足条件后会一直触发loading事件:
如果为true—->正在加载中, 不会触发load事件
如果为false—–>当满足offset条件是会触发load事件
使用; 滚动触发,插件内部会自动修改loading:true, 正在加载数据
加载完成; 设置loading:false,写在ajax中
finished属性, boolean值, 当为true值, 不在进行加载,如果发送的数据长度小于设定的长度, 说明数据已经没了, 不在进行加载数据
finished-text=‘数据加载完毕, 已经没有数据了’
git
1.本地管理
五点半提交代码, 尽早提交代码,以防冲突,新建一个压缩包, 每天的写的代码自己压缩一个文件包, 自己保存下来
git log 查看日志
git init 初始化
git checkout -b 'dev'
创建dev分支
git status 查看当前状态
git add . 提交所有文件暂存区
git commit -m 'login页面完成'
提交仓库区
git checkout master
切换到主分支
创建远程仓库 —-注册登录
https和ssh
https每次推送需要输入用户名和密码
ssh不需要
已有仓库
设置一个别名
git remote add origin [email protected]:王万琦git
如果忘了切换sssh 一定要检查 git-开头的, 不是https
- 生成公钥——
码云官网=-====>点击生成公钥======>点击公钥管理=====>点击生成公钥===复制命令
-- ssh-keygen -t rsa -C '邮箱名称'
随便随便找个终端; 连续三次回车====> 见到火星文说明生成公钥成功
- 查看本地公钥和私钥, 只有公钥和私钥同步,才能免密
c\users\default\.ssh----> .ssh
id_rsa:私钥
id_rsa.pub: 公钥
赋值公钥代码, 找到官网, 添加输入密码
- 推送到远程仓库
//添加一个远程仓库.,并且给他起一个别名 mycangku
git remote add mycangku git邮箱
//推送远程仓库,推动到mycangku 的主分支 里面去
git pull 远程仓库地址 第一次上班, 下班走之前gitpulllay拉一下
git push -u mucangku master //添加-u 以后, 每次只需git push 就行, 相当于设置默认选项
- 分支操作
git branch
查看分支
git branch 'login'
创建分支
git checkout 'login'
切换分支
git branch -D 'login'
删除分支
git checkout -b 'login'
创建并切换分支
git checkout master
切换到主分支
git merge 'login'
将login分支与merge合并
git pull
每次git push 之前先git pull一下
5.axios设置
axios.get(url, config)
config :配置对象
参数对象,比如要删除哪一条id,GET没有数据
params:{id=1}
请求头对象
headers:{token}
axios.post(url, data, config) , post一般是添加/上传,需要有data请求体参数
axios.post(http://localhost:3000/login', {usernmae:""}, {params:{},headers:{}}
axios.put(url,data,config) 修改id 4的整个数据
axios.put(http://localhost:3000/login', {usernmae:""}, {params:{id=4},headers:{}}
axios.put(http://localhost:3000/login', null, {params:{id=4},headers:{}} //null站位
axios.delete(url, config)删除id 4数据
axios.delete(http://localhost:3000/login', {params:{id=4},headers:{}}
axioas处理
-
每次都要引入 —挂载原型
-
每次都要添加基准地址 –全局统一设置
将axios挂载到Vue原型上,每一个组件vue实例都可以使用了
import axios from 'axios'
Vue.prototype.$axios=axios
//使用的时候 this.$axios
axios.defaults.baseURL = 'http://localhost:3000'
图片地址更换 $axios,defaults.baseURL + info_user_img
拦截器:处理token
请求拦截器拦截所有axios请求,发送ajax请求
axios.interceports.request.use(config => {
if(token) {
config.header
}
}) //config代表设置axios中的config
,响应拦截器拦截响应-拦截失效的token信息, 比如修改密码
失效时登录无线循环问题
async添加处理
- async 必须加到最近的函数
- async必须和await成对出现
- 通过try{}catch((errror)=>{})进行捕获异常
6.页面跳转传值
1.字符串对象this.$router.push('/login')
2.对象传值
^方法一: 缺点:参数都放在url上面,数据暴露在url地址栏中^
this.$router.push({
path:"/login', query:{
username:this.username,
password:this.password
}})
方法二: 命名路由传值 , 如果不在router中设置name , 只写path:‘/login’不会传递
params传值是通过name属性进行查找传递的
路由规则中设置添加name属性
{
path: '/',
redirect: '/login',
meta: {
title: '登录页面' },
name: 'login',
},
// 跳转传值
that.$router.push({
path: '/login',
name: 'login',
params: {
username: that.username,
password: that.password
},
})
//接收传值
created () {
const {
username, password } = this.$route.params
console.log(this.$route);
if (username && password) {
this.username = username
this.password = password
}
},
7.头像图片压缩
一般用object-fit;cover
设置个人头像,用户上传的头像可能不是正常比例的,如果图片本来不是1:1比例的,设置width70,height70px ,会出现变性
object-fit
: cover cantin
object-fit:cover等比例缩放,保证短边完整,超出的部分上下对称截掉,保留中间部分
object-fit : contain; 等比例缩放, 保证长边能显示完整,可能部分显示不全,同时居中
8.moment时间过滤器
9.未登录访问页面
跳转之前进行判断token, 如果不是按部就班的点击跳转, 而是修改入口,上述方法就不行
如直接输入url地址
7.Authorization 验证 -token
1.token令牌
2.http请求是无状态的
登录跳转页面之后,后台不知道,因为没有记录
前段浏览器——–>后台服务器
登录成功(用户名,密码)——>加密生成token令牌——>保存到本地localStorage.setItem(‘mytoken’, token)—->解析token进行验证
以后在请求数据的携带token解析进行验证,在get请求中发送用户id , 同时在config对象中传递Authorization设置token
created () {
axios.get('http://localhost:3000/user/:id', {
headers: {
Authorization: localStorage.getItem('usertoken')
}
})
}
将获取到的数据进行保存到vue数据中 this.info = res.data
然后在模板中进行渲染,注意设置imgsrc是需要设置本地服务其中的地址,再进行与info中的数据进行拼接
通过设置v-if设置男女性别
8.导航守卫:直接在router.js设置导航守卫
作用:拦截页面之间的跳转
beforeEach 前置钩子, 路由跳转之前触发的钩子
从from跳转到to组件
to代表当前的路由规则
from代表上一个路由规则
next函数被调用之后才能进行下一个生命钩子
next('/login')可以更改跳转的组件,可以在这里面进行判断是否用户是否登录的密码,如果没有登录密码,需要重新回到;login页面
next(false)如果在跳转页面的时候,用户点击了取消,可以进行中断页面跳传操作
meta元数据 , 描述数据的数据
注意 router.beforeEach
只有在嵌套子路由中才有效果
router.beforeEach(function (to, from ,next ) {})
next函数内部自动调用next , 如果自己写reouter.beforeEach如果不使用next就是不会进行跳转路由
meta:元数据,在发送的route中设置 是一个对象,
this.$route({
path:'/login',
meta:{title:'登录页面'},
query: {username:"战三"}
})
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
import Login from './../views/Login.vue'
import Register from './../views/Register.vue'
const routes = [
{
path: '/login',
component: Login,
meta: {
title: '登录页面' },
},
{
path: '/',
redirect: '/login',
meta: {
title: '登录页面' },
},
{
path: '/register',
component: Register,
meta: {
title: '注册页面' },
},
]
const router = new VueRouter({
routes,
})
router.beforeEach((to, from, next) => {
document.title = to.meta.title //设置浏览器头部显示
next() //next()函数如果是自己设置必须执行, 如果不执行不会发生路由跳转
})
export default router
如果不显示,这样写
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VVEgkQ8y-1604141484257)(C:\Users\22359\AppData\Roaming\Typora\typora-user-images\image-20201009232042540.png)]
2.导航守卫补充
- 后置守卫(钩子)
router.afterEach()
跳转之后调用
after函数里面没有next函数
router.afterEach((to, from ) => {
console.log('aftereach')
})
router.afterEach
和router.beforeEach
被称之为全局守卫:
- 路由独享的守卫
写在一个routes规则里面 next()
必须调用才能进入下一个
const router new Vuerouter( {
routes: {
path:'/login',
component:Login,
beforeEnter:(to,from , next) => {
next() //必须调用
}
}
})
- 组件内的守卫
写在组件内,详情使用查文档数据
7.keep-alive遇见vue-router
组件内部所有的状态没有保留,如果进行切换,会发生组件初始化
keep-alive是vue内置的一个组件,也可以使被包含的组件保留状态, 或者避免重新渲染
router-view也是一个组件, 如果直接被包在keep-alive里面,所有路径匹配的视图组件都会被缓存
应用场景
:嵌套路由
当发生嵌套路由跳转的时候 , 发生调回原来页面的话,可以进行keep-alive回到嵌套路由的某一个路由页面
9.git命令项目
- 查看分支 g
10树状结构递归组件
树形结构数据: parent : {parent: {parent:{}}}
递归组件:组件内部使用组件自己
1.组件a里面使用组件b, b组件注册全局/局部/路由控制, ======>显示即可
2.组件a里面的模板里面使用a自己 ======> 添加name =‘aa’
3.注意v-if终止条件,因为递归有可能一直循环下去, 可能造成死循环
11.this.$refs.element
vue中的数据更改是同步的,但是数据渲染dom的过程是异步的,所以获取不到dom最新的元素
改成异步的
12.嵌套对象数据渲染 报错解决方案
detail.user.nickname 报错问题
数据渲染的时候, template模板会先编译一遍detail={} detail.user====> undefined undefined.nickname====>报错
解决方案: 1detail里面添加一个空对象,user:{}
data() {
return {
detail:{
user:{
}}}}
解决方案:2 在 { {detail.user.nickname}}<
13.nextTick
定义: 下次dom更新循环结束之后执行延迟回调, 在修改数据之后立即使用这个方法, 获取更新之后的dom
- 作为一个promise使用
- async getData() { await this. n e x t T i c k ( ) ; t h i s . nextTick() ; this. nextTick();this.refs.input.color=red}
14.keep-alive
作用: 用于保留组件状态或者避免重新渲染,
-
通过在组件中添加name属性进行指定需要保留组件状态的组件
-
imclude 字符串或者是正则表达式,只有名称匹配的组件会被缓存\
-
max 最多可以缓存多少组件实例, 超过数量时, 时间最长的未活跃的会被创建
-
-
如果需要指定son页面返回时 , father页面不会刷新, 但是从其他页面返回时刷新数据,需要在rotuer给som路由规则设置,通过keepalive为true
- 进行传值
{
path: '/detail/:id',
component: Detail,
meta: {
keepalive: true,
},
},
2.在father页面进行判断
// 判断上一次数据路由的
son -----> from beforerouteenteer to------> father
beforeRouteEnter(to, from, next) {
if (from.meta.keepalive) {
console.log('dtail路哟') //来的路径
console.log(to)
to.meta.keepalive = true
next()
} else {
to.meta.keepalive = false //此时路径
next()
}
},
- rotuer-view 出口 中 keepalive通过meta中的keepalive进行判断
keep-alive生命周期钩子 毁掉第一个第一个组件是或组件是或组
activated : 被keep-alive缓存的组件激活时调用 , 进入组件
deactivated: 被keep-alive缓存的组件失活时调用, 离开组件
//从本地获取 此处是缓存后切换显示时调用activated
//created====>gettablist 从本地获取, 页面刷新时调用
15.回滚
如果划到底部,点击发表评论后想看到刚发表的内容 (滚动到某个位置)
- 在 评论列表的上面, 添加一个空盒子
- 发表评论成功, 跳转到该位置
this.$refs.box.scrollIntoView()
16.搜索页面
如果本地存储获取不到, 会返回null 或者undefined --不确定
如果本地存储设置grandfather----> father------>son 如果father不存在, 并且设置son 会报错
17pc端
pc端后台管理 登录页面
项目创建准备 vue create pc01
2. 官网视频设置 拉取2.x模板(旧版本)
npm install -g @vue/cli-init //或者vue init
vue init webapck my-project
3.基于3.x版本的脚手架创建vue项目
1基于交互式命令行的方式创建新版vue项目
vue create my-project
2基于图形化界面的方式,创建新版vue项目
vue ui
3基于2.x的旧模板 ,创建旧版vue项目
npm install -g @vue/cli-init
vue init webpack my-project
4.vue脚手架的自定义配置
1.通过package.json配置项目
必须是符合规范合法的json语法,在最底部设置
"vue" :{
"devServer": {
"port":"8000",
"open": true}
}
2.以上做法不推荐, 单独定义到vue.config.js文件中国进行配置
在项目根目录文件创建vue.config.js
在改文件中农进行相关配置,从而覆盖法默认配值
module.exports = {
devServer: {
port: 8888,
open: true
}
};
7.element-ui基本使用
vue2.0的桌面组件库:省省略美化样式的时间
1基于命令行方式的手动安装
步骤:
1.安装依赖包 npm i element-ui -S
2.导入Element-UI相关资源
//导入组件库
import ElementUI from 'element-ui';
//导入组件相关样式
import 'element-ui/lib/theme-chalk/index.css
//配置Vue插件
Vue.use(ElementUI)
2.基于图形化界面自动安装
- 运行
vue ui
命令
- 通过
vue项目管理器
计入具体的项目配置面板
- 点击
插件 添加插件
进入插件查询面板
- 搜索
vue-cli-pligin-element
并安装
- 配置插件, 实现按需导入, 从而减少打包的项目的体积
vue.config.js中关闭语法检测
lintOnSave:false,
devServer: {
overlay:{
warning:false,
errors:false
},
...
}
前项目技术栈
vue
vue-router
element-ui
axios
echarts
后端技术栈
node.js
express
jwt //状态保持工具,实现登录记录功能
mysql
sequelize 前后端项目分离模式
8.前段项目
1.项目初始化
- 安装vue脚手架
- 通过vue脚手架创建项目 vue ui创建项目
- 配置vue路由
- 配置element-ui 组件库
- 配置axios库,安装axios依赖,运行依赖
- 初始化git远程仓库
- 将本地项目托管到github或者码云中
步骤
###git ee安装公钥
添加公钥成功之后, 在终端输入
ssh -T git@gitee.com
是否添加到可信任列表中
yes
gitee上传绑定邮箱账号
账号 :wangwanqi999
密码 :wangwanqi999
后台环境安装配置
安装mysql数据库
安装node.js环境
配置项目相关信息
启动项目
使用postman测试后台项目接口是否正常
启动数据库 解压apiserver,导入数据
在apiserver目录下运行npm install命令,安装依赖包
上述
模块化语法
1.下载安装配置node.js版本文件
2.下载安装git
git需要path路径,配置密匙
点击右下角图标 —— ctrl shift p 输入git 命令,将选中的分支合并到当前分支
1.vs创建分支
点击创建新的分支, 输入分支名称.点击云图标,上传至git
3.安装插件
vue ——高亮语法
3创建项目
vue ui 创建项目 安装lint 开发依赖
4.安装
5本地存储
cookie , storage 区别
- 存储大小 : cookie 存储4k(有时候存储大量的报文. 内存不够) , storage 5m
- 有效期: cookie拥有有效期,过期之后cookie会自动消失, 存储在内存中, storage只存储在浏览器端
- 路径:cookie有路径限制, storage只 pi: cookie没有特定的api , storage有对应的api
- cookie会自动发送到服务器端, 用作用户唯一凭证 , storage只存储在域名下
6.接口统一拦截
- 统一报错
- 未登录统一拦截 返回login页面
- 请求值, 返回值统一处理
get请求传参用params post传参没有params
axios.all同时发送多个请求 , 封装函数, 设置返回值
7.接口环境设置
- 开发上线的不同阶段,需要不同的配置 ----不同的阶段接口是不同的
- 不同的跨域方式配置不同 -----设置跨域方式统一更改
- 打包的饿时候统一注入环境参数,统一管理环境,输出不同的版本包
–mode配置参数将环境变量给项目
conrs环境下配置 不同跨域方式配置
"serve": "vue-cli-service serve --mode=development",
"build": "vue-cli-service build --mode=production"
// 环境配置文件 创建env.js文件
// 进行判断时进行什么方式的跨域处理
let baseURL
switch (process.env.NODE_ENV) {
case 'development':
baseURL = 'http://dev-mall-pre.springboot.cn/api'
break
case 'test':
baseURL = 'http://test-mall-pre.springboot.cn/api'
break
case 'prev':
baseURL = 'http://prev-mall-pre.springboot.cn/api'
break
case 'prod':
baseURL = 'http://mall-pre.springboot.cn/api'
break
default:
baseURL = 'http://mall-pre.springboot.cn/api'
break
}
export default {
baseURL,
}
如果是proxy代理方式不需要设置, 需要改 vue.config.js中转接地址
8.mock设置模拟数据
- 本地创建json
- easy-mock平台
- 继承mock-api
ebpack my-project
### 4.vue脚手架的自定义配置
`1.通过package.json配置项目`
```js
必须是符合规范合法的json语法,在最底部设置
"vue" :{
"devServer": {
"port":"8000",
"open": true}
}
2.以上做法不推荐, 单独定义到vue.config.js文件中国进行配置
在项目根目录文件创建vue.config.js
在改文件中农进行相关配置,从而覆盖法默认配值
module.exports = {
devServer: {
port: 8888,
open: true
}
};
7.element-ui基本使用
vue2.0的桌面组件库:省省略美化样式的时间
1基于命令行方式的手动安装
步骤:
1.安装依赖包 npm i element-ui -S
2.导入Element-UI相关资源
//导入组件库
import ElementUI from 'element-ui';
//导入组件相关样式
import 'element-ui/lib/theme-chalk/index.css
//配置Vue插件
Vue.use(ElementUI)
2.基于图形化界面自动安装
- 运行
vue ui
命令
- 通过
vue项目管理器
计入具体的项目配置面板
- 点击
插件 添加插件
进入插件查询面板
- 搜索
vue-cli-pligin-element
并安装
- 配置插件, 实现按需导入, 从而减少打包的项目的体积
vue.config.js中关闭语法检测
lintOnSave:false,
devServer: {
overlay:{
warning:false,
errors:false
},
...
}
前项目技术栈
vue
vue-router
element-ui
axios
echarts
后端技术栈
node.js
express
jwt //状态保持工具,实现登录记录功能
mysql
sequelize 前后端项目分离模式
8.前段项目
1.项目初始化
- 安装vue脚手架
- 通过vue脚手架创建项目 vue ui创建项目
- 配置vue路由
- 配置element-ui 组件库
- 配置axios库,安装axios依赖,运行依赖
- 初始化git远程仓库
- 将本地项目托管到github或者码云中
步骤
###git ee安装公钥
添加公钥成功之后, 在终端输入
ssh -T git@gitee.com
是否添加到可信任列表中
yes
gitee上传绑定邮箱账号
账号 :wangwanqi999
密码 :wangwanqi999
后台环境安装配置
安装mysql数据库
安装node.js环境
配置项目相关信息
启动项目
使用postman测试后台项目接口是否正常
启动数据库 解压apiserver,导入数据
在apiserver目录下运行npm install命令,安装依赖包
上述
模块化语法
1.下载安装配置node.js版本文件
2.下载安装git
git需要path路径,配置密匙
点击右下角图标 —— ctrl shift p 输入git 命令,将选中的分支合并到当前分支
1.vs创建分支
点击创建新的分支, 输入分支名称.点击云图标,上传至git
3.安装插件
vue ——高亮语法
3创建项目
vue ui 创建项目 安装lint 开发依赖
4.安装
5本地存储
cookie , storage 区别
- 存储大小 : cookie 存储4k(有时候存储大量的报文. 内存不够) , storage 5m
- 有效期: cookie拥有有效期,过期之后cookie会自动消失, 存储在内存中, storage只存储在浏览器端
- 路径:cookie有路径限制, storage只 pi: cookie没有特定的api , storage有对应的api
- cookie会自动发送到服务器端, 用作用户唯一凭证 , storage只存储在域名下
6.接口统一拦截
- 统一报错
- 未登录统一拦截 返回login页面
- 请求值, 返回值统一处理
get请求传参用params post传参没有params
axios.all同时发送多个请求 , 封装函数, 设置返回值
7.接口环境设置
- 开发上线的不同阶段,需要不同的配置 ----不同的阶段接口是不同的
- 不同的跨域方式配置不同 -----设置跨域方式统一更改
- 打包的饿时候统一注入环境参数,统一管理环境,输出不同的版本包
–mode配置参数将环境变量给项目
conrs环境下配置 不同跨域方式配置
"serve": "vue-cli-service serve --mode=development",
"build": "vue-cli-service build --mode=production"
// 环境配置文件 创建env.js文件
// 进行判断时进行什么方式的跨域处理
let baseURL
switch (process.env.NODE_ENV) {
case 'development':
baseURL = 'http://dev-mall-pre.springboot.cn/api'
break
case 'test':
baseURL = 'http://test-mall-pre.springboot.cn/api'
break
case 'prev':
baseURL = 'http://prev-mall-pre.springboot.cn/api'
break
case 'prod':
baseURL = 'http://mall-pre.springboot.cn/api'
break
default:
baseURL = 'http://mall-pre.springboot.cn/api'
break
}
export default {
baseURL,
}
如果是proxy代理方式不需要设置, 需要改 vue.config.js中转接地址
8.mock设置模拟数据
- 本地创建json
- easy-mock平台
- 继承mock-api