Vue框架知识点

 一.Vue简介

1.什么是Vue

一套构建用户界面(就是将数据展示给用户看得懂的)的渐进式(自底向上逐层应用) JavaScript框架

2.Vue的特点

2.1.采用组件化(new.vue[.vue里面包含html css js])的模式,提高代码的复用率,且让代码更好维护

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

2.3.使用虚拟的DOM+Diff算法(进行虚拟的DOM比较),尽量复用DOM节点

3.vue模板语法

            1.要让Vue进行工作,必选先创建一个Vue实例,且传入一个配置对象

            2.容器中的代码依然符合html规范,只不过混入一些特殊的Vue语法

            3.容器中的模板成为Vue模板

            4.一个Vue实例对应一个容器

            5.实际开发中只会有一个Vue实例,并且搭配组件进行使用

            6.{{XXX}} XXX为js中的表达式,并且可以自动读取到data中的数据

            7.当data中的数据发生变化时,页面中的数据也会发生改变

            注意:js表达式和js代码(语句)

            1.表达式:一个表达式会生成一个值,可以放在任何需要的地方

            (1).a a+b demo(1)

            2.js代码

            (2)if(){}  for(){}

            Vue模板语法

            1.插值语法 用来解析标签体中的内容

            {{XXX}} XXX为js中的表达式,并且可以自动读取到data中的数据

            2.指令语法

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

            v-bind:href='xxx' 可以简写成 :href='xxx' xxx同样要写js表达式,且可以读取到data中的所有属性

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 引入vue -->
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <!-- 容器准备 -->
    <div class="root">
        <h1>你好,{{name}}</h1>
        <a :href="user.url">{{user.name}},去百度学习</a>
    </div>
    <script type="text/javascript">
    new Vue({
        el:'.root',
        data:{
            name:'jack',
            user:{
                name:'cms',
                url:'http://www.baidu.com',
            }
        }
    })
    </script>
    
</body>
</html>

4.数据绑定

        数据绑定两种方式:

        1.v-bind 单向绑定 数据只能从data流向页面

        2.v-model 双向绑定 数据不仅能从data流向页面 也能从页面流向data

        2.1双向绑定一般应用在表单元素上 (input select)

        2.2v-model:value可以简写成 v-model v-model就是获取value值

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <script>Vue.config.productionTip= false </script>
    <div class="root">
        单向数据绑定:<input type="text" v-bind:value="name">
        双向数据绑定:<input type="text" v-model="name">
    </div>
    <script type="text/javascript">
        new Vue({
            el:'.root',
            data:{
                name:'学习',
            }
        })

    </script>
    
</body>
</html>

5.el和data的两种写法

5.1用el  或者 用$.mount(mount挂载的意思)

5.2data 对象式或者函数式

 一个重要原则:由Vue管理的函数,一定不要写箭头函数 一但写了箭头函数就不在是Vue实例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <h1>你好,{{name}}</h1>
    </div>
    <script type="text/javascript">
        //el第一种写法
        // new Vue({
        //     el:'#root',
        //     data:{
        //         name:'jack',
        //     }
        // })
        // 第二种写法
        // const x=new Vue({
        //     data:{
        //         name:'jack',
        //     }
        // })
        // console.log(x)
        // //设置1000ms后将Vue实例和容器进行关联
        // setTimeout(()=>{
        //     x.$mount('#root')
        // },1000);
       //data两种写法
            new Vue({
                el:'#root',
                //data第一种写法 对象式
                // data:{
                //     name:'jack',
                // }
                //data第二种写法 函数式
                //一个重要原则:由Vue管理的函数,一定不要写箭头函数 一但写了箭头函数就不在是Vue实例
               data:function(){
                console.log(this) //此处表示的是Vue实例对象
                    return{
                        name:'jack1',
                    }
               }     
            })
    </script>
    
</body>
</html>

6. MVVM模型

MVVM模型

1.M 模型:data中的数据

2.V 视图:模板中的代理 就是容器中的模板代码

3.VM 视图模型:Vue实例 以后通过变量接收实例可以用 vm

3.1 data中的所有属性,最终都出现在vm上

3.2vm身上的属性以及Vue原型上的属性都可以在Vue模板中使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div class="root">
        <h1>名称:{{name}}</h1>
        <h1>地址:{{address}}</h1>
    </div>
    <script type="text/javascript">
    const vm=new Vue({
            data:function(){
                return{
                    name:'Vue',
                    address:'哔哩哔哩',
                }
            }
        })
        vm.$mount('.root')
    </script>
</body>
</html>

7.数据代理 

7.1Object.defineProperty()原理

传参:传入三个参数,一个是对象,一个是key,一个是value的操作

get:当有人读取person的age的属性,get函数(getter)就会被调用

set:当有人修改person的age的属性,set函数(setter)就会被调用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <script type="text/javascript">
        let number=18
        let person={
            name:'张三',
            sex:'男',
        }
        //传入三个参数,一个是对象,一个是key,一个是value的操作
        Object.defineProperty(person,'age',{
           // value:18,
           // enumerable:true,//控制属性是否能够枚举(就是能不能被遍历) 默认false
           // writable:true,//控制属性是否能被修改默认值 false
           // configurable,//控制属性是否能被删除,默认值false
           //当有人读取person的age的属性,get函数(getter)就会被调用,且返回值是age的值
            get:function(){
                return number
            },
            //当有人修改person的age的属性,set函数(setter)就会被调用,且收到修改的具体值
            set(value){
                number=value
            }

        })
        console.log(person)
        //将对象中的属性的key值进行遍历
        console.log(Object.keys(person))
    </script>
</body>
</html>

 7.2数据代理

 数据代理

    1.Vue中的数据代理

    通过vm对象来代理data中的属性操作(读/写)

    2.Vue中数据代理的好处

    更加方便的操作data中的数据

    3.基本原理

    通过 Object.defineProperty()方法把data中的所有属性添加到vm上

    为每一个添加的vm上的属性都指定一个getter和setter

    在getter和setter属性内部操作data中的属性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <h1>地址:{{name}}</h1>
        <h1>区域:{{address}}</h1>
    </div>
    <script type="text/javascript">
    const vm=new Vue({
        el:'#root',
            data () {
                return {
                    name:'长沙',
                    address:'天心区',
                }
            }
        })
    </script>
</body>
</html>

 8.事件处理

事件基本使用

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

        2.事件的回调配置需要在methods方法中,最终都会出现在vm上

        3.methods配置中方法不要使用箭头函数,否则这里的this就不是vm;

        4.mthods配置的函数都是被vue所管理的函数 this指向vm或者是组件实例对象

        5.@click="demo1" 和@click="demo2($event)"效果一样,后者可以传参

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <h1>你好,{{name}}</h1>
        <button v-on:click="showInfo">点我提示信息(不传参)</button>
        <button @click="showInfo2($event,11)">点我提示信息(传参)</button>
    </div>
    <script type="text/javascript">
        const vm=new Vue({
            data:{
                name:'jack'
            },
            methods: {
                showInfo(event){
                    //获取方法上的按钮
                    console.log(event)
                    console.log(this)//这里的this为vm实例
                    alert("学习Vue")
                },
                showInfo2(event,number){
                    console.log(event,number)
                    console.log(number)
                    alert("学习Vue2")
                },
            }
        })
        vm.$mount('#root')
    </script>
</body>
</html>

9.事件修饰符

Vue事件修饰符

        prevent 阻止默认事件

        stop 阻止冒泡事件

        once 事件只触发一次

        修饰符可以连续写 eg:@click.stop.prevent

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <!-- prevent 阻止跳转到对应页面 -->
        <a href="http://www.baidu.com" @click.prevent="show">点我去百度</a>
        <!-- stop阻止向上冒泡 -->
        <div class="demo" @click="show">
            <button @click.stop="show">点我跳转</button>
        </div>
        <!-- once 用一次之后就失效 -->
        <button @click.once="show">按钮只能用一次</button>
    </div>
    
    <script>
        const vm=new Vue({
            methods: {
                show(){
                    alert('点击跳转')
                }
            }
        })
        vm.$mount('#root')
    </script>
</body>
</html>

10.键盘事件

        Vue常用按键

        1.enter  delete(捕获删除和退格键) esc space

        换行 tab(特殊,必须搭配keydown使用)  上下左右

        2.系统修饰键(特殊用法)ctrl,alt,shift,meta(win键)

        2.1配合keyup使用时,按下修饰键时,在按下其他键,随后释放其他键,事件被触发

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

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <input placeholder="点我输入" @keydown.ctrl="show">
    </div>
    <script>
        const vm=new Vue({
            el:'#root',
            methods: {
                show(event){
                    //获取输入框中的值
                    console.log(event.target.value)
                }
            }
        })
    </script>
</body>
</html>

 11.姓名案例

11.1插值语法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div class="root">
        姓:<input v-model="firstName" type="text"><br>
        名:<input v-model="lastName" type="text"><br>
        全名:<span>{{firstName}}-{{lastName}}</span>
    </div>
    <script>
        const vm=new Vue({
            el:'.root',
            data () {
                return {
                    firstName:'张',
                    lastName:'三'
                }
            }
        })
    </script>
</body>
</html>

11.2methods

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div class="root">
        姓:<input v-model="firstName" type="text"><br>
        名:<input v-model="lastName" type="text"><br>
        全名:<span>{{fullName()}}</span>
    </div>
    <script>
        const vm=new Vue({
            el:'.root',
            data () {
                return {
                    firstName:'张',
                    lastName:'三'
                }
            },
            methods: {
                fullName(){
                    //这里的this就是vm实例 methods被Vue管理
                    return this.firstName+'-'+this.lastName
                }
            }
        })
    </script>
</body>
</html>

11.3计算属性(computed)

   计算属性computed

        1.要通过已有的属性进行进行计算得来

        2.原理:底层借助了Object.defineProperty中的getter和setter

        3.get调用时间

        3.1.初次读取的时候会被调用 3.2.所依赖的数据发生变化时

        4.和methods进行相比,内部有缓存机制

        5.计算的属性最终都会到vm上,直接使用即可

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

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div class="root">
        姓:<input v-model="firstName" type="text"><br>
        名:<input v-model="lastName" type="text"><br>
        全名:<span>{{fullName}}</span>
    </div>
    <script>
        const vm=new Vue({
            el:'.root',
            data () {
                return {
                    firstName:'张',
                    lastName:'三'
                }
            },
           computed: {
            // fullName:{
            //     //当fullName被读取时,get就会被调用,且返回值就是fullName的值
            //     //get啥时候被调用 1.初次读取的时候会被调用 2.所依赖的数据发生变化时
            //         get(){
            //             return this.firstName+'-'+this.lastName
            //         },
            //         //set啥时候调用,当fullName进行修改时
            //         set(value){
            //             //生成数组 按照指定字符串进分割
            //             const arr=value.split('-')
            //             this.firstName=arr[0]
            //             this.lastName=arr[1]
            //         }
            //     }
            
            //当只有读取数据,没有修改时,可以简写
            fullName:function(){
                return this.firstName+'-'+this.lastName
            }
                
            
           }
                
          
        })
    </script>
</body>
</html>

12.监视属性(watch)

    1.当被监视的属性发生变化时,回调函数进行调用(handler)

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

    3.两种方式

    (1)new Vue({})中写入watch

    (2)vm.$watch

 12.1天气案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <h1>今天天气{{info}}</h1>
        <button @click="change">点我切换</button>
    </div>
    <script>
       const vm= new Vue({
            el:'#root',
            data:{
                isHot:true
            },
            computed: {
                info(){
                    //三目运算
                    return this.isHot ?'炎热' :'凉爽' 
                }
            },
            methods: {
                change(){
                    return this.isHot=!this.isHot
                }
            },
            watch:{
                // isHot:{
                //     //immediate:true,//初始化时调用handler
                //     //当isHot发生变化时,handler被调用
                //     handler(newValue,oldValue){
                //         console.log("isHot被修改了",newValue,oldValue)
                //     }
                // }
                //简写形式
                isHot(){
                    console.log("isHot被修改了",newValue,oldValue)
                }
            }
        })
        //当创建vm实例不知道监听那个属性时,通过后续操作进行
        // vm.$watch('isHot',{
        //     handler(newValue,oldValue){
        //                 console.log("isHot被修改了",newValue,oldValue)
        //             }
        // })
    </script>
</body>
</html>

12.2深度监视

 深度监视
    1.Vue中的watch不默认监视对象内部值的改变 通过配置deep可以监视对象内部值的改变
    2.Vue自身是可以监测对象内部值的改变,但vue提供的watch是不可以的
    使用watch根据数据结构 是否要进行深度监视

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <h1>{{numbers.a}}</h1>
        <button @click="numbers.a++">点我a+1</button>
        <h1>{{numbers.b}}</h1>
        <button @click="numbers.b++">点我b+1</button>
    </div>
    <script>
       const vm= new Vue({
            el:'#root',
            data:{
                numbers:{
                    a:1,
                    b:1
                }
            },
            watch:{
                //监视多级结构中某个属性的变化
                // 'numbers.a':{
                //     handler(){
                //         console.log('a的值被修改了')
                //     }
                // }
                //监视多级结构中的所有属性
                numbers:{
                    deep:true,
                    handler(){
                        console.log('numbers被修改')
                    }
                }
            }

        })
       
    </script>
</body>
</html>

12.3watch和computed的区别

    1.computed能完成的功能,watch也能完成

    2.watch能完成的功能,computed不一定能完成 watch可以进行异步操作

    2.1所有被Vue管理的函数,最好写成普通函数,这样this指向的是vm对象或者是组件实例对象

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

13.条件渲染 

 1.v-if

        (1)v-if="表达式"

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

        (3)v-else="表达式"

        适用于频率切换低的场景  不展示DOM元素直接被移除

        (1)(2)(3)一起使用时,要求结构不要被打断

        2.v-show="表达式"

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

        不展示DOM元素未被移除,只是将DOM元素通过样式进行隐藏

        3.使用v-if,元素可能无法获取到 可以使用v-show一定获取到

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <h1>欢迎来到{{name}}</h1>
        <h2>当前值是{{count}}</h2>
        <button @click="count++">点我值+1</button>
        <!-- 使用v-show做条件渲染 -->
        <!-- <div v-show="count===1">1</div>
        <div v-show="count===2">2</div>
        <div v-show="count===3">3</div> -->
        <!-- 使用v-if做条件渲染 和v-if-else -->
        <!-- <div v-if="count===1">1</div>
        <div v-else-if="count===2">2</div>
        <div v-else-if="count===3">3</div>
        <div v-else>66</div> -->
            <!-- 搭配使用 template -->
        <template v-if="count===1">
            <h2>你好</h2>
            <h2>你好</h2>
            <h2>你好</h2>
        </template>
    </div>
    <script>
        const vm=new Vue({
            el:'#root',
            data:{
                name:'德莱联盟',
                count:0
            }
        })
    </script>
</body>
</html>

 14.基本遍历+key作用原理

    v-for

        1.用来遍历 可以遍历数组(最多) 对象 字符串 指定次数

        2.v-for="(p,index) in persons" :key="index"

     key的作用原理

    1.作用:key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据新数据生成新的虚拟DOM,随后将新的虚拟DOM和旧的虚拟DOM进行对比

    2.对比规则

    (1)新的虚拟DOM和旧的虚拟DOM找到相同的key 如果内容没有改变 就直接复用之前的DOM

    内容发生变化就,则生成新的DOM替换页面中的真实DOM

    (2)新的虚拟DOM和旧的虚拟DOM没有找到相同key,则直接生成新的真实DOM,渲染到页面中

    3.用index作为key会出现的问题

    (1)对数据进行逆向的添加,删除等操作 会产生没有必要的真实DOM更新===》页面没问题 但是效率低

    (2)如果结构中有输入类的DOM 会产生错误的DOM更新==》页面出现问题

    4.如何选择

    (1)最好使用每一条数据的唯一标识作为key

    (2)不存在逆序的添加,删除操作,仅仅用于页面展示 用index作为key没有问题

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <h2>人员列表</h2>
        <ul>
            <button @click.once="add">点我添加人员</button>
            <!-- 遍历数组 对象 -->
            <li v-for="(p,index) in persons" :key="p.id">
                {{p.name}}-{{p.age}}
                <input type="text">
            </li>
            <!-- 遍历对象 -->
            <li v-for="(c,key) in car" :key="key">
                {{key}}-{{c}}
            </li>
        </ul>
    </div>
    <script>
        const vm=new Vue({
            el:'#root',
            data:{
                persons:[
                    {id:'01',name:'张三',age:'18'},
                    {id:'02',name:'李四',age:'19'},
                    {id:'03',name:'王五',age:'20'}
                ],
                car:{
                    name:'奔驰',
                    price:'100万',
                    address:'上海'
                }
            },
            methods: {
                add(){
                    const p={id:'004',name:'老刘',age:'30'}
                    return this.persons.unshift(p)
                }
            }
        })
    </script>
</body>
</html>

 14.1案例---列表过滤

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <h2>人员列表</h2>
        <!-- 通过双向绑定获取数据 -->
        <input type="text" placeholder="请输入名字" v-model="keyWord">
        <ul>
            <li v-for="(p,index) in newPersons" :key="p.id">
                {{p.name}}-{{p.age}}-{{p.gender}}
            </li>
        </ul>
    </div>
    <script>
        const vm=new Vue({
            el:'#root',
            data:{
                persons:[
                    {id:'01',name:'马冬梅',age:'18',gender:'女'},
                    {id:'02',name:'周冬雨',age:'19',gender:'女'},
                    {id:'03',name:'周杰伦',age:'20',gender:'男'},
                    {id:'04',name:'温兆伦',age:'21',gender:'男'}
                ],
                // newPersons:[],
                keyWord:''
            },
            //监视已有属性
            // watch:{
            //     keyWord:{
            //         immediate:true,
            //         handler(val){
            //         this.newPersons=this.persons.filter((a)=>{
            //             return a.name.indexOf(val)!==-1
            //            })
            //         }
            //     }
            // }
            computed: {
                newPersons(){
                    return this.newPersons=this.persons.filter((p)=>{
                        return p.name.indexOf(this.keyWord)!==-1
                    })
                }
            }
        })
    </script>
</body>
</html>

14.2案例---列表排序

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <h2>人员列表</h2>
        <!-- 通过双向绑定获取数据 -->
        <input type="text" placeholder="请输入名字" v-model="keyWord">
        <button @click="softType=2">年龄升序</button>
        <button @click="softType=1">年龄降序</button>
        <button @click="softType=0">原顺序</button>
        <ul>
            <li v-for="(p,index) in newPersons" :key="p.id">
                {{p.name}}-{{p.age}}-{{p.gender}}
            </li>
        </ul>
    </div>
    <script>
        const vm=new Vue({
            el:'#root',
            data:{
                persons:[
                    {id:'01',name:'马冬梅',age:'25',gender:'女'},
                    {id:'02',name:'周冬雨',age:'19',gender:'女'},
                    {id:'03',name:'周杰伦',age:'30',gender:'男'},
                    {id:'04',name:'温兆伦',age:'21',gender:'男'}
                ],
                softType:0, //0原顺序 1降序  2升序
                keyWord:''
            },
            computed: {
                newPersons(){
                    //通过计算得到
                    const arr=this.persons.filter((p)=>{
                        return p.name.indexOf(this.keyWord)!==-1
                    })
                    //判断是否要进行排序
                    if(this.softType){
                        arr.sort((a1,a2)=>{
                            //前-后 升序 后-前 降序
                            return this.softType===1 ? a2.age-a1.age : a1.age-a2.age
                        })
                    }
                    return arr
                }
            }
        })
    </script>
</body>
</html>

15.vue监视数据原理

Vue监视数据原理

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

        2.监测对象中的数据

        通过setter实现监视,且在new Vue就传入要监视的数据【就是你的data中放什么数据】

        (1)给对象后进行数据添加,不做响应式处理

        (2)给后添加的数据进行响应式【data中本来的没有的数据,根据需求 进行数据添加】

        Vue.set(target,propertyName/index,value) eg:Vue.set(this.stu,'sex','男')                  

        vm.$set(target,propertyName/index,value) eg: this.$set(this.stu,'sex','男')

        3.监测数组中的数据

        通过包裹数组更新元素的方法实现

        (1)调用原生的数组对应的更新方式(eg:push,unshift...)

        (2)进行模板解析,重新更新页面

        4.在Vue修改页面中的某个元素要用以下的方法

        (1)使用这些API push(),pop(),shift(),unshift(),sort(),reverse(),splice()

        使用filter时 会得到新的数组 将新的数组替换原来的数组

        (2)使用Vue.set()或者vm.$set

        注意:Vue.set()和vm.$set不能给vm或者vm的根属性(data)进行添加属性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <h1>{{msg}}</h1>
        <button @click="stu.age++">点我年龄+1</button><br>
        <button @click="addSex">点我添加性别,默认男</button><br>
        <button @click="stu.sex='未知'">点我修改性别</button><br>
        <button @click="addFriend">点我添加朋友</button><br>
        <button @click="updateFriendFirst">修改列表第一个朋友</button><br>
        <button @click="addHobby">添加一个爱好</button><br>
        <button @click="updateHobbtFirst">修改第一个爱好为开车</button>
        <h2>name:{{stu.name}}</h2>
        <h2>age:{{stu.age}}</h2>
        <h2 v-if="stu.sex">sex:{{stu.sex}}</h2>
        <h2>hobby</h2>
        <ul>
            <li v-for="(h,index) in stu.hobby" :key="index">
                {{h}}
            </li>
        </ul>
        <h2>朋友</h2>
        <ul>
            <li v-for="(f,index) in stu.friend" :key="index">
                {{f.name}}-{{f.age}}
            </li>
        </ul>
    </div>
    <script>
        const vm=new Vue({
            el:'#root',
            data:{
                msg:'学生信息',
                stu:{
                    name:'张三',
                    age:'18',
                    hobby:['唱','跳','rap'],
                    friend:[
                    {name:'李四',age:'20'},
                    {name:'王五',age:'23'}
                ]
                },
                
            },
            methods: {
                addSex(){
                    //Vue.set(this.stu,'sex','男')
                    this.$set(this.stu,'sex','男')
                },
                addFriend(){
                   this.stu.friend.unshift({name:'jack',age:'20'})
                },
                updateFriendFirst(){
                    this.stu.friend[0].name='老樊'
                },
                addHobby(){
                    this.stu.hobby.push('学习')
                },
                updateHobbtFirst(){
                    // this.$set(this.stu.hobby,0,'开车')
                    //通过splice引起vm中数组的变化
                    this.stu.hobby.splice(0,1,'写代码')
                }
            }
        })
    </script>
</body>
</html>

 15.1Vue.set或者this.$set引起数据改变

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <h2>人员列表</h2>
        <button @click="updateMei">点我更新马冬梅数据</button>
        <ul>
            <li v-for="(p,index) in persons" :key="p.id">
                {{p.name}}-{{p.age}}-{{p.gender}}
            </li>
        </ul>
    </div>
    <script>
        const vm=new Vue({
            el:'#root',
            data:{
                persons:[
                    {id:'01',name:'马冬梅',age:'25',gender:'女'},
                    {id:'02',name:'周冬雨',age:'19',gender:'女'},
                    {id:'03',name:'周杰伦',age:'30',gender:'男'},
                    {id:'04',name:'温兆伦',age:'21',gender:'男'}
                ]
            },
            methods: {
                updateMei(){
                    //奏效
                    // this.persons[0].name='马老师'
                    // this.persons[0].age='50'
                    // this.persons[0].gender='男'
                    //不可行
                    //this.persons[0]={id:'01',name:'马老师',age:'50',gender:'女'}
                    this.$set(this.persons,0,{id:'01',name:'马老师',age:'50',gender:'女'})
                }
            }
        })
    </script>
</body>
</html>

16.收集表单数据

        收集表单数据

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

        <input type="radio"/>v-model收集的是value值 但是要在标签中给value值

        <input type="checkbox"/>

        没有在标签中配置value属性,收集的就是checkbox(布尔值)

        配置input中value值(1)v-model初始值是非数组,收集的就是checkbox(布尔值)

        (2)v-model初始值是数组,收集的就是value组成的数组

        v-model修饰符

        lazy 失去焦点时在收集数据

        trim 去首尾空格

        number 输入字符串转换成有效的数字

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
    <form @submit.prevent="demo">
        账号:<input type="text" v-model="account"><br>
        密码:<input type="password" v-model="password"><br>
        姓别:
        男:<input type="radio" name="sex" v-model="sex" value="male">
        女:<input type="radio" name="sex" v-model="sex" value="female"><br>
        爱好:
        学习:<input type="checkbox" v-model="hobby" value="study">
        写代码:<input type="checkbox" v-model="hobby" value="write">
        打游戏:<input type="checkbox" v-model="hobby" value="game"><br>
        所属位置:
        <select v-model="city">
            <option value="mr">请选择地区</option>
            <option value="bj">北京</option>
            <option value="sh">上海</option>
            <option value="gz">广州</option>
        </select><br>
        其他信息:
        <textarea v-model="other"></textarea><br>
        <input type="checkbox" v-model="agree">阅读并接受<a href="http://www.baidu.com">用户协议</a><br>
        <button>提交</button>
    </form>
    </div>
    <script>
        const vm=new Vue({
            el:'#root',
            data:{
                account:'',
                password:'',
                sex:'male',
                hobby:[],
                city:'mr',
                other:'',
                agree:''
            },
            methods: {
                demo(){
                    console.log(JSON.stringify(this._data))
                }
            }
        })
    </script>
</body>
</html>

17.v-html指令

    1.向指定节点渲染包含html结构的内容

    2.和插值语法的区别

    (1)v-html会替换掉节点中所有的内容,{{xxxx}}不会

    (2)v-html识别html结构

    3.安全性问题

    在网站上任意渲染html是非常危险,容易遭受攻击

    一定要在可信任的内容上使用v-html,用不要在用户提交的内容上

    v-cloak指令

    1.本质就是一个属性,当Vue创建实例并接管容器后,会删掉v-cloak属性

    2.使用css和v-cloak可以解决网速慢时页面展示{{xxx}}问题

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <h2>{{name}}</h2>
        <div v-text="str"></div>
        <div v-html="str"></div>
    </div>
    <script>
        const vm=new Vue({
            el:'#root',
            data:{
                name:'jack',
                str:'<h2>是我</h2>'
            }
        })
    </script>
</body>
</html>

17.1v-once指令和  v-pre指令

v-once指令

    v-once所在的节点初次进行动态渲染后,就被当作静态内容

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

    v-pre指令

    跳过所在节点的编译(就是不解析)

    可以用在没有实现动态渲染的地方,用于加快解析

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <h2 v-pre>Vue很好学</h2>
        <h2 v-once>n的初始值为:{{n}}</h2>
        <h2>n的值为:{{n}}</h2>
        <button @click="n++">点我n+1</button>
    </div>
    <script>
        const vm=new Vue({
            data:{
                n:1
            }
        })
        vm.$mount('#root')
    </script>
</body>
</html>

 17.2自定义指令

    <!-- 指令总结

    1.定义语法

    (1)局部指令 new Vue({

        directives:{指令名:配置对象或者回调函数}

    })

    (2)全局指令 Vue.directives(指令名,配置对象或者回调函数)

    2.常用三个回调

    bind 指令和元素进行绑定时

    inserted 指令所在的元素被放到页面中

    update 指令所在的模板被重新解析

    3.指令定义时,不要加v- 使用时要加v-

    指令名是多个单词时 中间加- eg: user-name 不要用小驼峰 eg userName  

    -->

     需求1当点击n时,其数值扩大十倍

     需求2 自定义指令 进入页面就获取input框的焦点 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <h2>n的值为{{n}}</h2>
        <!-- <h2>扩大后的值为<span v-big-number="n"></span></h2> -->
        <h2>扩大后的值为<span v-big="n"></span></h2>
        <button @click="n++">点我n+1</button>
        <input type="text" v-fbind="n">
    </div>
    <script>
        const vm=new Vue({
            el:'#root',
            data:{
                n:1
            },
            directives:{
                //elements获取绑定的文本框 binding获取绑定数据的值
                //big何时被调用 1.指令和元素成功绑定时 2.指令所在的模板被重新解析时
                //函数式
                big(element,binding){
                    console.log('big',this)//这里this是window
                    element.innerText=binding.value*10
                },
                // 'big-number'(element,binding){
                //     console.log('big')
                //     element.innerText=binding.value*10
                // },
                //对象式
                fbind:{
                    //指令和元素进行绑定时
                    bind(element,binding){
                        element.value=binding.value
                    },
                    //指令所在的元素被放到页面中
                    inserted(element,binding){
                        element.focus()
                    },
                    //指令所在的模板被重新解析
                    update(element,binding){
                        element.value=binding.value
                    }
                }
            }
        })
    </script>
</body>
</html>

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值