vue项目结构
前置准备
1.nodejs 2.vue-cli 3.创建项目:vue ui vue create 项目名(不能用纯VUE做名字)
项目结构
- node_modules //依赖 插件包 可以删 包里的插件全部在一个网站里
- 【重点】public //公共目录,存放着唯一的html模板
- 【重点】src //源代码 项目的核心所在,不能删也不能改名
- .gitignore // git过滤清单
- bable.conf.js //解析es6转成es5的插件配置
- 【重点】package.json //包管理器文件,存放着依赖的名字
- README.md //项目说明书
初始化面目依赖
当我们拿到别人的项目的时候,一般情况下是没有node_modules包。需要使用命令去初始化依赖。
`npm install` `yarn add`
- 【前提】项目里必须有package.json
开发规范
1.assets存放静态资源的
2.components存放组件的,公共组件等
3.views存放视图组件的,表示独立的页面
命名规范
1.函数命名:fn_name
2.对象:o_name
3.数组:a_name
4.字符串:s_name
5.数字:n_name
6.小组合作开发的时候,页面的名字_+功能的名字_+自己名字的缩写_+工号
指令
v-model
- 数据双向绑定指令,用于表单元素。
v-text
- 渲染文本内容的和插值
{{}}
等价 权重方便v-text优先于插值{{}}
v-html
- 渲染dom片段的,且拥有v-text的所有功能
v-once
- 让元素只显示第一次渲染内容,之后不在受数据更新的影响 注意:name里需要给值
v-if v-else-if v-else
- 有三条同组指令:v-if v-else-if v-else
控制元素加载与销毁;
v-if可以单独使用,后面两个必须跟在v-if后面才能生效
如果链式使用v-if,则其中一条规则复合条件,剩余的判断则不会执行
v-show
- 控制元素显示与隐藏,底层原理是修改的css样式的display属性
【注意】如果频繁切换应该优先使用v-show,这样可以避免页面的回流,减少浏览器的性能开销。
@click
- 点击事件
v-for
语法:<div v-for="(value,index) in arr" v-bind:key="index">{{value}}</div>
特性:必须在被循环渲染的元素上加key,且key的值对元素是隐藏的,只是给diff算法用的
不要在循环元素使用v-if
渲染值类型:字符串,数字,数组,对象
v-bind
- 绑定属性指令,简写 “:”,一旦使用里面的值必须是一个数据变量,如果是字符串必须使用引号引起来
既可以绑定原生属性,也可以绑定自定义属性,一般情况下,自定义属性用来组件通信
v-on
- 绑定事件指令 简写"@" ,用来处理事件响应操作的写在methods里的自定义函数
循环渲染
语法:v-for="(value,index) in data" v-bind🔑=“index”
data=[1,2,3]
1.渲染数组 v-for=’(value,index) in data’
2.渲染对象 v-for=’(value,key,index) in obj’
3.【注意】被循环的元素上必须加key 不要加v-if
可以遍历的值类型
数组,对象,数字,字符串
为什么加key?
用于虚拟dom的diff算法优化,且key在相对作用域里必须保持唯一值。
官方不推荐使用下标,且不可以使用时间戳,随机数。
推荐使用value+sshkey,sshkey= index || value + value2
key必须保证在作用域中每一个值都是唯一不可重复的。
作用:每个元素拥有独立的key值,key相当于人类的身份证
diff算法
渲染快的原理:当数据发生改变的时候,会生成新的虚拟dom树(object)
层层对比,用新的节点对比旧的节点,一旦发现不一样的节点就直接用新的替换旧的
事件
事件的绑定
v-on:eventName简写@eventName
事件的回调函数来自于methods里的函数
事件修饰符
.stop阻止事件冒泡 .prevent阻止默认事件
按键修饰符
.enter 或.13 监听回车
自定义修饰符
Vue.config.keyCodes.myCode=keyCodes
定义
- 生老病死= = =人的生命周期
初始化 完成渲染 更新页面 销毁程序===程序的生命周期
定义
- 事物在不同阶段的不同表现叫生命周期
初始化 挂载 更新 销毁的四个阶段
api
初始化/创建阶段
beforeCreate 创建前 created 创建后
挂载/渲染阶段
beforeMount 挂载前 mounted 挂载完成
更新阶段
beforeUpdate 更新前 updated 更新后
卸载/销毁
beforeDestroy 销毁前 destroyed 销毁后
总结
- 生命周期里:
1.mounted用于组件渲染完成后发起的ajax请求
2.beforeDestroy用于组件销毁前清除常驻内存的数据
//一次性生命周期
//创建
beforeCreate() { //骨架屏技术 console.log('创建前') }, created() { //ajax可以写这里,但非常不推荐 //vue里面有一个服务端渲染,在使用服务端渲染的时候,beforeMount,mounted两个函数失效--不会执行 //爬虫--seo:只爱爬写死的静态页面 console.log('创建后') }, //挂载 beforeMount() { console.log('挂载前') }, mounted() { //页面渲染成功后,发起ajax请求 console.log('挂载后') }, //更新:props和data数据发生修改,触发 beforeUpdate() { //更新前函数中可以修改data this.count++ console.log('更新前') }, updated() { //更新后的函数中只能用于观察修改后的data console.log('更新后', this.count) }, //销毁 beforeDestroy() { console.log('销毁前') }, destroyed() { console.log('销毁后') }, }
form
专属指令
v-model
标签类型
input
文本 text
密码 password
日期 date
数字 number
单选框 radio v-model绑定的是它的value值
多选框 checkbox
按钮 button
select
v-model加在select标签上但是获取的值是来自于包裹的option标签上的value值
textarea 文本域 v-model
组件
局部组件
- 在单独的vue文件里使用components注册的组件
只能在当前组件内使用,叫做局部组件
全局组件
- 使用全局Vue对象的component方法注册的组件
可以在任意的vue文件里使用,叫全局组件
安装element-ui命令
yarn add element-ui
- 如果修改element样式不生效,需要使用/deep/或>>>
深度选择器,去修改
css使用/deep/ scss使用>>
组件通信
props属性
1.普通写法:
props:['props1','props2']
2.配置写法:
exprot default{ props:{ //设置默认值 obj;{ //如果是对象或数组使用函数 type:Object, default:function(){ return {} } } //简单的初始值 count:{ type:Number, default:100, } } }
3.注意的是:在子组件内直接修改简单类型值的props会报错,但是如果修改的值是对象和数组里的值,不会报错
4.定义:props是上游组件传递的数据,子组件不可修改
5.props是父传子最常见的通信方式
props父传子
- 父组件向子组件通过绑定属性传递一个数据
子组件通过Props接收父组件传递的属性值
$childern获取子元素直接操作子元素或调用子元素的方法【非常不推荐】
$emit子传父
1.常规方式e m i t 调 用 父 级 传 过 来 的 函 数 2. emit调用父级传过来的函数 2.emit调用父级传过来的函数2.parent获取父组件实例对象,直接修改或调用【非常不推荐】
双向通信
v-model
作用:使父子组件进行双向的伪绑定
语法:
1.父传子
v-model绑定到子组件上
2.子传父
this.$emit('input',newData)
概念:当我们在子组件上使用使用v-model的时候,会自动的向子组件注入一个value值和input函数,
子组件如果想修改value就是用$emit调用input函数名
.sync 属性修饰符
作用:使父子组件进行双向的伪绑定
语法:
1.父传子:
v-bind:prop.sync='prop'
2.子传父:
this.$emit('updata:prop',newData)
props 父传子【常用】
$emit & $on 子传父【常用,来自于自定义事件】
$parent & $children【应急方案,不推荐】
$attrs & $listeners【夸组件层级,简单,推荐】
provide & inject【开发高阶组件,不推荐。跨组件层级】
vuex【强大,适合大项目,跨组件层级】
slot插槽
定义
- 模块化高复用的组件模板,接收一定的值并输出一定的值
匿名插槽
- 父组件
<Myslot>内容或标签</Myslot>
子组件接收
<slot></slot>
具名插槽
- 根据插入内容的名称匹配接收,可灵活控制期渲染位置等
父组件传递
<template v-slot:header> 内容或标签 </template>
子组件接收
<slot name='header'></slot>
插槽作用域
具名插槽作用域
插槽的内容或标签实际上的作用域还是属于父组件的,比如样式绑定
但是在子组件的slot标签上传参默认父组件不能直接使用
父传子
和常规传参一样在子组件上绑定属性子组件用props接收
子传父
// 子组件 <slot name='header' :data='data></slot> // 父组件 <template #header='data'>{{data}}</template>
匿名插槽作用域
父组件
<template v-slot:default="{ data }"> <h1>{{ data }}</h1> </template>
子组件
<slot data="李云龙"></slot>
vuex
定义
全局状态管理器
组成部分
- strict 严格模式,默认非严格
非严格模式下,state可以被任意修改
mutations可以执行异步
state 状态数据
数据双向响应
- getters 对state计算出来的新值
- mutations 用于修改state的同步函数
使用commit方法调用mutation
- actions 执行异步且只能调用mutations函数来修改state
使用dispatch调用action
- module 模块化store
干什么的?
切割vuex,让每个独立使用store的页面拥有自己的store
什么时候用?
比如电商项目,每个页面除了使用全局的用户信息外,还有额外的自己独立页面使用的状态。
尤其是当小组开发的时候,避免冲突,使用模块化
- plugins 插件
让vuex拥有没有的功能,比如,vuex的数据是存在内存中的,刷新页面会丢。
使用vue-persist插件将数据存入本地,当刷新页面的时候优先从本地读取
vuex执行 | 工作流程
state到组件,组件通过dispatch调用actions进行通信,actions通过commit调用mutations修改state,
state是双向数据响应的,会自动让组件更新
辅助函数
{mapState},{mapGetters},{mapMutations},{mapActions}
# router
路由定义
根据不同的地址呈现不同的内容或页面
路由三大组件部分
导航 router-link
视图 router-view
配置 router
路由router
表示当前项目全局的路由实例对象
线路route
表示当前路由页面的信息对象
路由的跳转方式
声明式导航
router-link
编程式导航
$router.push()
路由的跳转方法
push() 向历史记录添加一条
go() 通过数字控制前进后退
back() 返回上一个历史记录
replace()用最新地址替换当前历史记录
路由的模式
hash history abstract
路由传参
params 动态路由是显式传参,非动态路由使用params传参叫隐式传参
隐式的参数在内存里,刷新页面就丢了。params传参只能通过命名路由name跳转
meta 元数据,用于传参,更多情况下用于配置路由的权限
query 以?开头的get请求传参方式
路由类型
动态路由 一组拥有相同基础路径的路由,加载的是同一个页面
嵌套路由 一组拥有相同基础路径的路由,加载不同的页面
路由拦截器
每个路由守卫都有一个回调函数,该函数里有三个参数,分别是to,from,next
全局
beforeEach 前置守卫
afterEach 后置守卫 没有next
组件
beforeRouteUpdata 准备路由更新
beforeRouteLeave 准备离开路由
路由配置的api
name: 路由命名,给路由取名字
path: 匹配浏览器地址栏里的地址
component:加载组件
alias:给路由取别名 区别:地址栏不显示地址
redirect: 重定向 区别:地址栏显示地址
meta:元数据,用于路由配置里的传参
children:嵌套路由的api
{ path:'/book/:id', component:Book, children:[ { path:'hot', component:Hot } ] }
路由实例配置
mode
router
scrollBehavior