慕课网Vue-去哪了3

三、Vue基础讲解

1.创建实例

<body>
    <div id="root">
        <div @click="handleClick">
            {{message}}
        </div>
        <item></item>
    </div>
    <script>
        Vue.component('item',{
            template:'<div>hellow world!</div>'
        })//组件也是一个个实例
        var vm = new Vue({//创建实例,入口,根实例
            el:'#root', //接管#root标签里面所有的dom显示
            data:{ //存放数据,插值表达式显示
                message:'hellow world'
            },
            methods:{
                handleClick(){ //绑定事件
                        alert('hello')
                }
            }
        })
        //一个vue项目是由很多小组件组成的(是由很多vue实例组成的)
    </script>
</body>

2.Vue实例的生命周期钩子

<body>
    <div id="app">hellow world
    </div>
    <script>
        //生命周期函数就是vue实例在某一个时间点会自动执行的函数
        var vm = new Vue({ //1
            el:'#app',
            template:"<div>{{text}}</div>",
            //4如果没有模板属性,自动将el对应的html元素当做模板渲染,如果有template就用模板渲染         
            data:{
                text:"goodbye"
            },
            beforeCreate:function(){//2创建vue实例,部分初始化后自动执行的函数
                console.log('beforeCreate')
            },
            created:function(){ //3初始化完成后执行
                console.log('created')
            },
            beforeMount:function(){ //5在模板渲染到页面上之前,执行函数
                console.log(this.$el),
                console.log('beforeMount')
            },
            mounted:function(){ //5模板挂在到页面之上(显示数据后),执行生命周期函数
                console.log(this.$el),
                console.log('mounted')
            },
            beforeDestroy:function(){ //6当实例要被销毁时( vm.$destroy() )。销毁之前执行
                console.log('beforeDestroy')
            },
            destroyed(){//7销毁之后执行,
                console.log('destroyed')
            },
            beforeUpdate:function(){//7当数据发生改变,还没有重新渲染之前
                console.log('beforeUpdate')
            },
            updated:function(){//8当重新渲染之后
                console.log('updated')
            }
            
        })
    </script>
</body>

输出:

goodbye

console:

3.Vue的模板语法

① 插值表达式{{ }}

<div id="app">
        {{name}}
</div>
<script>
        var vm = new Vue({ //1
            el:'#app',
            data:{
                name:"Dell"
            }
        })
</script>

② v-text指令

== innertext内容

<div id="app">
    <div v-text="name"></div>
</div>

③v-html指令

== innerhtml

<div v-html="name"></div>

v-text == {{ }}

v-html可以识别html标签(h1),其他两种会直接转义为字符串

④ v-on: 绑定事件 ,简写 @

    v-bind: 绑定数据 =>

<div v-html="name" v-bind:title="name"></div>
指令后跟的都是 js表达式
<div id="app">
        <div>{{name + 'Lee'}}</div>
        <div v-text="name"></div>
        <div v-html="name + 'Lee'" v-bind:title="name"></div>
</div>

4.计算属性,方法和侦听器

①计算属性

例:显示全名

<div id="app">
        {{firstName + " " + lastName}}
</div>
    <script>
        var vm = new Vue({ 
            el:'#app',
            data:{
                firstName:"Dell",
                lastName:"Lee"
            }
        })
</script>

计算属性有一个缓存机制 :该计算属性依赖的变量未发生改变时,(当其他数据改变后)计算属性就不会重新计算。一直用上一次计算的结果,提高性能

<div id="app">
        {{fullName}}
    </div>
    <script>
        var vm = new Vue({ 
            el:'#app',
            data:{
                firstName:"Dell",
                lastName: "Lee",
                //fullName: "Dell Lee" //产生冗余,因为已经定义过姓和名
            },
            //为了不产生冗余,又把fullName显示出来 ==》计算属性
            computed:{
                fullName:function(){
                    return this.firstName+ " " +this.lastName;
                }
            }
        })
    </script>

②还可以用一个方法的形式实现同样的功能

<body>
    <div id="app">
        {{fullName()}}
        {{age}}
    </div>
    <script>
        var vm = new Vue({ 
            el:'#app',
            data:{
                firstName:"Dell",
                lastName: "Lee",
                age:28
            },
            methods:{
                fullName(){
                    console.log("计算了一次");
                    return this.firstName+ " " +this.lastName;
                }
            }
        })
    </script>
</body>

console:

 

 由此可见,方法并不如计算属性有效

③侦听器watch

<body>
    <div id="app">
        {{fullName}}
        {{age}}
    </div>
    <script>
        var vm = new Vue({ 
            el:'#app',
            data:{
                firstName:"Dell",
                lastName: "Lee",
                fullName: "Dell Lee", //产生冗余,因为已经定义过姓和名
                age:28
            },
            //为了不产生冗余,又把fullName显示出来 ==》计算属性
            // computed:{
            //     fullName:function(){
            //         return this.firstName+ " " +this.lastName;
            //     }
            // }
            //方法
            // methods:{
            //     fullName(){
            //         console.log("计算了一次");
            //         return this.firstName+ " " +this.lastName;
            //     }
            // }
            //侦听器
            watch:{//当 firstname改变时执行
                firstName:function(){
                    this.fullName = this.firstName+ " "+this.lastName;
                },
                lastName:function(){
                    this.fullName = this.firstName+ " "+this.lastName;
                }
            }
        })
    </script>
</body>
View Code

watch 和 computed 都具有缓存机制,且相对而言,wach的代码程度比computed要复杂。

所以当一个功能同时可以用computed、methods和watch实现时,优先推荐 computed

5. 计算属性的getter和setter

<body>
    <div id="app">
        {{fullName}}
        {{age}}
    </div>
    <script>
        var vm = new Vue({ 
            el:'#app',
            data:{
                firstName:"Dell",
                lastName: "Lee",
                age:28
            },
           computed:{
                // fullName:function(){
                //     return this.firstName+ " " +this.lastName;
                // }//等于get

                //写成对象
                fullName:{
                    get:function(){
                        return this.firstName+ " " +this.lastName;
                    },//取值
                    set:function(value){//(fullName发生改变)接收外部传入的value
                        console.log(value);
                        var arr = value.split(" ");//以空格分割字符串
                        this.firstName = arr[0];
                        this.lastName = arr[1]
                    }//设置值
                }

            }
        })
    </script>
</body>
View Code

上一节使用的computed方法就是get。

当set设置fullName时,firstName发生变化,且firstName是fullName依赖的值,就会引起fullName的重新计算。

总结:

get:当fullName依赖的数据发生变化时,重新计算显示

set:当fullName设置后,set业务代码执行,间接使fullName依赖的数据改变,从而重新计算fullName显示。

6. Vue中的样式绑定

vue是面向数据开发,并不直接操作dom,如何将数据和样式关联,数据改变样式就改变:

① class对象绑定

:class="{activated: isActivated} "
<body>
    <div id="app">
        <div @click="handleDivClick"
             :class="{activated: isActivated} "
        >
            hello world</div>
    </div>
    <script>
        var vm = new Vue({ 
            el:'#app',
            data:{
                isActivated: false
            },
            methods:{
                handleDivClick(){
                    this.isActivated = !this.isActivated
                }
            }

        })
    </script>
    <style>
        .activated{
            color: red;
        }
    </style>
</body>
View Code

②class数组绑定

 :class=" [activated] "
/* :class=" ['activated'] " 当作字符串
    <div id="app">
        <div @click="handleDivClick"
             :class="[activated] "
        >
            hello world</div>
    </div>
    <script>
        var vm = new Vue({ 
            el:'#app',
            data:{
                activated:''
            },
            methods:{
                handleDivClick(){
                    this.activated= this.activated==="activated"?" ":"activated"
                }
            }

        })
    </script>
View Code

③ style 对象绑定

:style="styleObj"

  <div id="app">
        <div @click="handleDivClick"
             :style="styleObj" 
        >
            hello world</div>
    </div>
    <script>
        var vm = new Vue({ 
            el:'#app',
            data:{
                styleObj:{
                    color:"black"
                }
            },
            methods:{
                handleDivClick(){
                    this.styleObj.color= this.styleObj.color==="black"? "red ":"black"
                }
            }

        })
    </script>

④style数组绑定

:style="[styleObj,{fontSize:'20px'}]"
<body>
    <div id="app">
        <div @click="handleDivClick"
             :style="[styleObj,{fontSize:'20px'}]" 
        >
            hello world</div>
    </div>
    <script>
        var vm = new Vue({ 
            el:'#app',
            data:{
                styleObj:{
                    color:"black"
                }
            },
            methods:{
                handleDivClick(){
                    this.styleObj.color= this.styleObj.color==="black"? "red ":"black"
                }
            }

        })
    </script>
    <style>
        .activated{
            color: red;
        }
    </style>
</body>
View Code

 7.Vue 条件渲染

v-if指令:返回值true、false决定了当前div是否挂载到页面

比较:v-if和v-show都可以控制一个模板标签是否在页面上显示

当返回值为false时,v-if 是直接不显示在dom元素上,而v-show是给当前div添加dislay:none;属性

在使用上,如果一个页面上dom元素有频繁的显示隐藏操作,建议用v-show,因为它不会(像v-if)频繁的把一个dom删除添加

<body>
    <div id="app">
        <div v-if ="show" >{{message}}</div>
        <div v-show ="false" >{{message}}</div>
    </div>
    <script>
        var vm = new Vue({ 
            el:'#app',
            data:{
                show:true,
                message:"hello world",
                false:false
                
            },
            methods:{
                
            }

        })
    </script>
</body>

结合v-else使用,当v-if为false时执行else

<div id="app">
        <div v-if ="show" >{{message}}</div>
        <div v-else>Bye World</div>
</div>

if和else要紧贴使用,两者之间不能有其他元素标签,否则报错

代码加工:

<body>
    <div id="app">
        <div v-if ="show === 'a'" >This is A</div>
        <div v-else-if ="show === 'b'" >This is B</div>
        <div v-else>Bye World</div>
        
    </div>
    <script>
        var vm = new Vue({ 
            el:'#app',
            data:{
                show:'a',                
            }
        })
    </script>
</body>

②关键字 key

当给某个元素标签加上key值后,Vue会知道它是页面上唯一的元素。

如果两个相同的元素key值不一样,vue就不会去尝试复用以前的input标签

源码:

<body>
    <div id="app">
        <div v-if ="show" >用户名:<input  kye="username"/></div>
        <div v-else>邮箱:<input key="useremail"/></div>
    </div>
    <script>
        var vm = new Vue({ 
            el:'#app',
            data:{
                show:false,
            }
        })
    </script>
</body>

 

示例:

 

有key:

 

 

 没有key:

8. Vue中的列表渲染

v-for列表遍历

<body>
    <div id="app">
        <div v-for="item of list">
            {{item}}
        </div>
    </div>
    <scripat>
        var vm = new Vue({ 
            el:'#app',
            data:{
                list:[
                    "hello",
                    "dell",
                    "nice",
                    "to",
                    "meet",
                    "you"
                ] 
            }
        })
    </script>
</body>

问题一:

数组的默认参数index:数组中每一项的索引下标

<body>
    <div id="app">
        <div v-for="(item,index) of list">
            {{item}}---{{index}}
        </div>
    </div>
    <scripat>
        var vm = new Vue({ 
            el:'#app',
            data:{
                list:[
                    "hello",
                    "dell",
                    "nice",
                    "to",
                    "meet",
                    "you"
                ] 
            }
        })
    </script>
</body>
View Code

问题二:

为了提升循环显示的性能,会给每一个循环项上加上一个唯一的key。

key值并不推荐用index,在频繁操dom元素相对应的数据时,比较费性能,让vue不能充分复用dom节点。

一般后端返回数据时,会有和数据条目对应的唯一的数据符(id)

<body>
    <div id="app">
        <div v-for="(item,index) of list" 
             :key="item.id">
            {{item.text}}---{{index}}
        </div>
    </div>
    <script>
        var vm = new Vue({ 
            el:'#app',
            data:{
                list:[
                    {
                        id:"0000000111",
                        text:"hello"
                    },{
                        id:"0000000112",
                        text:"world"
                    }
                ]
               // list:[
               //  "hello",
               //    "dell",
               // ] 
            }
        })
    </script>
</body>

输出:

hello---0

world---1

问题三: 数组添加删除(七个变异方法)

vm.list.push({id:"001",text :"1"}) √

vm.list[3]  =  {id:"001",text :"1"}  ×

push ---  最后一项后添加

pop  ---  最后一项后删除

shift --   数组第一项删除

unshift -- 数组第一项前加

splice  ---  数组截取

sort  ---   数组排序

reverse  --- 取反

例子:替换

vm.list.splice(从下标开始,处理长度,内容)

vm.list.splice(1,1,{id:"001",text :"1"} ) √

输出:

hello---0
1---1
改变引用
vm.list=[{ { id:"0000000111", text:"hello" },{ id:"001", text:"1" }]   √
通过改变数据的引用地址从而实现数据变化页面变化
问题四:模板占位符
-> 可以帮助我们去包裹一些元素,但是在循环的过程中并不会真正渲染到页面上
<body>
    <div id="app">
        <template v-for="(item,index) of list" 
                 :key="item.id">
            <div >
                {{item.text}}---{{index}}
            </div>
            <span> {{item.text}}</span>
        </template>
    </div>
    <script>
        var vm = new Vue({ 
            el:'#app',
            data:{
                list:[
                    {
                        id:"0000000111",
                        text:"hello"
                    },{
                        id:"0000000112",
                        text:"world"
                    }
                ]
               // list:[
               //  "hello",
               //    "dell",
               // ] 
            }
        })
    </script>
</body>
View Code

输出:

 

 

但是有一个小问题:Vue不支持在 template 元素上绑定属性。

比如这里想绑定 key 属性就不行。会报错。

解决方法:可以改成div (会被渲染)或者 不使用template元素做for循环(新建一个div做两个for循环,会冗余)

问题五:对象循环

循环展示对象内容

<body>
    <div id="app">
        <div v-for="(item,key,index) of userInfo" >
            {{item}}---{{key}}----{{index}}
        </div>
    </div>
    <script>
        var vm = new Vue({ 
            el:'#app',
            data:{
                userInfo:{
                    name:"Dell",
                    age:25,
                    gender:"male",
                    salary:"secret"
               }
          
            }
        })
    </script>
</body>

对象额外能接收参数key,表键名

输出:

Dell---name----0
25---age----1
male---gender----2
secret---salary----3

问题五:对象修改

vm.userInfo.name = ”Dell Lee“   √

对象添加:

vm.userInfo.address= "BeiJing"   × (数据虽然变了,但是页面上依然是4条)

实现: 类似数组那样直接改引用

vm.userInfo={  

                    name:"Dell",
                    age:25,
                    gender:"male",
                    salary:"secret",
                    address:"BeiJing"

}    √  数据发生变化,页面同时变化

9. Vue中的set方法

除了上节讲到直接改引用的方式添加对象数据之外,Vue还提供了一种set方法

通过Vue.set方法向一个对象中增加值,vm.userInfo 中就会多出来address这个值,而且数据变了后页面会跟着联动

 

 

① set既是Vue上的一个全局方法,可以用以修改对象。

又是vue的实例方法

通过vue实例的$set方法,也可以实现一样的效果

 

 ② 数组上的set方法使用

给数组添加数据:

回顾上文的两个方法

  •    =》数组的7个变异方法(push、pop等等)
  •    =》改变数组的引用

第三种 set方法:

前面有说,如果想修改数组中某一项的内容,通过直接修改数组的方式(vm.userInfo[1]= ..),

数据虽然改变了,但是页面并不会跟着变化。

Vue.set就是解决这个问题

<body>
    <div id="app">
        <div v-for="(item,index) of userInfo" >
           {{item.text}} -{{index}}
        </div>
    </div>
    <script>
        var vm = new Vue({ 
            el:'#app',
            data:{
                userInfo:[
                {
                    id:"0000000111",
                        text:"hello"
                    },{
                        id:"0000000112",
                       text:"world"
                }
                ]
            }
        })
    </script>
</body>

console:

 

 同样:使用vue实例的$set方法也是可以的  == 例:vm.$set(vm.userInfo,1,{id:"0000000112",text:"Dell world"}) 


总结:

数组改变,页面改变:

改变数组的引用。调数组的变异方法。使用vue中set方法。

对象改变,页面改变:

改变对象的引用。使用vue中set方法

posted @ 2022-03-04 23:57  以深  阅读(31)  评论(0编辑  收藏  举报
TOP