vue核心

vue的特点

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

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

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

 

helloworld的一个小案例

1)想让vue工作,就必须创建一个vue案例,且要传入一个配置对象

2)root容器里的代码依然符合html规范,只不过混入了一些特殊的vue语法

3)root容器里的代码被称为vue模板

4)vue实例和容器是一一对应的

5)真实开发中只有一个vue实例,并且会配合着组件一起使用

6){{xxx}}中的xxx要写js表达式,且xxx可以自动读取到data中的所有属性

7)一旦data中的数据发生改变,那么模板中用到该数据的地方也会自动更新

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    </head>
    <body>
        <div id="root">
            <h1>{{name}}之道</h1>
        </div>
        <script type="text/javascript">
            const x = new Vue({
                el:'#root',
                data:{
                    name:'学习'
                }
            })
        </script>
    </body>
</html>

 

模板语法

  1.插值语法

    功能:用于解析标签体内容

    写法:{{xxx}}, xxx是js表达式,且可以直接读取到data中的所有属性

  2.指令语法

    功能:用于解析标签(包括:标签属性、标签体内容、绑定事件...)

    举例:v-bind:href="xxx" 或简写为: :href="xxx"   xxx同样要写js表达式,且可以直接读取到data中的所有属性

 

数据绑定

  1.单向绑定: 数据只能从data流向页面

  2.双向绑定:数据不仅能从data流向页面,还可以从页面流向data

    备注:双向绑定一般都应用在表单类元素上

       v-model:value 可以简写为 v-model 因为v-model默认收集的就是value值 

 

el的两种写法

  

 

 data的两种写法

  1).对象式

  2).函数式

    如何选择:目前哪种都可以,但是到了使用组件的阶段,data必须使用函数式,否则会报错

  3)一个重要的原则,由vue管理的函数,一定不要写箭头函数,一旦写了箭头函数,this就不再是vue实例了

 

 

MVVM 模型

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

  V:视图(View) 模板      

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

 

 

数据代理

  数据代理:就是将数据交由Object.defineProperty(Person,'age')

  如下例子中,当有需求获取age属性时,就会调用get()方法,当我们想要修改age的大小时,直接给其赋值,根据所写的set()方法,会直接将值赋给number,之后如果想要再获取age值,就再调用get方法获取number

  例子如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    </head>
    <body>
        <script type="text/javascript">
            let number = 18
            let person = {
                name:'张三',
                sex:'',
            }    
            Object.defineProperty(person,'age',{
                get(){
                    console.log('有人读取age属性了')
                    return number
                },
            
                set(value){
                    console.log('有人修改了age属性,并且值为',value)
                    number = value
                }
            
            })
        </script>
    </body>
</html>

  事件的基本使用

  1)使用v-on:xxx  或者xxx  绑定事件  其中xxx是事件名

  2)事件的回调需要配置在methods对象中,最终会在vm上

  3)methods中配置的函数,不要用箭头函数!否则this就不是vm了

  4)methods中配置的函数,都是被vue所管理的函数,this的指向是vm或组件实例对象

  5)@click=“demo” 和 @click=“demo($event)” 效果一致,后者可以传参

  

  事件修饰符

  1)prevent   阻止默认事件  (常用)

  2)stop        阻止事件冒泡  (常用)

  3)once:   事件只触发一次   (常用)

  4)capture: 使用事件的捕获模式

  5)self:     只有event.target是当前操作的元素才是触发事件

  6)passive:事件的默认行为立即执行,无需等待事件回调执行完毕

   例子如下,只举例了常用的

  

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    </head>
    <style>
        *{
            margin-top: 20px;
        }
        .demo1{
            height: 50;
            background-color: aqua;
        }
    </style>
    <body>
        <div id="root">
            <h2>欢迎来到{{name}}学院</h2>
            <a href="http://www.baidu.com" @click.prevent="showInfo()">点我提示信息</a>
            
            <div class="demo1" @click="showInfo()">
                <button @click.stop="showInfo()">点我提示信息</button>
            </div>
            
            <button @click.once="showInfo()">点我提示信息</button>
        </div>
        <script type="text/javascript">
            new Vue({
                el:'#root',
                data:{
                    name:'gubi'
                },
                methods:{
                    showInfo(e){
                        //e.stopPropagation()
                        //e.preventDefault()
                        alert('hello')
                    }
                }
            })
        </script>
    </body>
</html>

   键盘事件

    vue中常见的按键别名:

      回车  =>  enter

      删除  =>  delete

      退出  =>  esc

      空格  =>  space

      换行  =>  tab

      上     =>   up

      下     =>   down

      左     =>   left

      右     =>   right

   vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转化为kebab-case(短横线命名)

   系统修饰键(用法特殊)  ctrl、alt、shift、meta

      配合keyup使用  按下修饰按键的同时,再按下其他键,随后释放其他键,事件才被触发

      配合keydown使用,正常触发事件

   也可以使用keyCode去指定具体的按键(不推荐)

   Vue.config.keyCodes.自定义键名 =  键码, 可以去定制按键别名

   举例(按下回车提示信息)

   

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    </head>
    <body>
        <div id="root">
            <input type="text" placeholder="按下回车提示输入" @keyup.enter="showInfo()">
        </div>
    </body>
    <script type="text/javascript">
        new Vue({
            el:'#root',
            data:{
                name:'gubi'
            },
            methods:{
                showInfo(e){
                    //e.stopPropagation()
                    //e.preventDefault()
                    alert('hello')
                }
            }
        })
    </script>
</html>

 组合键的使用方式:

 

 

姓名案例

插值语法实现

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    </head>
    <body>
        <div id="root">
            姓: <input type="text" v-model="firstname">  <br/><br/>
            名:     <input type="text" v-model="lastname">  <br/><br/>
            全名: <span>{{firstname}}-{{lastname}}</span>
        </div>
    </body>
    <script type="text/javascript">
        new Vue({
            el:'#root',
            data:{
                firstname:'',
                lastname:'',
            }
        })
    </script>
</html>
View Code

methods实现

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    </head>
    <body>
        <div id="root">
            姓: <input type="text" v-model="firstname">  <br/><br/>
            名:     <input type="text" v-model="lastname">  <br/><br/>
            全名: <span>{{fullname()}}</span>
        </div>
    </body>
    <script type="text/javascript">
        new Vue({
            el:'#root',
            data:{
                firstname:'',
                lastname:'',
            },
            methods: {
                fullname(){
                    return this.firstname+'-'+this.lastname
                }
            }
        })
    </script>
</html>
View Code

计算属性实现

  1)定义:要用的属性不存在,要通过已有属性计算得来

  2)原理:底层借助了Object.defineproperty方法提供的getter和setter

  3)get函数什么时候执行?

      初次读取时会执行一次(接下来如果数据没有改变就不会再执行,因为有缓存)

      当依赖的数据发生改变时会被再次调用

  4)优势:与methods相比,内部有缓存机制(复用)效率更高,调试方便

  5)备注:

    计算属性最终会出现在vm上,直接读取使用即可

    如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    </head>
    <body>
        <div id="root">
            姓: <input type="text" v-model="firstname">  <br/><br/>
            名:     <input type="text" v-model="lastname">  <br/><br/>
            全名: <span>{{fullname}}</span>
        </div>
    </body>
    <script type="text/javascript">
        const vm = new Vue({
            el:'#root',
            data:{
                firstname:'',
                lastname:'',
            },
            computed:{
                fullname:{
                    get(){
                        return this.firstname+'-'+this.lastname
                    },
                    set(value){
                        console.log('set',value)
                        const arr = value.split('-')
                        this.firstname=arr[0];
                        this.lastname=arr[1];
                    }
                }
            }
        })
    </script>
</html>
View Code

 

 

监视属性

  1)当被监视的属性变化时,回调函数自动调用,进行相关操作

  2)监视的属性必须存在,才能进行监视

  3)监视的两种写法(以下代码中有)

    通过.new Vue时传入watch配置

    通过vm.$watch监视

  

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    </head>
    <body>
        <div id=root>
            <h2>今天天气很{{info}}</h2>
            <button @click="changeWeather">切换天气</button>
        </div>
    </body>
    <script type="text/javascript">
        const vm = new Vue({
            el:'#root',
            data:{
                isHot:true
            },
            computed:{
                info(){
                    return this.isHot ? '炎热' : '凉爽'
                }
            },
            methods:{
                changeWeather(){
                    this.isHot=!this.isHot
                }
            },
            //写法1
            /* watch:{
                isHot:{
                    handler(newValue,oldValue){
                        console.log('ishot被修改了',newValue,oldValue)
                    }
                }
            } */
        })
        //写法2, 适用于一开始不知道要监视的对象,后来才得知然后补上的情况
        vm.$watch('isHot',{
            handler(newValue,oldValue){
                console.log('ishot被修改了',newValue,oldValue)
            }
        })
    </script>
</html>
View Code

 

深度监视

  1)vue中的watch默认不监测对象内部值的改变 (一层)

  2)配置deep:true可以监测对象内布置改变(多层)

 

computed和watch之间的区别

  1)computed能完成的功能,watch都可以完成

  2)watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作,但是computed不行

两个重要的小原则

  1)所被vue管理的函数,最好写成普通函数,这样this的指向才是vm或组件实例对象

  2)所有不被vue所管理的函数(定时器的回调函数,ajax的回调函数等),最好写成箭头函数,这样this的指向才是vm或组件实例对象

 

绑定样式

  我们在进行开发的时候,如果不用vue的话,免不了直接操作dom对象,vue给了我们一种间接操作dom对象的方法

  如下代码中,使用了三种间接操作dom对象并且给其赋予样式的方式,各有优劣

  

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <style>
            .basic{
                width: 400px;
                height: 100px;
                border: 1px solid black
            }
            .tmp1{
                background-color: red;
            }
            .tmp2{
                background-color: green;
            }
            .tmp3{
                background-color: black;
            }
        </style>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    </head>
    <body>
        <div id="root">
            <!-- 绑定class样式--字符串写法,适用于:样式的类名不确定,需要动态指定 -->
            <div class="basic" :class="mood" @Click="changeMood">test</div>
            <!-- 绑定class样式--数组写法, 适用于:要绑定的样式个数不确定、名字不确定 -->
            <div class="basic" :class="classArr">test</div>
            <!-- 绑定class样式--对象写法,适用于:要绑定的样式个数确定,名字也确定,但要动态决定是否使用 -->
            <div class="basic" :class="classObj">test</div>
        </div>
    </body>
    <script type="text/javascript">
        const vm = new Vue({
            el:'#root',
            data:{
                mood:'tmp1',
                classArr:['tmp1','tmp2'],
                classObj:{
                    tmp1:false,
                    tmp2:false,
                    tmp3:false
                }
            },
            methods:{
                changeMood(){
                    const arr = ['tmp1','tmp2','tmp3']
                    const index = Math.floor(Math.random()*3)
                    this.mood=arr[index]
                }
            }
        })
    </script>
</html>
View Code

 

条件渲染

  v-if 

   1)v-if=“表达式”

   2)v-else-if="表达式"

   3)v-else="表达式

  适用于:切换频率较低的场景

  特点:不展示的DOM元素直接被移除

  注意::v-if可以和:v-else-if、 v-else 一起使用,但要求结构不能被“打断”

 v-show

   写法:v-show="表达式"

   适用于:切换频率较高的场景

      特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉

 注意:使用v-if时,元素可能无法获取到,而使用v-show一定可以获取到

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    </head>
    <body>
        <div id="root">
            <h2 v-show="flag">{{name}},欢迎您</h2>
            <h2>当前的n值时:{{n}}</h2>
            <button @click="n++">点我n+1</button>
            <div v-if="n===1">hah</div>
            <div v-else-if="n===2">huh</div>
            <div v-else-if="n===3">xix</div>
        </div>
    </body>
    <script type="text/javascript">
        const vm = new Vue({
            el:'#root',
            data:{
                name:'gubi',
                flag:true,
                n:0
            }
        })
    </script>
</html>
View Code

 

 

列表渲染

  v-for 指令

    1)用于展示列表数据

    2)语法:v-for="(item,index) in xxx" :key="yyy"

    3) 可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)

  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时没有问题的

 

列表过滤

  想要实现列表过滤,可以通过监听和计算

  举个例子:如下,我们进行关键字查询来过滤出条件

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    </head>
    <body>
        <div id="root">
            <input type="text" placeholder="请输出名字" v-model="keyWord"/>
            <ul>
                <li v-for="p in filpersons">
                    {{p.name}}-{{p.age}}
                </li>
            </ul>
        </div>
    </body>
    <script type="text/javascript">
        new Vue({
            el:'#root',
            data:{
                keyWord:'',
                persons:[
                    {id:'001',name:'马冬梅',age:18,sex:''},
                    {id:'001',name:'周冬雨',age:19,sex:''},
                    {id:'001',name:'周杰伦',age:20,sex:''},
                    {id:'001',name:'温兆伦',age:20,sex:''}
                ],
                filpersons:[]
            },
            /* 方式一 监听*/
            watch:{
                keyWord:{
                    immediate:true,
                    handler(val){
                        this.filpersons=this.persons.filter((p)=>{
                            return p.name.indexOf(val) !=-1
                        })
                    }
                }
            }
            /* 方式二 计算属性 */
            /* computed:{
                filpersons(){
                    return this.persons.filter((p)=>{
                        return p.name.indexOf(this.keyWord) !== -1
                    })
                }
            } */
        })
    </script>
</html>
View Code

 

vue数据监测原理

  1)vue监视data中所有层次的数据

  2)如何监测对象中的数据?

    通过setter实现监视,且要再new Vue时就传入要监测的数据

    1)对象中后追加的属性,vue默认不做响应式处理

    2)如需给后添加的属性做响应式,请使用如下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的根数据对象添加属性!

  例子如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    </head>
    <body>
        <div id="root">
            <h1>学生信息</h1>
            
            <button @click="addSex">添加性别属性,默认值:男</button>
            <button @click="addFriend">在列表首位添加一个朋友</button>
            <button @click="updateFirstFriendName">修改第一个朋友的名字为:张三</button>
            <button @click="addHobby">添加一个爱好</button>
            <button @click="updateHobby">修改第一个爱好为开车</button>
            
            <h3>姓名:{{student.name}}</h3>
            <h3>年龄:{{student.age}}</h3>
            <h3>年龄:{{student.sex}}</h3>
            <h3>爱好</h3>
            <ul>
                <li v-for="(h,index) in student.hobby" :key=index>
                    {{h}}
                </li>
            </ul>
            <h3>朋友们</h3>
            <<ul>
                <li v-for="(f,index) in student.friends" :key=index>
                    {{f.name}}--{{f.age}}
                </li>
            </ul>
        </div>
    </body>
    <script type="text/javascript">
        const vm = new Vue({
            el:'#root',
            data:{
                student:{
                    name:'tom',
                    age:18,
                    hobby:['抽烟','喝酒','烫头'],
                    friends:[
                        {name:'jerry',age:35},
                        {name:'tony',age:36}
                    ]
                }
            },
            methods:{
                addSex(){
                    //这种写法vue不认
                    //this.student.sex='男'
                    Vue.set(this.student,'sex','')
                },
                addFriend(){
                    this.student.friends.unshift({name:'jack',age:70})
                },
                updateFirstFriendName(){
                    this.student.friends[0].name='张三'
                },
                addHobby(){
                    this.student.hobby.push('学习')
                },
                updateHobby(){
                    //这句话意思为,删除第0个,然后插入一个新的,叫开车
                    this.student.hobby.splice(0,1,'开车')
                }
                
            }
        })
    </script>
</html>
View Code

 

收集表单数据

  若 <input type="text" /> 则v-model收集的就是value值,用户输入的就是value值

  若 <input type="radio" /> 则v-model收集的就是value值,且要给标签配置value值

  若 <input type="checkbox"/> 

    1)没有配置input的value属性,那么收集的就是checked   (布尔值)

    2)配置input的value值

      如果v-model的初始值是非数组,那么收集的是checked

      如果v-model的初始值是数组,那么收集的就是value值

    v-model的三个修饰符

      lazy: 失去焦点时再收集数据

      number: 输入字符串转为有效的数字

      trim: 输入首位空格过滤

 

过滤器 (没有进行实操,视频在P39)

  定义:对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理)

  语法:

    1)注册过滤器 Vue.filter(name,callback) 或 new Vue{filters:{}}

    2)使用过滤器: {{xxx | 过滤器名 }}  或  v-bind: 属性 = “xxx | 过滤器名”

  备注:

    1)过滤器可以接受额外参数,多个过滤器也可以串联

    2)并没有改变原本的数据,是产生新的对应数据

 

内置指令

  我们在这之前学过的指令有

  v-bind:         单向绑定解析表达式

  v-model:      双向数据绑定

  v-for:            遍历

  v-on:            绑定事件监听,可以简写为@

  v-if:              条件渲染语句

  v-else:         条件渲染语句

  v-show:       条件渲染语句

  

  接下来我们要学习的指令

  v-text   

    作用:向其所在的节点中渲染文本内容

    与插值语法的区别: v-text会替换掉节点中的内容  {{xxx}}则不会

    不能解析html语法

  例子如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    </head>
    <body>
        <div id="root">
            <!-- 这一种比较灵活 -->
            <div>{{name}}</div>  <br/>
            
            <!-- v-text这一指令用起来没有上面这一种顺手 -->
            <div v-text="name">你好</div>
        </div>
    </body>
    <script type="text/javascript">
        new Vue({
            el:'#root',
            data:{
                name:'gubi'
            }
        })
    </script>
</html>
View Code

  v-html

    作用:能够解析html语法

    与插值语法的区别:

      v-html会替换掉节点中的内容  {{xxx}}则不会

      可以识别html结构

    严重注意:v-html有安全性问题

      在网站上动态渲染任意HTML是非常危险的,容易导致X

  

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    </head>
    <body>
        <div id="root">
            <!-- 这一种比较灵活 -->
            <div>{{name}}</div>  <br/>
            
            <!-- v-text这一指令用起来没有上面这一种顺手 -->
            <div v-html="str">你好</div>
        </div>
    </body>
    <script type="text/javascript">
        new Vue({
            el:'#root',
            data:{
                name:'gubi',
                str:'<h3>你好啊!</h3>'
            }
        })
    </script>
</html>
View Code

  v-cloak

    本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性

    使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题

  v-once

    v-once所在节点再初次动态渲染后,就视为静态内容了

    以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    </head>
    <body>
        <div id="root">
            <h2 v-once>初始化的n值是:{{n}}</h2>
            <h2>当前的n值是:{{n}}</h2>
            <button @click="n++">click me  n++</button>
        </div>
    </body>
    <script type="text/javascript">
        new Vue({
            el:'#root',
            data:{
                n:1
            }
        })
    </script>
</html>
View Code

  v-pre

    跳过其所在节点的编译过程

    可利用它跳过:没有指令语法、没有使用插值语法的节点,会加快编译

  

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    </head>
    <body>
        <div id="root">
            <h2 v-pre>hahah,这里就适合用v-pre来加快编译</h2>
            <h2 v-once>初始化的n值是:{{n}}</h2>
            <h2>当前的n值是:{{n}}</h2>
            <button @click="n++">click me  n++</button>
        </div> 
    </body>
    <script type="text/javascript">
        new Vue({
            el:'#root',
            data:{
                n:1
            }
        })
    </script>
</html>
View Code

  自定义指令

    需求1:定义一个v-big指令,将绑定的数据10倍呈现

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    </head>
    <body>
        <div id="root">
            <h2>当前的n值为:{{n}}</h2>
            <h2>放大10倍后的n值为:<span v-big="n"> </span> </h2>
            <button @click="n++">click me n++</button>
        </div>
    </body>
    <script type="text/javascript">
        new Vue({
            el:'#root',
            data:{
                n:1
            },
            directives:{
                big(element,binding){
                    element.innerText=binding.value*10
                }
            }
        })
    </script>
</html>
View Code

    big函数何时会被调用?

      1)指令与元素成功绑定时

      2)指令所在的模板被重新解析时

    需求2:定义一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素默认获取焦点(在此例子中,只能用对象式,因为焦点这种细节问题函数式无法解决)

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    </head>
    <body>
        <div id="root">
            <h2>当前的n值为:{{n}}</h2>
            <h2>放大10倍后的n值为:<span v-big="n"> </span> </h2>
            <input type="text" v-fbind:value="n">
            <button @click="n++">click me n++</button>
        </div>
    </body>
    <script type="text/javascript">
        new Vue({
            el:'#root',
            data:{
                n:1
            },
            directives:{
                big(element,binding){
                    element.innerText=binding.value*10
                },
                /* fbind(element,binding){
                    element.value=binding.value*10
                } */
                fbind:{
                    bind(element,binding){
                        console.log('fbind',this)    //注意,指令的对象时window   
                        element.value=binding.value
                        console.log('bind')
                    },
                    inserted(element,binding){
                        element.focus()
                        console.log('inserted')
                    },
                    update(element,binding){
                        element.value=binding.value
                        console.log('update')
                    }
                }
            }
        })
    </script>
</html>
View Code

  语法总结:

    一、定义语法:

      

 

     二、配置对象中常用的3个回调

      1)bind:指令与元素成功绑定时调用

      2)inserted 指令所在元素被插入页面时调用

      3)update  指令所在模板结构被重新解析时调用

    三、备注

      1)指令定义时不加v-,但使用时要加v-

      2)指令名如果是多个单词,要使用kebab-case命名方式,不要用camelCase命名。

 

 

生命周期

  1)又名:生命周期回调函数,生命周期函数,生命周期钩子

  2)是什么:vue在关键时刻帮我们调用的一些特殊名称的函数

  3)生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的

  4)生命周期函数中的this指向是vm或组件实例对象

  举个例子,让一段话出现一种从实体到透明到实体的循环过程

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    </head>
    <body>
        <div id="root">
            <h2 :style="{opacity}">gubi加油</h2>
        </div>
    </body>
    <script type="text/javascript">
        const vm = new Vue({
            el:'#root',
            data:{
                opacity:1
            },
            
            //vue完成模板的解析并把初始的真实dom元素放入页面后调用mounted
            mounted(){
                console.log('mouted')
                setInterval(()=>{
                    this.opacity -= 0.01
                    if(this.opacity <= 0) this.opacity = 1 
                },16)
            }
        })
        
    </script>
</html>
View Code

  这个例子当中涉及了一个函数  mounted()  这就是生命周期当中的其中一个函数

  1)beforeCreate   初始化生命周期、事件,但数据代理还未开始,此时,无法通过vm访问到data中的数据,methods中的方法

  2)created            初始化数据监测、数据代理,可以通过vm访问到data中的数据,methods中配置的方法

  3)beforeMount    页面呈现的是未经vue编译的dom结构,所有对dom的操作,最终都不奏效

  4)mounted          页面中呈现的是经过vue编译的DOM   对DOM的操作均有效,至此初始化过程结束,一般会在这个阶段进行如下操作:开启定时器、发送网络请求、订阅消息、绑定自定义事件等初始化操作

    5)beforeUpdate   此时数据是新的,但页面是旧的,即:页面尚未和数据保持同步

  6)update             此时数据是新的,页面也是新的,即:页面和数据保持同步

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

  8)destory            

  常用的生命周期钩子:

  1)mounted  发送ajax请求、启动定时器,绑定自定义事件、订阅消息等初始化操作

  2)beforeDestory  清除定时器,解绑自定义事件,取消订阅消息等收尾工作

  关于销毁vue实例

  1)销毁后借助vue开发者工具看不到任何信息

  2)销毁后自定义事件会失效,但原生DOM事件依然有效

  3)一般不会在beforeDestory阶段操作数据,因为i即使操作了数据,也不会再触发更新流程了

  

 

posted @ 2021-10-11 16:26  古比  阅读(144)  评论(0编辑  收藏  举报