对于Vue的初步学习

对于Vue的初步学习,第1张

注意

目录

注意

js表达式和js代码

初始Vue

模板语法(插值和指令)

数据绑定(v-bind和v-model)

el和data的两种写法

MVVM模型

Object.defineProperty

数据代理

事件处理

事件的基本使用

事件修饰符

键盘事件

计算属性(computed)

监视属性(watch)

computed和watch之间的区别

绑定class样式(bind)

绑定style样式(bind)

条件渲染(指令)

列表渲染

列表过滤

列表排序

数组中响应式的方法

key的作用和原理

Vue监视数据的原理 (响应式)

收集表单数据( v-model )

过滤器

高阶函数( filter / map / reduce )

内置指令

v-bind(涉及到上面的绑定class样式和style样式)

v-on(事件监听)

v-model

自定义指令

生命周期

生命周期总结

组件

组件化思想

组件注意点

模板的分离写法

组件数据的存放

组件中的data为什么是个函数

VueComponent

Vue和VueComponent的关系

关于不同版本的Vue

ref属性

props配置(父子组件之间的通信)

父传子

子传父

父子组件的访问方式

mixin(混入)

插件

scoped样式

webStorage

组件的自定义事件

查看版本的命令


js表达式和js代码
* 表达式
    * 一个表达式会产成一个值,可以放在任何一个需要值的地方
* js代码(语句)
    * if(){}
    * for(){}
初始Vue
* 想让Vue工作,就必须创建一个Vue实例,且要传入一个配置对象
* root容器里的代码依然符合html规范,只不过混入了一些特殊的语法
* root容器里的代码被称为[Vue模块]
* Vue实例和容器是一一对应的
* /真实开发中只有一个Vue实例,并且会配合着组件一起使用
* {{xxx}}中的xxx要写js表达式,/*且xxx可以自动读取到data中的所有属性*/
* #一旦data中的数据发生变化,那么页面中用到该数据的地方也会自动更新
模板语法(插值和指令)
* 插值语法
    * 功能: /用于解析标签体内容
    * 写法: {{xxx}},xxx是js表达式,且可以直接读取到data中的所有属性 
           //Mustache(胡子/胡须)语法表示大括号
* #指令语法
    * 功能: /用于解析标签(包括:标签属性,标签体内容,绑定事件...)
    * 举例: v-bind:href="xxx"或简写为 :href="xxx",
            xxx同样要写js表达式,且可以直接读取到data中的所有属性
            // (会将xxx当成js表达式去执行)
数据绑定(v-bind和v-model)
* 单向
    * v-bind(数据只能从data流向页面,/*单向流动*/)
* 双向
    * v-model
        * 数据不仅能从data流向页面,也可以从页面流向data
        * /*只能应用在表单类元素(输入类元素)上*/
* 注意
    * #双向绑定一般都应用在表单类元素上
    * /v-model: value --> 简写为v-model
        //(因为v-model默认收集的就是value的值)
el和data的两种写法
* el有2种写法
    * new Vue时候配置el属性
    * /先创建Vue实例,随后再通过vm.$mount('#root')指定el的值
* data有2种写法
    * 对象式
    * 函数式
    * 如何选择
        * 目前哪种写法都可以,/*以后学习到组件时,data必须使用函数式,否则会报错*/
* 一个重要原则
    * /由Vue管理的函数,一定不要写箭头函数,一旦写了箭头函数,this就不再时Vue实例了
MVVM模型

* M: 模型(model): data中的数据
* V: 视图(View): 模型代码
* VM: 视图模型(ViewModel): Vue实例
发现
    * /data中所有的属性,最后都出现在了vm身上(数据代理)
    * /vm身上所有的属性及Vue原型上所有属性,在Vue模板中都可以直接使用

 

Object.defineProperty        



    
    回顾方法


    

数据代理
* 含义: 通过一个对象代理对另一个对象中属性的 *** 作(读/写)
* Vue中的数据代理
    * 通过vm(_data)对象代理data对象中属性的 *** 作(读/写)
    * /vm._data是数据劫持不是数据代理
* Vue中数据代理的好处
    * 更加方便的 *** 作data中的数据
* #基本原理
    * 通过Object.defineProperty()把data对象中所有属性添加到vm上
    * 为每一个添加到vm上的属性,都指定一个getter/setter
    * 在getter/setter内部去 *** 作(读/写)data中对应的属性 

事件处理 事件的基本使用
* 使用v-on:xxx 或 @xxx 绑定事件,其中xxx是事件名
* 事件的回调需要配置在methods对象中,最终会在vm上
* /methods中配置的函数,不能再用箭头函数!否则this就不是vm了
    * /被vue管理的函数不要使用箭头函数
*/ methods中配置的函数, 都是被Vue所管理的函数,this的指向是vm或组件实例对象
* @click="demo"和@click="demo($event)"效果一致,//但后者可以传参
事件修饰符
* prevent: 阻止默认事件(常用)   
* stop: 阻止事件冒泡(常用)
* once: 事件只触发一次(常用)
​
//扩展知识
* capture: 使用事件的捕获模式
* self: 只有event.target是当前 *** 作的元素时才触发事件
* passive: 事件的默认行为立即执行,无需等待事件回调执行完毕
键盘事件
* Vue中常用的按键别名:
    * 回车 => enter / 删除 => delete (捕获"删除"和"退格"键)
    * 退出 => esc 
    * 自己常用的快捷方式
    * 换行 => tab (特殊,必须配合keydown去使用)
* Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为kebab-case(短横线命名)
* 系统修饰键(用法特殊): ctrl alt shift meta
    * 配合keyup使用: 按下修饰键的同时,再按下其他键,随后释放其他键,事件才会被触发
    * 配合keydown使用: 正常触发事件
* 也可以使用keyCode去指定具体的按键
* #Vue.config.keyCodes.自定义键名 = 键码,可以去定制按键别名
计算属性(computed)
* 定义
    * /*要用的属性不存在,要通过已有的属性计算得来*/
​
* #原理
    * 底层借助了Object.defineproperty方法提供的getter和setter
​
* #get函数什么时候执行?
    * 初次读取时会执行一次
    * 当依赖的数据发生改变时会被再次调用
​
* 优势
    * /*与methods实现相比,内部有缓存机制(复用),效率更高,调试更方便*/
    * 计算属性会进行缓存,如果多次使用时,计算属性只会调用一次
​
* #备注
    * 计算属性最终会出现在vm上,直接读取使用即可
    * 如果计算属性要被修改,那必须写set函数去响应修改,
      且set中要引起计算时依赖的数据发生改变
    
* #计算属性简写
    * /只考虑读取不考虑修改的时候,只用简写的形式
监视属性(watch)
* 监视属性watch
    * 当被监视的属性变化时,回调函数自动调用,进行相关 *** 作
    * #监视的属性必须存在,才能进行监视!!
    * 监视的两种写法   
        * new Vue时传入watch配置
        * #通过vm.$watch('',{})监视
    * immediate //初始化时让handler调用一下
    * deep //属性值是布尔值,表示开启深度监视   
​
* #深度监视
    * //Vue中的watch默认不监测对象内部值的改变(一层)
    * /配置deep: true可以监测对象内部值改变(多层),监视多级结构中某个属性的变化
    * //注意
        * Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以
        * 使用watch时根据数据的具体结构,决定是否采用深度监测
computed和watch之间的区别
* //computed能完成的功能,watch都可以完成,watch能完成的功能,computed不一定能完成
    * 例如: watch可以进行异步 *** 作
    * /两个重要的原则 
        * 所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm
        * 所有不被Vue所管理的函数(定时器的回调函数,Ajax的回调函数等),
            最好写成箭头函数,这样this的指向才是vm
绑定class样式(bind)
* 字符串写法
    * 适用于: 
            样式的类名不确定,/*需要动态指定*/
* 数组写法  
    * 适用于: 
            要绑定的样式个数不确定,名字也不确定
* 对象写法  
    * 适用于: 
            要绑定的样式个数确定,名字确定,但动态决定用不用
绑定style样式(bind)
* 对象写法
    * :style = "{key(属性名):value(属性值)}" //对于数值的属性值需要加上单引号
    * :,其中xxx是动态值
​
* 数组写法
    * :style = "[baseStyle,baseStyle1]"
    * :,其中a,b是样式对象 //key值是存在的属性名
条件渲染(指令)
* v-show
	* 写法: v-show="表达式"
	* /适用于: 切换频率较高的场景
	* 特点: 不展示的DOM元素未被移除,仅仅是使用样式隐藏掉

* 三者之间连用不可间断
    * v-if //(可以和template(模板)一起使用)
		* 写法
			* v-if="表达式"
			* v-else-if="表达式"
			* v-else
		* /适用于: 切换频率较低的场景
         * 特点: 不展示的DOM元素直接被移除
         * #注意: v-if可以和v-else-if,v-else一起使用,但要求结构不能被"打断"
		* 原理
			* 后面的条件为false时,对应的元素以及其子元素不会渲染
			* 就是根本没有不会有对应的标签出现在DOM中
    * v-else-if
    * v-else
    
* 区别
	* 使用v-if时,元素可能无法获取到,而使用v-show一定可以获取到 
	* v-if的条件为false时,包含v-if指令的元素,根本不会存在dom中
	* v-show条件为false时,v-show只是给我们的元素添加一个行内样式: display: none
列表渲染
* v-for指令
	* 用于展示列表数据
	* 语法: v-for="(item, index) in/of xxx" :key="yyy"
	* /可遍历: 数组,对象,字符串(用的很少),指定次数(用的很少)
列表过滤
* 通过计算属性
* 通过监视属性  (immedicate: true)
数组中响应式的方法
* push()	//在数组最后面添加元素,可以添加多个参数
* pop()  	//删除数组中最后一个元素
* shift()	//删除数组中第一个元素
* unshift()	//在数组最前面添加元素,可以添加多个参数

* splice()	
	* 作用: 删除元素/插入元素/替换元素
* sort()	//排序
* reverse() //翻转
# 注意vue中通过索引值无法修改数组中的元素
# Vue.set (要修改的对象,索引值,修改后的值) //这个方法也可以使用
key的作用和原理
* 虚拟DOM中key的作用:
	key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据[新数据]生成[新的虚拟DOM],随后Vue进行[新虚拟DOM]与[旧虚拟DOM]的差异比较,比较规则如下:

* 对比规则:
	* 旧虚拟DOM中找到了与新虚拟DOM相同的key:
		* 若虚拟DOM中内容没变, 直接使用之前的真实DOM!
		* 若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM。
     * 旧虚拟DOM中未找到与新虚拟DOM相同的key
		* 创建新的真实DOM,随后渲染到到页面。										
* 用index作为key可能会引发的问题:
	* 若对数据进行:逆序添加、逆序删除等破坏顺序 *** 作:
		* 会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低。
	* 如果结构中还包含输入类的DOM:	
        * 会产生错误DOM更新 ==> 界面有问题
        
* 开发中如何选择key?
	* 最好使用每条数据的唯一标识作为key,比如id、手机号、身份z号、学号等			唯一值。
    * 如果不存在对数据的逆序添加、逆序删除等破坏顺序 *** 作,仅用于渲染列表用		  于展示,使用index作为key是没有问题的

Vue监视数据的原理 (响应式)
* vue会监视data中所有层次的数据
* #监测对象中的数据 ( Vue.$set )
	* 通过setter实现监视,且要在new Vue时就传入要监测的数据
    	* 对象中后追加的属性,Vue默认不做响应式处理
		* 如需给后添加的属性做响应式,请使用如下API:
            * Vue.set(target,propertyName/index, value)
		   * Vue.$set(target, propertyName/index, value)

* #监测数组中的数据
	* 通过/*包裹数组*/更新元素的方法实现,本质就是
		* 调用原生对应的方法对数组进行更新
		* 重新解析模块,进而更新页面

* #在Vue修改数组中的某个元素一定要用如下方法
	* 使用这些API: 				   		     		           		            push(),pop(),shift(),unshift(),splice(),sort(),reverse()
	* Vue.set() 或 vm.$set()
	* /特别注意: Vue.set()和vm.$set() 
			   # 不能给vm或vm的根数据对象添加属性!!!
# Avoid adding reactive properties to a Vue instance or its root $data at runtime        (不能给data追加属性,可以给data里面的对象追加属性)
收集表单数据( v-model )
* 若:,
    	则v-model收集的是value值,用户输入的就是value值

* 若:,
    	则v-model收集的就是value值,且要给标签配置value值

* 若: 
    / 复选框:单个勾选复选框和多个勾选复选框
    # 单选框使用布尔值,多选框使用数组
	* 没有配置input的value属性,那么收集的就是checked 
		//(勾选 or 未勾选,是布尔值)
	* 配置input的value属性
		* v-model的初始值是非数组,那么收集的就是checked 
			//(勾选or未勾选,是布尔值)
		* v-model的初始值是数组,那么收集的就是value组成的数组

* v-model结合select类型
	* 单选: 只能选中一个值
    	* v-model绑定的是一个值
		* 当我们选中option中的一个时,会将它对应的value赋值到mySelect中
	* 多选: 可以选中多个值
    	* v-model绑定的是一个数组
		* 当选中多个值时,就会将选中的option对应的value添加到数组mySelect中

* 备注: 
	* /v-model的三个修饰符	
		* lazy: 失去焦点再收集数据
         * number: 输入字符串转为有效的数字
         * trim: 输入首尾空格过滤       
过滤器
* 定义
	# 对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理)
* 语法
	* 注册过滤器: Vue.filter(name,callback) 或 new Vue{filters:{}}
	* 使用过滤器: {{xxx | 过滤器名}} 或 v-bind:属性 = "xxx | 过滤器名"
* 备注:
	* 过滤器可以接收额外参数,多个过滤器也可以串联
	* /并没有改变原本的数据,是产生新的对应的数据
高阶函数( filter / map / reduce )
* filter()
	* 它其中的参数: 回调函数有一个要求: 必须返回一个布尔值
	* true: 当返回true时,函数内部会自动将这次回调的n加入	//到新的数组中
	* false: 当返回false时,函数内部都会过滤这次的n
* map() //映射
	* 对数组中所有的元素进行变化时 
* reduce()
	* 作用
		* 对数组中所有的内容进行汇总 
内置指令 v-bind(涉及到上面的绑定class样式和style样式)
* 作用: 单向绑定解析表达
* 简写为: xxx
* #作用: 动态的绑定标签里面的属性
* 对象语法
	* v-bind:class = "{类名: Boolean,类名2: Boolean }"
* 数组语法
	* v-bind:class = "[active,line]"
v-on(事件监听)
* #作用: 绑定事件监听
* 简写为 @
* 参数: event
* //在调用方式,如何手动的获取到浏览器参数的event对象: $event
* 注意
	* #如果方法不需要额外参数,那么方法后的()可以不添加 
		* 如果方法本身中有一个参数,那么会默认将原生事件event参数传递进去
	* #如果需要同时传入某个参数,同时需要event时,可以通过$event传入事件

* v-on修饰符
    * .stop 	//调用event.stopPropagation()
    * .prevent 	//调用event.preventDefault()
    * .{keyCode | keyAlias} 
		   //只当事件是从特定键触发时才触发回调
    * .native 	//监听组件根元素的原生事件
    * .once		//只触发一次回调
v-model
* 作用: 双向数据绑定
	* 原理
		* 它的背后本质上是包含两个 *** 作
			* v-bind绑定一个value属性
			* v-on指令给当前元素绑定input事件
* v-for: #遍历数组,对象,字符串
* v-if: 条件渲染(动态控制节点是否存在)
* v-else: 条件渲染(动态控制节点是否存在)
* v-show: 条件渲染(动态控制节点是否展示)

* v-text
	* 作用: 向其所在的节点中渲染文本内容
    * #与插值语法的区别: v-text会替换节点中的内容,{{xxx}}(插值语法)则不会
    
* v-html
	* 后面往往跟上一个string类型
	* 会将string的html解析出来并进行渲染
	* 作用
		* 向指定节点中渲染包含html结构的内容
	* #与插值语法的区别
		* v-html会替换掉节点中的所有的内容,{{xx}}则不会
         * v-html可以识别html结构
	* /严重注意: v-html存在安全问题
		* 在网站上动态渲染任意HTML是非常危险的,容易导致XSS(冒充用户之手)攻击
		* 一定要在可信的内容上使用v-html,永不要用在用户提交的内容上!
            
* v-cloak(没有值)
	* #本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性
	* 使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题
    * 在Vue解析之前,div中有一个属性v-cloak
    * 在Vue解析之后,div中没有一个属性v-cloak 

* v-once
	* 表示元素和组件只渲染一次,不会随着数据的改变而改变
	* 后面不需要跟任何表达式
	* v-once所在节点在初次动态渲染后,就视为静态内容了
	* 以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能

* v-pre
	* 跳过其所在节点的编译过程
	* 可利用它跳过:没有使用指令语法,没有使用插值语法的节点,会加快编译

自定义指令 
* 定义语法	
	* 局部指令
		* 第一种
		new Vue({
            directives:(指令名:配置对象)  
        })
		* 第二种
		new Vue({
            directives{指令名:回调函数}
        })
	* 全局指令
		* Vue.directive(指令名,配置对象)
		* Vue.directive(指令名,回调函数)
* /配置对象中常用的3个回调
	* bind: 指令与元素成功绑定时调用
    * inserted: 指令所在元素被插入页面时调用
    * update: 指令所在模板结构被重新解析时调用
* /备注
	* 指令定义时不加v-,但使用时要加v-
    * 指令名如果是多个单词,要使用kebab-case命名方式,不要用camelCase命名
生命周期
* 又名: 生命周期回调函数,生命周期函数,生命周期钩子
* 是什么: Vue在关键时刻帮助我们调用的一些特殊名称的函数
* 生命周期函数的名字不可以更改,//但函数的具体内容是程序员根据需求编写的
* /生命周期函数中的this指向是 vm 或 组件实例对象

生命周期总结
* 常用的生命周期钩子
	* mounted: 
		* 发送Ajax请求,启动定时器,绑定自定义事件,订阅消息等(初始化 *** 作)
		* 初始的真实DOM放入页面后
	* beforceDestory: 清除定时器,解绑自定义事件,取消订阅消息等(收尾工作)
* 关于销毁Vue实例
	* 销毁后借助Vue开发者看不到任何信息
	* 销毁后自定义事件会失效,但原生DOM事件依然有效
	* 一般不会在beforceDestory *** 作数据,因为即便 *** 作数据,也不会再次触发更新流程了 
组件

含义

用来实现局部(特定)功能效果的代码集合(html/css/js/image...)

为什么

一个界面的功能很复杂

作用

复用编码,简化项目编码,提高运行效率

Vue中使用组件的三大步骤

定义组件 (创建组件构造器--调用Vue.extend()方法)

注册组件--调用Vue.component(全局组件,意味着可以在多个Vue的实例下面使用)

调用Vue.component()需要传递两个参数:

注册组件的标签名

组件构造器

使用组件(写组件标签)--在Vue实例的作用范围内

如何定义一个组件

使用Vue.extend(options)创建,其中options和 new Vue(options)时传入的那个options几乎一样,但也有点区别

区别如下

/el不要写(最终所有的组件都要经过一个vm的管理,由vm中的el决定服务那个容器)

/data必须写成函数(避免组件被复用时,数据存在引用关系)

备注: 使用template可以配置组件结构

如何注册组件

局部注册: 靠new Vue的时候传入compenents选项

全局注册: 靠Vue.compenent('组件')

编写组件标签

组件化思想
* 组件化是Vue.js中的重要思想
	* 它提供了一种抽象,让我们可以开发出一个个独立复用的小组件来构造我们的应用
	* 任何的应用都会被抽象成一颗组件树
* 组件化思想的应用  
	* 有了组件化的思想,我们在之后的开发中就要充分利用它
	* 尽可能的将页面拆分成为一个个小的、可复用的组件
	* 这样让我们的代码更加方便组件组织和管理,并且拓展性也更强
组件注意点
* 关于组件名
	* 一个单词组成
		* 第一种写法(首字母小写): school
		* 第二种写法(首字母大写): School
	* 多个单词组成 
        * 第一种写法(kebab-case命名): my-school
	    * 第二种写法(CamelCase命名): MySchool   //(需要Vue脚手架支持)
	* 备注
    	(1) //组件名尽可能回避HTML中已有的元素名称,例如: h2、H2都不行
		(2) //可以使用name配置项指定组件在开发者工具中呈现的名字
* 关于组件标签
	第一种写法:  
	第二种写法: 
#备注: 不用使用脚手架时,会导致后续组件不能渲染
    
* 一个简写方式 const school = Vue.extend(options)  
	* 可简写为: const school = options
模板的分离写法
* Vue提供了两种方案来定义HTML模板内容
	* 使用