Vue基础

插值语法 :常用标签体内容
{{...}}  ...为js表达式

指令语法:解析标签
v-bind 动态绑定
例:
简写: ====>   :
例:

数据绑定
 单向数据绑定:v-bind
 双向数据绑定:v-model:value
 简写: ====> v-model
 v-model 只能应用于表单类元素

el与data两种写法
el:'#root'
v.$mount('#root')
 
对象式:data:{}
函数式:dara:funtion(){return{}}//此处的this是vue实例

MVVM模型
M:模型(Model):对应data中的数据
V:视图(View):模板(DOM页面结构)
VM:视图模型(ViewModel):Vue实例对象

数据代理
Object.defineproperty(x,y,z)
例:let person = {name:'a'}
    number = 20
Object.defineproperty(person,age,{
    value:'2',
    enumerable:ture,
    writable:ture,
    configurable:ture,
    get:function(){return number}})
    set:function(value){number = value}
enumerable:控制属性是否可以枚举,默认值为false;
writable:控制属性是否可以修改,默认值为false;
configurable:控制属性是否 可以被删除,默认值为false;
当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值

数据代理:通过一个对象代理对另一个对象中的属性的操作(读/写)

事件处理
v-on:click="show"//不传参
简写: ===> @click="show($event,aa)"//传参
new vue({methods:{show(event,aa){}}})

事件修饰符
@click.prevent:阻止默认事件
.stop:阻止事件冒泡
.once:事件只触发一次
.capture:使用事件的捕获模式
.self:只有在event.target是当前操作的元素时才触发事件
.passive:事件的默认行为立即执行,无需等待事件回调执行完毕

键盘事件
常用按键别名:
@keyup.enter:回车
.delete:删除(捕获删除和退格键)
.esc:退出
.space:空格
.up:上
.down:下
.left:左
.right:右

计算属性 computed
get函数执行:初次读取时会执行一次;当依赖的数据发生改变时会被再次调用。
优势:与methods实现相比,内部有缓存机制(复用),效率 更高,调试方便。
计算属性最终会出现在vm上,直接读取使用即可。
计算属性要被修改,必须写set函数去响应修改,且set中要引起计算时依赖的数据发生。


监视属性watch
当被监视的属性发生变化时,回调函数自动调用,进行相关操作;
监视的属性必须存在,才能进行监视;
监视的两种写法:1.new Vue时传入watch配置;2.通过vm.$watch监视

深度监视
vue中的watch默认不监视对象内部值的改变(一层);
配置deep:true可以监视对象内部值改变(多层);
监视多级结构中某个属性的变化:'number.a':{}
监视多级结构中所有属性的变化:number:{deep:true}
简写:ishot(newValue,oldValue){
    //     console.log('a',newValue,oldValue)
    //    }
    vm.$watch('ishot',function(newValue,oldValue){
        //             console.log('a',newValue,oldValue)
            
        // })

computed 和 watch 之间的区别:
 1.computed能完成的功能,watch也能完成
2.watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作
两个重要的原则:1.所被vue管理的函数,最好写成普通函数,这样this的指向才是vm 或组件实例对象;2.所有不被vue所管理的函数(定时器的回调函数,ajax的回调函数等),最好写成箭头函数,这样this的指向才是vm或组件实例对象。
    
绑定样式
1.class样式
字符串写法:适用于样式的类名不确定,需要动态指定;
:class="basic"
basic:'aaa'
数组写法 :适用于要绑定的样式个数不确定,名字也不确定;
:class="classArr"
classArr:[aaa,bbb]
对象写法:适用于要绑定的样式个数确定,名字也确定,但要动态觉得用不用;
:class="classobj"
classobj:{aaa:false,bbb:true}
2.style样式
:style="{fontSize:xxx}";//xxx是动态值
:style="[a,b]";//其中a.b是样式对象

条件渲染
v-show="true"
切换频率较高的场景,不展示的DOM元素未被移除,仅仅是使用样式隐藏;
v-if="true"
v-else-if=""
v-else=""
使用切换频率较低的场景,不展示的DOM元素直接被移除;
使用v-if时,元素可能无法获取到,而使用v-show一定可以获取到;
temple

列表渲染
遍历数组
v-for="(p,index) in persons" :key="index"
遍历对象
v-for="(value,k) of car" :key="k"
遍历字符串
v-for="(cahr,index) of str" :key="index"
 
key作用与原理
1.虚拟DOM中key的作用:
    key是虚拟DOM对象的标识,当状态中的数据发生变化时,vue会根据新数据生成新的虚拟DOM,随后vue进行新虚拟DOM与旧虚拟DOM的差异比较, 比较规则如下:
2.比较规则:
(1)旧虚拟DOM中找到了与新虚拟DOM相同的key:
        若虚拟DOM中内容没变,直接使用之前的真实DOM;
    若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM;
 (2)旧虚拟DOM中未找到与新的虚拟DOM相同的key
        创建新的真实DOM,随后渲染到页面;
3.使用index作为key可能会引起的问题:
   (1)若对数据进行:逆序添加,删除等破坏顺序操作:会产生没有必要的真实DOM更新 ==>界面效果没有问题,但效率低;
     (2)如果结构中还包括输入类的DOM:会产生错误DOM更新 ===>界面没有问题
4.开发中如何选择Key:
   (1)最好使用每条数据的唯一标识作为key,比如id,手机号,身份证号
      (2)如果不存在对数据的逆序添加删除等破坏顺序操作,仅用于渲染列表用于展示,使用index作为key没有问题;

列表过滤

监视数据原理
1.vue会监视data中所有层次的数据;
2.如何监视对象中的数据:
    通过setter实现监视,且要在new vue时就传入要监视的数据;   
(1)对象中后追加的属性,vue默认不做响应式处理;
(2)如需给后添加的属性做响应式,请使用如下API:
    vue.set(target,peopertyName/index,value)或vm.$set(target,peopertyName/index,value)
3.如何监测数组中的数据:
  通过包裹数组更新元素的方法实现,本质就是做了两件事:
   (1)调用元素对应的方法对数组进行更新;
   (2)重新解析模板,进而更新页面;
4.在vue修改数组中的某个元素一定要用如下方法:
    (1)使用这些API:push(),shift(),unshift(),splice(),sort(),reberse()
   (2)vue.set()或vm.$set()
vue.set()和vm.$set()不能给vm或vm的根数据对象添加属性。

收集表单数据
若:则v-model收集的是value值,用户输入的就是value值;
若:则v-model收集的是value值,且要给标签配置value值;
若:
   1.没有配置input的value属性,那么收集的就是checked(勾选或未勾选,是布尔值);
      2.配置input的value属性:
    (1)v-model的初始值是非数组,那么收集的就是checked(勾选或未勾选,是布尔值);
    (2)v-model的初始值是数组,那么收集的就是value组成的数组;
v-model的三个修饰符:
    lazy:失去焦点在收集数据;
    number:输入字符串转为有效数字;
    trim:输入首尾空格过滤;

BootCDN
过滤器
定义:对要显示的数据进行特定格式化后在显示(适用于一些简单逻辑的处理)
语法:1.注册过滤器:vue.filter(name,callback)或new vue(filters:{})
     2.使用过滤器:{{xx | 过滤器名}}或 v-bind:属性="xxx | 过滤器名"
过滤器也可以接受额外参数,多个过滤器也可以串联;
斌没有改变原本的数据,是产生新的对应的数据;

v-text指令

该文本会被替换

作用:向其所在的节点中渲染文本内容;
与插值语法的区别:v-text会替换掉节点中的内容,{{xxx}}则不会;

v-html指令
作用:向指定节点中渲染包含html结构的内容;
与插值语法的区别:
   (1)v-html会替换掉节点中所有的内容,{{}}则不会;
   (2)v-html可以识别html结构;
v-html有安全性问题:
    (1)在网站上动态渲染任意html是非常危险的,容易导致xss攻击;
    (2)不要用在用户提交的内容上;


v-cloak指令

v-once指令
所在节点在初次动态渲染后,就视为静态内容;
以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能;

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

自定义指令——函数式——对象式
1.局部指令:
    new Vue({directive:{指令名:配置对象})}
    或 new Vue({directive(){}})
2.全局指令:
    Vue.directive(指令名,配置对象)
    或 Vue.directive(指令名,回调函数)
配置对象中常用的三个回调:
(1)bind:指令与元素成功绑定时调用;
(2)inserted:指令所在元素被插入页面时调用;
(3)update:指令所在模板结构被重新解析时调用;
指令定义时不加v-,但使用时要加v-;
指令名如果是多个单词,要使用kebab-case命名方式,不要用camelCase命名;

生命周期
又名:生命周期回调函数,生命周期函数,生命周期钩子;
Vue在关键时刻帮我们调用的一些特殊名称的函数;
生命周期函数的名字不能更改;
生命周期函数的this指向是vm 或组件实例对象;
beforeCreate created
挂载 beforMount mounted
mounted:发生ajax请求,启动定时器,绑定自定义事件,订阅消息等【初始化操作】
Vue完成模板的解析并把初始的真是DOM元素放入页面后(挂载完毕)调用mounted
更新 beforeUpdate  updated
beforeUpdate: 数据是新的,但页面是旧的;即:页面尚未和数据保持同步;
updated: 页面和数据同步
销毁 beforeDestroy  destroyed
beforeDestroy: 清楚定时器,解绑自定义事件,取消订阅消息等【收尾工作】
关于销毁Vue实例:
1.销毁后借助Vue开发者工具看不到任何信息;
2.销毁后自定义事件会失效,但原生DOM事件依然有效;
3.一般不会在beforeDestroy操作数据,因为即便操作数据也不会触发更新数据

组件
实现应用中局部功能代码和资源的集合
非单文件组件
Vue中使用组件的三大步骤:
1.定义组件(创建组件)2.注册组件3.使用组件(写组件标签)
(1)定义组件:
    使用Vue.extend(options)创建,其中options 和 new Vue(options)时传入的那个options几乎一样,但区别如下:
    el不要写,最终所有的组件都要经过vm管理,由vm中的el决定服务哪个容器;
    data必须写成函数,避免组件被复用时,数据存在引用关系;
使用template可以配置组件结构
2.注册组件:
    (1)局部注册:靠new Vue的时候传入components选项
    (2)全局注册:靠Vue.componet('组件名',组件)
3.编写组件标签

1.关于组件名:
(1)一个单词组成:school/School;
(2)多个单词组成:my-school/MySchool(需要Vue脚手架支持)
组件名尽可能避免HTML中已有的元素名称;
可以使用name配置项指定组件在开发者工具中呈现的名字;
2.关于组件标签:
(1)
 (2)
不用使用脚手架时,会导致后续组件不能渲染
3.简写方式:
 const school = Vue.extend(options)可简写:const school = options

组件嵌套

VueCommponet:
1.school组件本质是一个名为VueComponet的构造函数,是Vue.extend生成的;
2.我们只需写,Vue解析时会帮助我们创建school组件的实例对象,即Vue帮我们执行的:new VueComponent(options);
3.每次调用Vue.extend,返回的都是一个全新的VueComponent;
4.关于this指向:
(1)组件配置中:data函数,methods中的函数,watch中的函数,computed中的函数,它们的this均是VueComponent实例对象;
(2)new Vue()配置中:data函数,methods中的函数,watch中的函数,computed中的函数,它们的this均是Vue实例对象;
5.VueComponent的实例对象,以后简称VC,也称组件实例对象;Vue的实例对象简称vm

内置关系
VueComponent.prototype._proto_===Vue.prototype
让组件实例对象(vc)可以访问到Vue原型剩的属性,方法;

单文件组件
School.vue-...-App.vue-main.js-index.html

Vue脚手架
render函数
render(createElement){return creaElement('h1','你好')}
render:h=>h(App)

关于不同版本的Vue
  1.vue.js与vue.runtime.xxx.js的区别:
  (1)vue.js是完整版的Vue,包含核心功能和模板解析器
  (2)vue.runtime.xxx.js是运行版的vue,只包含核心功能,没有模板解析器
  2.因为vue.runtime.xxx.js没有模板解析器,所以不能使用template配置项,
    需要使用render函数收到creatElement函数去指定具体内容

修改默认配置
## 脚手架文件结构
|—— node modules
|—— public
|   |—— favicon.ico:页面图标
|   |—— index.html: 主页面
|—— src
|   |—— assets: 存放静态资源
|   |   |—— logo.png
|   |—— component: 存放组件
|   |   |—— HelloWord.vue
|   |—— App.vue: 汇总所有组件
|   |—— main.js: 入口文件
|—— .gitignore: git版本管理忽略的配置
|—— babel.config.js: babel的配置文件
|—— jsconfig.json: 应用包配置文件
|—— README.md: 应用描述文件
|—— package-lock.json: 包版本控制文件

ref属性
1.被用来给元素或子组件注册引用信息(id的替代者)
2.应用在html标签上获取的是真实DOM元素,应用在组件标签上是组件实例对象(vc)
3.使用方法:
打标识:

学校名字:{{ name }}


获取: return console.log(this.$refs.xuexiao)

props配置
功能:让组件接受外部传过来的数据;
(1)传递数据:
 (2)接受数据:
第一种方式(只接受):props:['name'];
第二种方式(限制类型):props:{name:'aaa'};
第三种方式(限制类型,限制必要性,指定默认值):props:{name:'aaa',type:String,default:'bbb',//默认值 required:true//必要性};
props是只读的,Vue底层会监测你对props的修改,如果修改了会发出警告,如果需要修改,需复制props的内容到data中,然后再修改data中的数据


mixin混入
功能:可以吧多个组件公共的配置提取成一个混入对象;
使用方式:
第一步定义混合,例:{data(){...},methods:{}}
第二步使用混合,例:1.全局混入:Vue.mixin(xx);2.局部混入:mixins:['xx']

插件
功能:用于增强Vue
本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据;
定义插件:
对象:install = function(Vue,options){
    //1.添加全局过滤器
    Vue.filter(..)
    //2.添加全局指令
    Vue.directive(..)
    //3.配置全局混入
    Vue.mixin(..)
    //4.添加实例方法
    Vue.prototype.$myMethod = function(){..}
    Vue.protptype.$myProperty = xxx}
使用插件: Vue.use()

scoped样式
作用:让样式在局部生效,防止冲突;
写法: