vue项目结构
前置准备
1.node.js
2.vue-cli
3.创建项目:
-vue ui
-vue create 项目名
项目名不能是纯vue作为名字
项目结构
node_modules//依赖 插件包 可以删,因为包里面的插件全部是在一个网站里npmjs.com
【重点】public //公共目录,存放着我们唯一的html模板
【重点】src //源代码,项目的核心所在,不能删也不能改名字
.gitignore //git过滤清单
babel.conf.js //解析es6转成es5的插件配置
【重点】package.json // 包管理器文件,存放着依赖的名字,运行项目的命令
README.md //项目的说明书
初始化项目依赖
当我们拿到别人的项目的时候一般情况下是没有node_modules包,需要使用命令初始化依赖
npm install
or npm i
yarn install
【前提!】项目里必须有package.json
指令
v-model
数据双向绑定,用于表单元素
v-text
渲染文本内容的 插值{{}}等价
v-html
渲染dom片段,且拥有v-text全部特性(防注入攻击,自动过滤)
v-noce
让元素只显示第一次渲染的内容,之后不再受数据更新的影响
v-if
有三条同组指令:v-if v-else-if v-else,控制元素加载与销毁,v-if可以单独使用,后面两个必须跟在v-if后面才能生效
如果链式使用v-if则其中一条规则符合条件剩余的判断不会执行
v-show
控制元素的显示与与隐藏,底层原理是修改的css样式的display的属性(如果频繁切换应使用v-show)
[注意]频繁切换显示隐藏优先显示v-show,这样可以避免页面的回流,减少浏览器的性能开销
v-for
语法:<div v-for='(value值,index下标) in arr' v-bind:key='index'>{{value}}</div>
–特性必须在被循环的元素上加key,且key的值对元素是隐藏的,只是给diff算法用的;
【不要在循环元素使用v-if】
–循环渲染为什么要加key:v-for语法中循环渲染虚拟dom时使用diff算法计算中用于优化算法的。key必须保证在作用域中每一个值都是唯一不可重复的。
官方不推荐使用下标,且不可以使用时间戳,随机数
–作用:每个元素拥有独立的key值,key相当于人类的身份证(key值是唯一的)
推荐使用value+sshkey,sshkey=index || value+value2
v-for渲染值类型
数组,对象(value,key,index),字符串,数字
渲染对象 v-for=’(value值,key属性名,index下标) in obj’ v-bind:key=‘index’
diff算法
渲染快的原理:当数据发生改变的时候会生成新的虚拟dom树(object)。层层对比,用新的节点对比旧的节点,一旦发现不一样的节点就直接用新的替换旧的
v-bind
绑定属性指令,简写 : ,它用来给元素绑定动态属性,一旦使用,里面的值必须是一个数据变量,如果是字符串必须使用引号引起来,它既可以绑定原生属性,也可以绑定自定义属性,一般情况下,自定义属性用来组件通讯
v-on
绑定事件指令,简写@
循环渲染
语法
1.渲染数组v-for=’(value值,index下标) in data’ v-bind:key=‘index’
可以遍历的值类型
数组,对象,字符,串数字
2.渲染对象 v-for=’(value值,key属性名,index下标) in obj’ v-bind:key=‘index’
3.【注意】被循环的元素上必须加上key(key值不能重复)
4.循环渲染为什么要加key:v-for语法中循环渲染虚拟dom时使用diff算法计算中用于优化算法的。key必须保证在作用域中每一个值都是唯一不可重复的。
官方不推荐使用下标,且不可以使用时间戳,随机数
推荐使用value+sshkey,sshkey=index || value+value2
5.作用:每个元素拥有独立的key值,key相当于人类的身份证(key值是唯一的)
diff算法
渲染快的原理:当数据发生改变的时候会生成新的虚拟dom树(object)。层层对比,用新的节点对比旧的节点,一旦发现不一样的节点就直接用新的替换旧的
事件
事件的绑定
v-on:eventName
简写@eventName
事件的回调函数来自于methods里的函数
事件修饰符
- .stop 阻止事件冒泡
- .prevent 阻止默认事件
自定义按键修饰符
Vue.config.keyCodes.back = 8
props : 属性
属性是父组件传进来的数据,子组件不能直接修改
props和data数据很相似,都是属于存放数据的
props只接受属性,函数不能在这里接收
按键修饰符
.enter或者.13监听回车
自定义按键修饰符
Vue.config.keyCodes.myCode=keyCodes
生命周期
概念
初始化,完成渲染,更新页面,卸载页面(销毁程序)===程序
定义
事物在不同阶段的不同表现,叫做生命周期。
即初始化,挂载,更新,销毁四个阶段
api
初始化/创建阶段
-beforeCreate 创建前
-created 创建后
挂载/渲染阶段
-beforeMount 挂载前
-mounted 挂载完成
更新阶段
-beforeUpdate 更新前
-updated 更新后
卸载/销毁阶段
-beforeDestroy 卸载前
-destroyed 卸载后
总结
1.生命周期里,mounted用于组件渲染完成后发起的ajax请求(里面写我们要获取的数据)
2.beforeDestroy用于组件销毁前清除常驻内存的数据
server就是在内存打包后的build代码
如果把图片地址赋给变量,需要用require语法
require就是nodejs导入模块的意思
等价于import
组件
局部组件
在单独的vue文件里使用components注册的组件
只能在当前组件内使用,叫做局部组件
全局组件
使用全局Vue对象的component方法注册的组件,
可以在任意的vue文件使用,叫做全局组件
$开头的变量都是vue内置的
ref就是获取dom元素的
组件通讯
props属性
1.普通写法:props:['p1','p2']
2.配置写法:
export default{
props:{
//简单验证
props:string,
//设置默认值
obj:{
//如果是对象或数组使用函数
type:Object,
default:function () {
return {
}
},
//简单的初始值
count:{
type:string,
}
}
}
3.注意的是在子组件内修改简单类型的值props会报错,
如果修改的是对象或数组里的值,则不报错
4.定义:props是上游组件传递的数据,子组件不可以修改
5.props是父传子最常见的通信方式
父传子
1.父组件向子组件通过绑定属性,传递一个数据
子组件通过props接收父组件传递的属性值(数据)
2.$children
获取所有子元素的集合,直接操作子元素或调用子元素的方法【不推荐】
子组件
1.常规方式 e m i t 调 用 父 级 传 过 来 的 函 数 2. emit调用父级传过来的函数 2. emit调用父级传过来的函数2.parent获取父组件实例对象,直接修改或调用【非常不推荐,别使!!!】
双向通讯
v-model
作用:使父子组件进行双向的修改,双向的伪绑定
语法:1.父传子v-model绑定带子组件上
2.子传父:this.
e
m
i
t
(
′
i
n
p
u
t
′
,
n
e
w
D
a
t
a
)
概
念
:
当
我
们
在
子
组
件
上
使
用
v
−
m
o
d
e
l
绑
定
值
的
时
候
会
自
动
的
向
子
组
件
注
入
一
个
v
a
l
u
e
值
和
一
个
i
n
p
u
t
函
数
子
组
件
如
果
想
修
改
v
a
l
u
e
就
是
用
emit('input',newData) 概念:当我们在子组件上使用v-model绑定值的时候 会自动的向子组件注入一个value值和一个input函数 子组件如果想修改value就是用
emit(′input′,newData)概念:当我们在子组件上使用v−model绑定值的时候会自动的向子组件注入一个value值和一个input函数子组件如果想修改value就是用emit调用input函数名
.tirm:去掉两头空格
.number:尝试把输入内容转成数字
.lazy:当失去焦点时赋值
.sync 属性修饰符
作用:使父子组件进行双向的修改,双向的伪绑定
语法:1.父传子:叫v-bind:prop.sync=‘prop’
2.子传父:this.$emit(“update:prop”,nweData)
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' v-bind:data='data '></slot>
<!-- 父组件 -->
<template v-slot:header='data'>{{data}}</template>
匿名插槽作用域
–父组件
<template v-slot:dafault="data">{{data}}</template>
–子组件
<slot data="一个固定值"></slot>
计算属性和监听
watch监听器 侦听器
概念
用来监听数据data或属性props的
当被监听的值发生改变后会触发相应的方法
定义
对数据进行监听
语法
简单类型数据
watch:{
value(newVal,oldVal){
console.log("新",newVal)
console.log("旧",oldVal)
}
}
对复合型数据进行监听
//对象
object:{
handler(val,oldVal){}
deep:true
}
//监听对象里的某一个属性,用点语法
'obj.prop'(val){
}
//数组
object:{
handler(val,oldVal){}
deep:true
}
//自动执行一次
arr: {
handler(val) {
console.log(val)
},
deep: true,
//默认自动执行一次
immediate: true,
},
computed计算属性
对数据data或props属性进行监听,并返回一个新值
计算属性不受数据类型影响
计算属性必须使用,不然不会触发
初始化时就会执行,自动执行一次
修改计算属性
computed:{
value:{
get(){
return this.data
},
set(str){
this.data=str;
}
}
}
计算属性和监听的异同
相同
都是对数据或属性进行监听,都可以在数据或属性被修改时做出响应
不同
watch是对数据进行监听,并且受数据类型影响,如果监听的是数组或者对象,需要开启深度监听
computed监听数据并返回一个数据,如果监听属性没有使用,那么该属性永远不会执行。计算属性不受数据类型影响
缓存
<keep-alive>
是vue内置组件的一种,用于缓存组件状态的,保证在不刷新页面的情况下,使被销毁的组件保留操作状态
- 特性:缓存状态存在内存中,刷新页面时就丢了
- 凡是被包裹在keep-alive中组件默认都会被缓存
exclude排除
将exclude里的组件不缓存其余都缓存
- 字符串
exclude='Dom'
orexclude='Dom,Dom2'
-数组
:exclude=['Dom','Dom2']
-正则
:exclude=/Dom/
include包含
只对包含的组件进行缓存,非include的组件不缓存
动态组件
<component v-bind:is="init"></component>
定义:内置组件的一种,用于动态加载注册在component里的组件
特点:简介优雅方便
解决的问题:原始写组件切换,需要在每个子组件上写v-if语句,如果该组件的名字被修改了,那么修改的地方很多,使用component动态加载组件就可以减少修改
【重要】必须要有is属性,该组件基于is属性动态加载
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
自定义
过滤器filter//[注释]frtrs
组件内过滤器是使用filters
全局过滤器使用filter
定义
过滤器把一个值接收处理完毕后返回新值
语法
- 使用
``{{ value | filterName | filterName2}}
多个过滤器用“|”管道符隔开 - 声明:
filters:{
filterName(value){
return value+100
}
}
全局过滤器
//声明
import Vue from 'vue'
Vue.filter("filterName",(value)=>{
return value/3
})
自定义指令
有些情况下,需要获取dom的时候,如果不用ref,就是用自定义属性
举例:页面打开后,让input获取焦点
组件内的
directives//[注释]diruaikets
语法
//声明
directives:{
focus:{
//初始绑定一次
bind(){},
//解除指令绑定
unbind(){},
//更新所有子组件和自己
componentUpdated(){},
//优先更新自己
update(el,binding){},
//元素渲染成功后的生命周期
inserted(el,binding){
el.focus()
}
}
}
//使用
<input v-focus>
全局
import Vue from 'vue'
Vue.directives("focus",{
inserted(el, binding){
el.focus()
//赋值
el.value = binding.value
}
})
// 使用
<input v-focus="'content'">
quest与cors
axios
- 安装:
npm i axios
yarn add axios
跨域
- jsonp:动态创建script标签,使用src属性请求接口jsonp.js
- vue.config.js 配置跨域 proxy:‘第三方接口地址’
页面请求的时候,/就表示proxy的代理接口
proxy: {
"/api": {
target: "https://www.ivsky.com/index.php",
changeOrigin: true, // 允许跨域
pathRewrite: {
'^/api': ''
}
}
}
关闭map映射
每次build打包的时候,默认是会编译出源码映射文件map,它的目的是为了调试代码用的,但是从性能上来说,每次打包都要打包它,浪费时间还可能泄漏源码
productionSourceMap:flase;