【Vue2学习笔记】Vue2入门学习-01

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: 本笔记跟随Bilibili尚硅谷张天禹讲师的Vue全家桶课程学习,非常适合不了解Vue2的同学们入门观看!

Vue2入门笔记

Vue入门必备本!

⭐关注我查看全套配套笔记

学习视频: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(){}
})

image-20220328193753311

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

相关文章
|
2月前
|
API UED
如何实现Vue2项目升级Vue3?
如何实现Vue2项目升级Vue3?
282 59
|
2月前
|
缓存 JavaScript 前端开发
「offer来了」从基础到进阶原理,从vue2到vue3,48个知识点保姆级带你巩固vuejs知识体系
该文章全面覆盖了Vue.js从基础知识到进阶原理的48个核心知识点,包括Vue CLI项目结构、组件生命周期、响应式原理、Composition API的使用等内容,并针对Vue 2与Vue 3的不同特性进行了详细对比与讲解。
「offer来了」从基础到进阶原理,从vue2到vue3,48个知识点保姆级带你巩固vuejs知识体系
|
2月前
|
JavaScript 前端开发 小程序
一小时入门Vue.js前端开发
本文是作者关于Vue.js前端开发的快速入门教程,包括结果展示、参考链接、注意事项以及常见问题的解决方法。文章提供了Vue.js的基础使用介绍,如何安装和使用cnpm,以及如何解决命令行中遇到的一些常见问题。
一小时入门Vue.js前端开发
|
1月前
|
JavaScript 前端开发 算法
对比一下Vue2 和 Vue3?—— 8个方面给你答案
本文介绍了 Vue 和 React 的起源、核心思想、表现形式、API 差异、社区差异、升级方向、响应式原理、Diff 算法、事件机制,并进行了总结。Vue 以其渐进式框架设计和简洁性著称,而 React 则强调单向数据流和灵活性。两者均支持组件化开发和虚拟 DOM,适用于不同的开发场景。
24 0
对比一下Vue2 和 Vue3?—— 8个方面给你答案
|
1月前
|
存储 JavaScript 前端开发
前端开发:Vue.js入门与实战
【10月更文挑战第9天】前端开发:Vue.js入门与实战
|
1月前
|
缓存 JavaScript 前端开发
对比一下Vue2和Vue3?
本文首发于微信公众号“前端徐徐”,详细对比了 Vue 2 和 Vue 3 在原理、生命周期、性能、编码方式、API、Diff 算法、打包构建、TS 支持等八个方面的差异,帮助读者全面了解两者的不同之处。
180 0
对比一下Vue2和Vue3?
|
1月前
|
JavaScript API 开发者
十分钟 带你强势入门 vue3
十分钟 带你强势入门 vue3
63 1
|
1月前
|
JavaScript API
|
1月前
|
JSON JavaScript 前端开发
vue尚品汇商城项目-day00【项目介绍:此项目是基于vue2的前台电商项目和后台管理系统】
vue尚品汇商城项目-day00【项目介绍:此项目是基于vue2的前台电商项目和后台管理系统】
45 1
|
1月前
|
JavaScript
vue3完整教程从入门到精通(新人必学2,搭建项目)
本文介绍了如何在Vue 3项目中安装并验证Element Plus UI框架,包括使用npm安装Element Plus、在main.js中引入并使用该框架,以及在App.vue中添加一个按钮组件来测试Element Plus是否成功安装。
65 0
vue3完整教程从入门到精通(新人必学2,搭建项目)
下一篇
无影云桌面