Vue2入门学习笔记

Vue2入门必备!

⭐关注我查看更多配套笔记

学习视频:https://www.bilibili.com/video/BV1Zy4y1K7SH/

【尚硅谷Vue全家桶】

本博客是对该视频内容的整理以及加入自己的理解 想全面学习的推荐大家去看原视频

1.基础

1.特点

1.采用组件化模式,提高代码复用率,让代码更好维护

2.声明式编码,让编码人员无需直接操作DOM,提高开发效率

3.使用虚拟DOM + 优秀的Diff算法,尽量复用DOM节点

2.官网内容

官方网址 :cn.vuejs.org

3.下载及安装

1.下载

在官方网址 : 安装 — Vue.js (vuejs.org)

需要配置以下内容:

2.安装开发者工具

一、Chrome浏览器安装方式:
①:点击右上角三个点
②:点击更多工具
③:点击扩展程序
④:点击右上角的开发者模式,将他启用
⑤:将下载的Vue.crx文件直接拖动到浏览器窗口即可
二:Edge浏览器安装方式
①:点击浏览器右上角的三个点
②:点击扩展
③:点击左下角的开发人员模式,将他启用
④:将Vue.crx文件拖动到浏览器即可

https://pan.baidu.com/s/1MtYvMPew4lb14piIrs9x6w
提取码:6666

3.关闭开发者提示

Vue.config.productionTip = false;

2.基础使用

// 非Vue控制的函数尽量写成箭头函数

1.基础Vue全局配置(传参)/使用对象方法

<div id="root">
    <h1>你好,{{name}}</h1> <!-- 使用模板语法去渲染 -->
</div>

<div class="root">
    <h1>你好,{{name}}</h1> <!-- {{ }} 中必须写JS表达式! -->
    <h2>现在时间是{{Date.now()}}</h2>
</div>

<!-- 表达式: 一个表达式会生成一个值,可以放在任何一个需要值的地方 -->

<script>
    x = new Vue({
        el:'#root', //el用于指定当前Vue实例为哪个容器服务 通常为css选择器字符串
        data:{  //储存数据,只能在指定的容器中去使用,值写成一个对象
            name:'尚硅谷', 
        }
    })
    
    // 只会选择第一个 root 
    // 容器与Vue是一一对应的!!!
    const y = new Vue({
        el:'.root',
        data:{
            name:'尚硅谷'
        }
        // data第二种写法 函数式写法 vue自动调用该函数
        // 不能使用箭头函数 this 会指向windows
        data:fuction(){
        	console.log('QQQ', this)
        	return{
                name:'尚硅谷'
            }
    	}
        
    }
    })
    // 使用方法修改参数
    y.$mount('#root')  // s修改实例构造器中的 element
</script>

2.模板语法

<!-- 
	插值语法 
	功能:用于解析标签体内容 
	写法:{[xXXx}]. xxx是js表达式,且可以直接读取到data中的所有属性
-->
<h1>你好,{{name}}</h1> 

<!-- 
	指令语法 设置元素的属性
	功能:用于解析标签(包括:标签属性、标签体内容、绑定事件.....)
	举例:v-bind:href=""xxx”或简写为:href="xxx"",xxx同样要js表达式,且可以直接读取到data中的所有属性
	备注:Vue中有很多的指令,且形式都是: v-????,此处我们只是拿v-bind举个例子。
-->
<a v-bind:href="url">点我</a>
<!-- 简写 -->
<a :href="url">点我</a>

3.数据绑定

<input v-bind:value="url">我是单项绑定
<input v-model:value="url">我是双向绑定
<!-- v-model 只能用在表单类元素上 输入类元素 含有value值 -->

<!-- 简写 -->
// 绑定后 为js表达式 不绑定为字符串
<input :value="url">我是单项绑定
<input v-model="url">我是双向绑定

4.MVVM模型

1.M:模型(Model):对应data中的数据

2.V:视图(View):模板

3.VM:视图模型(ViewModel) : Vue 实例对象心

image-20220328193753311

因此 vm 也经常作为 Vue的实例对象

const vm = new Vue({})

5.vm

<!--
    vm中实例含有的内容
    可以直接在 Vue 模板中直接使用
-->

<h1>
    {{ $mount('#root') }}
</h1>
{{name}} 存在是因为会自动添加到 vm 对象中

6.进阶技术 Object方法

// 使用 object.defineProperty 添加对象成员
Object.defineProperty(对象名,添加的键,添加的值)

Object.defineProperty(obj,keys,{
    value:18, // 设置 
    enumerable:true, // 控制属性是否可以被枚举(被遍历)  默认为false
    writable:true, // 控制属性是否可以被修改 默认为false
    configurable:true, // 控制属性石佛可以被删除 默认为false
    // 当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
    get:function(){
        return number;
    }
    // 简写
    get(){
        return number;
	}
	// getter 与 setter
	set(value){
        number = value;
    }

})

7.数据代理

<!--数据代理:通过一个对象代理对另一个对象中属性的操作(读/写) -->
<script>
    obj1 = {
    	x:100,
    }
    obj2 = {
    	y:200,
    }
    
    Object.defineProperty(obj2,x,{
    	value:obj1.x, // 此处与 obj1 的属性绑定
	})
</script>
    

数据代理在 Vue 中的应用

<!-- 
	vm 实例中的数据 与构造器中 data中的数据绑定
-->

image-20220328202239085

_data实际上里面为数据劫持

8.事件的基本使用

<div id="root">
    <!-- 事件触发回调函数 -->
    // 需要传参可以加括号 但是 event会消失 加入 $event Vue帮助传参
    <button  v-on:click="showInfo($event,66)">点我提示信息</button>
    
    
    <!-- 事件修饰符 + 简写 @   -->
    <a href="#" @click.prevent="methods">点我跳转</a> // 阻止跳转
    <!--
		1.prevent: 阻止默认事件(常用);
		2.stop:阻止事件冒泡(常用);
		3.once:事件只触发一次(常用);
		4.capture:使用事件的捕获模式;
		5.self:只有event.target是当前操作的元素是才触发事件;
		6.passive:事件的默认行为立即执行,无需等待事件回调执行完毕;
		// 默认的时候 先执行回调函数 等待回调函数执行完毕再运行默认事件(鼠标下滑等)
	-->
</div>

<script>
    x = new Vue({
        el:'#root',
        data:{ // 数据劫持 + 数据代理
            name:'尚硅谷', 
        },
        methods:{ // methods中的函数可以加到data中 但会拖累Vue
            showInfo(event,number){ // event 为事件对象
                alert("同学你好" + number);
            },
            aClick(e){
                e.preventDefault();
                alert("同学你好")
            }
        }
        
    })
</script>

9.键盘事件

<!--准备好一个容器-->
<div id="root">
    <h2>欢迎来到{{name}学习</h2> <!-- 这里的.enter代表按下键盘enter键 -->
    <input type="text" placeholder="按下回车提示输入"@keyup.enter="showInfo">
</div>
<script type="text/javascript">
    Vue.config.productionTip = false //阻止 vue在启动时生成生产提示
    new Vue({
        el : "#root",
        data:{
            name:"尚硅谷"
        },
        methods:showInfo(e){
        	console.log(e.target.value)
    	},
    })
</script>
1.Vue中常用的按赞别名:
	回车 =>enter
	删除=>delete(捕获“删除”和“退格”键)
	退出=>esc	
	空格=>space
	换行=>tab
	上=>up
	下=>down
	左=>left
	右=> right
2.Vue未提供别名的按健,可以使用按键原始的key值去绑定,但注意要转为kebab-case(短横线命名)
	caps-lock 大小写键别名
3.系统修饰健(用法特殊): ctrl、alt、shift、meta(win)
	(1).配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键。事件才被触发。
	(2).配合keydown使用:正常触发事件。
4.也可以使用keyCode去指定具休的按键(不推荐)
5.Vue.config.keyCodes.自定义健名=健码,可以去定制按健别名

/*

修饰符是可以连续使用的(链式调用)

  • @click.prevent.top
  • @keydown.alt.y /* y 与 alt 一起按下 */

*/

10.计算属性

<div id="root">
    <h2>欢迎来到{{name}}学习</h2>
    // 模板中可以写一些简单的语句 但是不能写 Vm中没有的!
    <h2>欢迎来到{{name = !name}}学习</h2> 
    <input type="text" placeholder="按下回车提示输入"@keyup.enter="showInfo">
</div>
<script type="text/javascript">
    Vue.config.productionTip = false //阻止 vue在启动时生成生产提示
    new Vue({
        el : "#root",
        data:{
            // firstname 叫属性
            // "尚硅谷" 叫属性值
            firstname:"尚硅谷",
            lastname:"snowman",
        },
        methods:{
            get(){
                // method中的方式不会缓存 会被多次调用
            }
		}
        // computed的属性叫做计算属性
        computed:{
        	// 输入 {{fullname}} 自动调用fullname get函数
            fullname:{
        		// fullname 被读取调用get
                get(){
                    // 此处的 this 被 Vue 配置为 vm
                    // get 什么时候调用?
                    // 1.初次读取fullname时 2.所依赖的数据改变时
                    return this.firstname + this.lastname;
        		// fullname 被修改时 调用set
        		set(value){
                    const arr = value.split('-');
                    this.firstname = arr[0];
                    this.lastname = arr[1];
                }
        		/*
        		* 1.定义:要用的属性不有在,要通过已有属性计算得来。
        		* 2.原理:底层什助了objcet.defineproperty方法捉供的getter和setter.
        		* 3.get函数什么时候执行?
        			(1).初次读取时会执行一次.
        			(2).当依赖的数据发生改变时会被再次调用。
        		* 4.优势:与methods实现和比,内部有级存机制(复用)。效率更高。调试方便
        		* 5,备注:
        			1.计算届性最终会出现在vm上,直接读取使用即可..
        			2.如果计算属性要被修返,那必须写set函数夫响应修改,fset中要引起计算时依赖的数据发牛	
        		*/
                }
    			// 简写方式 确定只读不改
    			fullname(){
                    return "小猪佩奇";
                }
            }
        }
    })
</script>

11.监视属性

Vue ({
    // 监视在 vm 中的值是否发生变化 变化时 作何处理
	watch:{
        isHot:{
            // 初始化时调用一次handler
            immediate:true,
            // isHot发生变化 传参 newValue为新的值 oldValue 为旧的值
		handler(newValue,oldValue){
            console.log(newValue,oldValue);
        	}
        }
    }
})
// 第二种写法 添加到vm实例中
vm.$watch('isHot',{
    immediate:true,
	handler(newValue,oldValue){
        console.log(newValue,oldValue);
    }
})

12.深度监视

// Vue可以检测多层级的监视 watch不检测
/*
* (1).vue中的watch默认不监测对象内部值的改变(一层)。
* (2).配置deep:true可以监测对象内部值改变(多层)。
* 备注:
* (1).vue自身可以监测对象内部值的改变,但vue提供的watch默认不可以!
* (2).使用watch时根据数据的具体结构,决定是否采用深度监视。
*/

Vue ({
    data:{
        number:{
            a:500,
            b:600,
        },
        name:'逯少',
    }
    // 监视在 vm 中的值是否发生变化 变化时 作何处理
	watch:{
        number:{
    		// 开启深度监视 不开启的话number的成员不会被检测
    		deep:true,
            // 初始化时调用一次handler
            immediate:true,
            // number发生变化 传参 newValue为新的值 oldValue 为旧的值
		handler(newValue,oldValue){
            console.log(newValue,oldValue);
        	}
        }
    },
    // watch 简写 前提: 不需要 deep immediate
    watch:{
        name(){
            console.log("name被改变了");
        }
    }
})

// $符简写
vm.$watch('isHot',fuction(){
          console.log("isHot被改变了");
          })

13.watch与computed对比

// computed更容易写
// 但是computed无法进行异步操作
// computed 需要返回值 异步会出错
// watch中的异步操作
 handler(){
	setTimeout(()=>{
 	console.log("1s passing number改变了");
	},1000)
	}
/*
* computed和lwatch之间的区别:
* 1.computed能完成的功能。 watch都可以完成..
* 2.watch能完成的功能,computed不一定能完成,例如: watch可以进行异步糅作。
*	1.所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm或组件实例对象。
*	2.所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等),最好写成箭头函数。这样this的指向才是vm或组件实例对象。
*/

14.修改/绑定 class

Vue 会解析数组/对象 --> Js表达式

<!-- 需要的 class 是动态的 -->
<div class="basic" :class="yourclass"></div><br/><br/>
<!--绑定class样式--数组写法,适用丁:要绑定的样式个数不确定、名字也不确定-->
<div class="basic" :class="list_arr"></div>
<!--绑定class样式对象写法。适用于:要绑定的样式个数确定、名宁也确定但要动态决定用不川-->
<div class="basic" :class="classObj"></div>

<!-- Style行内样式 传入Style对象 或者 数组内包含Style对象-->
<div class="basic" :style="styleObj"></div>
    
---> 经过Vue解析之后会变成
<div class="basic normal"></div><br/><br/>
<div class="basic class1 class2 class3" :class="list_arr"></div>
<div class="basic class1 class3"></div>
<div class="basic" style="color:red;fontSize:10px;backgroundColir:grzy;"></div>


<script>
new Vue({
	el:'#id',
    data:{
        yourclass:'normal',
        list_arr:['class1','class2','class3'],
        classObj:{
            class1:true,
            class2:false,
            class3:true,
        }
        // 此处的样式必须为 css 中有的样式 font-size --> fontSize 多单词拆散大小写拼接
        styleObj:{
            color:red,
            fontSize:10px,
            backgroundColir:grzy,
    	}
    }
})
</script>

15.条件渲染

<!-- v-show 与 v-if show控制display属性 if直接会删除/保留该元素 -->
“” 中填写 js 表达式
<div v-show="false">我的display属性为none</div>
<div v-show="true">我的display属性为默认</div>

<!-- 与js语法中if else if else 的用法一致 -->
<div v-if="false">我不会在DOM中出现</div>
<div v-else-if="false">我不会在DOM中出现</div>
<div v-else="false">我不会在DOM中出现</div>
<div v-if="true">我会在DOM中出现</div>



需要整体隐藏的时候 使用 template不会影响结构 
div也可以 注意css
template 只能与 v-if 配合 v-show 会失效
<template v-if="表达式">
    <h1>h1</h1>
    <h1>h2</h1>
</template>

16.列表渲染 循环

<div>
    <ul>
        <!-- 每个li标签需要有其单独唯一的标识 -->
        <li v-for="p in persons" :key="p.id">{{p.id}}-{{p.name}}</li>
        
        
        <!-- p为persons中的元素 index为其对应的下标 index写key比较方便  -->
        <li v-for="(p,index) in persons" :key="index">{{p.id}}-{{p.name}}</li>
    
    	<!-- v-for 可以遍历 数组,对象,字符串  -->
        <!-- 遍历对象 -->
        <li v-for="(value,key) in Obj" :key="key">{{key}}-{{value}}</li>
    </ul>
</div>

<script>
new Vue({
	el:'#id',
    data:{
    	persons:[
            {id:"001", name:"001"},
            {id:"002", name:"002"},
            {id:"003", name:"003"},
        ]
        Obj:{
            name:"王二",
            adress:"二仙桥",
    	}
    }
})
</script>

<!-- 
v-for指令:
1.用于展示列表数据
2.语法:v-for="(item,index) in xxx" : key="yyy"
3.可逅历:数组、对象、字符串(用的很少)、指定次致(用的很少)
-->

17.循环 key详解

<!-- 虚拟Dom 对比算法 !!! 对比后转化为真实 Dom
key 如果用 index进行绑定会出问题 -->
<!-- 一定要使用唯一的 key 可以使用数据库中的主键 -->

<!-- 
面试题: react、 vue中的key有什么作用?(key的内部原理)
	1,虚拟DON中'key的作用:
		key是虚拟DOA对象的标识,当状态中的数据发生变化时,Vue会根据【新数据】生成【新的虚拟DO随后Vue进行【新虚抵DOM】 与【旧虚拟DOM】的差异比较,比较规则如下:
	2.对比规则:
		(1).旧虚拟DOM中找到了与新虚拟DO相同的key:
			若虚拟DOM中内容没变,百接使用之前的真实DOM
			若虚拟DOM中内容变了,则生成新的真实DOM。随后替换掉页面中之前的真实DOM
		(2).旧虚拟DOM中未找到与新虚拟DOM相同的key
			创建新的真实DOM。随后渲染到到页面。
3.用index作为key 可能会引发的问题:
	1.若对数据进行:逆序添加、逆序剧除等破环顺序操作:
			会产生没有必要的真实DOM更新==>界面效果没问题,但效率低。
	2.如果结构中还包含输入类的DOM:
			会产生错误DOM更新==>界面有问题
4.开发中如何选择key?:
	1.最好使用每条数据的唯一标识作为key,I比如id、于机号、身份证号、学号等唯一伯。
	2.如果不存在对数据的逆序添加、逆序朋除等破坏顺序操作,仅用于渲染列表用于展示使用index作为key是没有问题的。
-->

18.列表过滤 (搜索)

<input v-model="keyWord" placeholder="请输入姓名">
<ul>
	<li v-for="p in filterPersons" :key="p.id">{{p.id}}-{{p.name}}</li>
    <button @click="sortType = 1">id降序</button>
    <button @click="sortType = 0">原排序</button>
</ul>


<script>
new Vue({
	el:'#id',
    data:{
        sortType:0,
        keyWord:"",
    	persons:[
            {id:"001", name:"001"},
            {id:"002", name:"002"},
            {id:"003", name:"003"},
            {id:"004", name:"004"},
        ],
        filterPersons:[],
    },
    // 使用watch 实现搜索方法
    watch:{
        keyWords:{
            immediate:true,
            handler(val){
                this.filterPersons = this.persons.filter((e)=>{
                    return p.name.indexOf(bal) !== -1;
                })
            }
        }
    },
    // 计算属性实现
   
    computed:{
        filterPersons:{
            return this.persons.filter((p)=>{
        		return p.name.indexOf(this.keyWord) !== -1;
    		})
		}
    }
    
     // 实现 分需求 排序功能
    computed:{
        filterPersons:{
            const list = this.persons.filter((p)=>{
        		return p.name.indexOf(this.keyWord) !== -1;
    		})
            if(this.sortType){
                list.sort((p1.age,p2.age)=>{
                    return this.sortType === 1 ? p1.age-p2.age : p2.age-p1.age;
                }
             return list;             
            }
		}
    }
    
})
</script>

<!-- 
"abc".indexOf('') >>> 0  //空字符串返回值为 0
-->

3.Vue检测数据的原理

19.Vue检测数据改变的原理

<!-- 更改数据 -->
<script>
    
    // Vue无法检测
vm.persons[0] = {id:"001", name:"马老师", age:50}; 

	// Vue可以检测
vm.persons[0].name = "马老师";
vm.persons[0].age = 50;
</script>

<script>
    // data --> 加工后 vm 对象中生成 _data 包含data中的属性 并创建对应的getter setter方法
    get set 方法 在调用 对象时会自动被更改

    
    // 直接 object.defineProperty 对应的对象 调用get set 会陷入死循环
    
    // 创建检测实例对象 进行数据代理
    data = {
        name:"王二",
        age:18,
    }
    const obs = new Observer(data)
    console.log(obs)
    
    function observer(obj){
        //汇总对象中所有的属性形成一个数组
        const keys = object.keys(obj)
        //遍历
        keys.forEach((k)=>{
            object.defineProperty(this,k,{
                get(){
                    return obj[k]
                },
                set(val){
                    obj[k] = val
                } 
</script>
!!!!!! 检测原理就是使用setter 考虑非常周到!递归数组都能检测!!!

20.vue.set 添加响应式属性

// _data 与 data 是数据代理

// Vue 方法
Vue.set(target,key,value)
Vue.set(vm.student,"name","王二")
Vue.set(vm._data.student,"name","王二")

// vm 方法
vm.$set(vm.student,"name","王二")
vm.$set(vm._data.student,"name","王二")


// 局限性 set 不能 将 vm 作为 target

21.Vue检测数组

// 不能直接更改数组中的数值 vue 无法检测
// Vue 可以检测程序员使用数组方法

// 以下均为可以修改数组的方法
/*	push/pop 末尾 添加/删除 元素
*	unshift/shift 开头 添加/删除 元素
*	splice 替换元素
*	sort 排序
*	reverse 反转		
*/

// 两个push不一样 vue 对push进行了覆写 原push功能 + 响应式的更改
vm.data.student.hobby.push === Array.prototype.push 
>>> false 

总结

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

特别注意: Vue.set()和 vm.$set()不能给vm 或 vm的根数据对象添加属性 !!
*/

4.收集表单数据

/*
若:<input type="text"/>,则v-model收集的是value值。用户输入的就是value值。
若:<input type="radio" />,则v-model收集的是value值,且要给标签配置value值。
若:<input type="checkbox"/>
	1.没有配置input的value属性,那么收集的就是checked(勾选or未勾选,是布尔值)
	2.配置input的value属性:
		(1)v-model的初始值是非数组,那么收集的就是checked(勾选 or未勾选,是布尔值)
         (2)v-model的初始值是数组,那么收集的的就是value组成的数组
备注:v-model的三个修饰符:
	lazy:失去焦点再收集数据
	number:输入字符串转为有效的数字
	trim:输入首尾空格过滤
*/

5.过滤器

day.js 库可以格式化时间

在BootCDN可以查询到开源的所有库

过滤器 可以在 v-bind 与 插值语法中使用
<!-- 语法: 本质是一种函数 可以连续链式使用-->
<h3>现在是: {{time | timeFormater() | otherFilters()}}</h3>
<script>
    // 全局过滤器 任意 Vue 实例对象中均可使用
    Vue.filter("mySlice",fuction(){
         return "过滤后的内容"
		})
var vm = new Vue({
	filters:{
		timeFormater(value){
			return "value为传入time的值 返回值作为 表达式展示的值"
		}
	}
})
</script>

6.Vue指令汇总

<!--
	v-bind :单向绑定解析表达式,可简写为:XXX
	v-model :双向数据绑定
	v-for :遍历数组/对象/字符串
	v-on: 绑定事件监听,可简写为@
	v-if:条件渲染(动态控制节点是否存存在)
	v-else:条件渲染《动态控制节点是否存存在)
	v-show:条件渲染(动态控制节点是否展示)
	v-text: 替换整个 Value
	v-html: 可以渲染html语法 <h1></h1>
	// v-html 具有安全性问题 xss注入
	v-cloak: 加入该属性与css display:none Vue接管时会删除该属性
	v-once: 让某元素只渲染一次
	v-pre: 阻止Vue解析doucment
-->

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

<!--
v-cloak指令(没有值):
	1.本质是一个特殊属性,Vue实例创建完中并接管容器后。会删掉v-cloak属性.
	2.使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题。

-->
<style>
    [v-cloak]{
        display:none;
    }
</style>



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

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

-->

7.Vue自定义指令

7.1函数式

n放大十倍之后的值为:
<span v-big="n"> </span>
<input v-bind:value="n">


<script>
new Vue({
    directives:{
        // element传入对应元素对象
        // binding 与 big中的表达式绑定 "n"
        big(element,binding){
            element.innerText = binding.value * 10;
            // 绑定时会自动调用 但是 input 还没有放入doucment fouce不起作用
            element.fouce();
        }
        // big函数何时会被调用?
        // 1.指令与元素成功绑定时(一开始)
        // 2.指令所在的模板被重新解析时
    } 
})
</script>

7.2对象式

<input v-fbind:value="n">

<script>
new Vue({
    directives:{
        // 此对象中所有的 this 均指向 window
        fbind:{
            // 绑定时被调用
            bind(){
			},
            // 元素被插入时被调用
            inserted(){
            },
            // 模板被重新解析时被调用
            update(){
			},
        }
    } 
})
</script>

7.3小总结

注意: 命名时尽量不要用大写字母 Vue 会将大写字母 解析成小写字母
v-set-member  --->   `set-member`(){}

<script>
	// 全局Vue directives配置
   	Vue.directive('big',{
        ...
    })
</script>

8.生命周期函数

8.1 mounted介绍

// 动态绑定数据需要写成对象的形式
<h2 style="{opacity: opacity}"> 我会变化透明度 </h2>
// 属性值与键名重复时可简写   
<h2 style="{opacity}"></h2>
<script>
new Vue({
    data:{
    	opacity:1,
    },
    methos:{
    	change(){
            // 非 Vue 管理的函数 使用箭头函数 this 指向 Vue(vm)
            setInterval(()=>{
                this.opacity -= 0.01;
                if(this.opacity <= 0) this.opacity = 1;
                // 透明变化的字体
            },16)
        }
	},
    // mounted 挂载
    // Vue完成模板的解析并且把初始的真实Dom放入元素页面后(挂在完毕后) 执行mounted
    // 写入此处执行一次 mounted 函数 进行计时器函数书写
    // 第一次放入时执行 !!! 之后的叫更新 重新解析 不执行 mounted 
    mounted(){
        setInterval(()=>{
                this.opacity -= 0.01;
                if(this.opacity <= 0) this.opacity = 1;
                // 透明变化的字体
            },16)
    }
    // 生命周期函数有多种 这里只介绍了 mounted
    })
</script>

8.2挂载流程

<script>
new Vue({
    
    tmplate:`在此处可以写 HTML 语法 替换模板`
    // 初始化:生命周期、事件,但数据代理还未开始。
    // 此时:无法通过vm访问到data中的数据. methods中的方法。
	beforeCreate(){}
    
    // 初始化:数据监测、数据代理。
    // 此时:可以通过vm访问到data中的数据、 methods中配置的方法。
    // 还未进行模板解析 生成虚拟DOM
    created(){}
    
    // 1.页面呈现的是未经Vue编译的DOM结构。
    // 2.所有对DOM的操作,最终都不奏效。 因为在最后会使用 虚拟DOM 替换全部真实DOM
    // 进行模板解析之后 虚拟DOM已生成
    beforeMount(){}
    
    // 将虚拟DOM转为真实DOM插入页面
    // 1.页面中呈现的是经过Vue编译的DOM.
    // 2.对DOM的操作均有效(尽可能避免)。
    // 至此初始化过程结束,一般在此进行:
    // 开启定时器、发送网络请求、订阅消息、绑定自定义事件、等初始化操作。
    mounted(){}
    })
</script>

8.3更新流程:

new Vue({
    // 此时:数据是新的,但页面是旧的,即:页面尚未和数据保持同步。
    beforeUpdate(){}
    
    // 虚拟DOM 之间的对比 修改虚拟DOM
    
    // 此时:数据是新的,页面也是新的,即:页面和数据保持同步。
    updated(){}
})

8.4销毁流程

// 使用 $destroy() 方法 完全销毁vm实例 不会进行管理 DOM页面了
// vm.$destroy()
// 原生DOM事件不会被销毁 会销毁自定义事件

new Vue({
    // 此时: vm中所有的: data、methods、指令等等,都处于可用状态,马上要执行销毁过程,一般在此阶段:关闭定时器、取消订阅消息.解绑自定义事件等收尾操作
    beforeDestory(){}
    
    // vm 已销毁
    destoryed(){}
})

在这里插入图片描述

9.组件化 !!!

定义:现实应用中局部功能代码和资源的集合

非单文件组件∶

​ 一个文件中包含有n个组件。

单文件组件∶

​ 一个文件中只包含有1个组件。

1.非单文件组件

1.非单文件组件

// 1.创建组件
const school = Vue.extend({
    // 不需要写 el 配置项 只可配置在 vm 实例中
    // el:"",
    // data 必须写成函数式
    // 对象式引用的内存中同一地址 会出错(Vue报错阻止)
    data:fouction(){
    	return {...}
	}
    template:`
		HTML 内容
	`
})


// 2.注册组件
new Vue({
    el:"#root",
    // 注册组件 (局部注册)
    components:{
        xuexiao:school,
        // 以下可以简写
        school:school,
        // 简写形式
        school
    }
})
// 全局注册组件
// Vue.component('hello',hello)


// 3.在HTML页面中使用组件标签
// 在 components 中配置的键值
/*
<div id="root">
	<xuexiao></xuexiao>
</div>
*/

注意点

// Vue推荐组件命名
/*
单个单词: 1.school (纯小写) 2.School(首字母大写)
多个单词: 1.my-school (用-连接) 2.MySchool(每个单词首字母均大写 需要Vue脚手架支持)
备注:
	(1).组件名尽可能回避HTAL中已有的元素名称,例如:h2、H2都不行。
	(2).可以使用name配置项指定组件在开发者工具中呈现的名字。
	Vue.extend({
		name:"显示的名字",
	})


2.关于组件标签:
	第一种写法:<school></school>
	第二种写法:<school/>
	备注:不用使用脚手架时,<schoo1/>会导致后续组件不能渲染。

3.一个简写方式:
	const school = Vue.extend(options)可简写为: const school = options
	// 如果注册时传入的是对象 Vue 自动调用Vue.extend
*/

2.组件的嵌套

// 可以在组件中书写组件配置项

const school = Vue.extends({
    template:"...",
    compoent:{
        scool,
        "..."
    }
})

const student = Vue.extends({
    template:"...",
    components:{
        scool,
        "..."
    }
})

3. Vue Compoent构造函数

vm 实例中 包含 $children 为数组 数组中包含着 VueComponent 对象
VueComponent 中 的成员变量以及方法与 vm 一致

组件: 不可使用 el  data 只能使用函数式
/*
关于VueComponent:
	1.school组件木质是一个名为vueComponent的构造函数,且不是和序员定义的,是Vue.extend生成的。
	2.我们只需要写<school/>或<schoolx</school>.Vue解析时会帮我们创建school组件的实例对象,Nvue帮我们执行的: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.
*/

4.重要的内置关系

/*
1.一个重要的内置关系:VueComponent.prototype._proto_ == Vue.prototype
2.为什么要有这个关系:让组件实例对象(vc)可以访问到Vue原型上的属性、方法。
*/

Vue 与 VueComponent 的关系

image-20220405165609319

2.单文件组件

{webpack, 脚手架} 编译使用 .vue后缀

image-20220405182255969

App结构

安装 VSCODE vue 插件 后 输入 <v tab键就可自动补全

image-20220405182553879

main.js

image-20220405182701818