Vue学习

1.初识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 src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
 </head>
 <body>
     <!-- 双括号里写js表达式,注意区分表达式和代码
     1.一个表达式可以生成一个值,放在任何一个需要值的地方
     拿一个变量的可以接到表达式的值,例子 a,a+b,.demo(1)
     2.代码,例子 if(){},for(){}
     3.真实开发中只有1个vue实例,并且会配合着组件一起使用
     -->
     <div id="root">
         <h1>Hello,{{name}}</h1>
     </div>
     <script>
         //创建vue实例,一个Vue实例只能对应一个容器!!
         var x=new Vue({
             el:'#root',//el用于指定当前Vue实例为哪个容器服务,值通常为css选择器
             data:{//data中用于存储数据,数据供el所指定的容器使用
                 name:'cc'
            }
        })
     </script>
 </body>
 </html>
 
 <div id="root">
    <h1>插值语法</h1>
    <h3>你好,{{name}}</h3>
    <hr>
    <h1>指令语法</h1>
    <!-- Vue指令,bind,绑定,v-bind:可以简写为:
    功能:用于解析标签,
    举例:v-bind:href="xxx",xxx同样写js表达式 -->
    <a href="#">点我去{{school.name}}学习</a>
    <a :href="url">点我进入百度</a>
 </div>
 <script>
    var x=new Vue({
        el:"#root",
        data:{
        name:"cc",
        url:'http://www.baidu.com',
        school:{
            name:233
        }
        }
    })
 </script>

数据绑定

 
 <div id="root">
    单向数据绑定:<input type="text" v-bind:value="name">
    双向数据绑定:<input type="text" v-model="name">
    <!-- v-model只能应用在表单类元素,(能输入,有value值),注意简写写法 -->
 </div>
 <script>
    var x=new Vue({
        el:"#root",
        data:{
        name:"cc",
        }
    })
 </script>
## el和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 src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
 </head>
 <body>
   
    <div id="root">
        <h1>你好,{{name}}</h1>
    </div>
    <!-- data与el的两种写法
    1.el的两种写法(1),.new Vue时配置el属性
                  (2),先创建Vue实例,后通过vm.$mount('#root')指定el的值
    2.data有两种写法
                (1)对象式
                (2)函数式
    3.Vue所管理的函数,一定不要写箭头函数,一旦写了箭头函数,this就不再是实例了,变成Window-->
    <script>
        var x=new Vue({
            //el:"#root",//第一种写法
 
        //data的第一种写法,对象式
        //   data:{
        //     name:"cc",
        //   }
        //data的第二种写法:函数式(Vue调用的,此处this是Vue实例对象)
        data:function(){
            return{
                name:"cc"
            }
        }
 
        })
        x.$mount('#root')//第二种写法
    </script>
 </body>
 </html>

 

理解MVVM

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

  • V:视图:模板

  • VM:视图模型:Vue实例对象

 

Object.defineProperty方法

 //Property属性
        //Object.defineProperty
        let number=18
        let person={
            name:'张三',
            sex:'男',
        }
        Object.defineProperty(person,'age',{
            //value:18,
            enumerable:true,//控制属性是否可以枚举
            writable:true,//控制属性是否可以修改
            configurable:true,//控制属性是否可以被删除
            //想让person增加age属性,属性值为number,可随着number更改而变化
            //当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
            get:function(){
                return number
            },
            //当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
            set(value){
                number=value
            },
        })
        //Object.keys(person)可以将传入的对象属性名遍历出来,形成一个数组
        // Object.defineProperty通过这个方法加入的属性不可枚举(不可遍历),不可更改,可加入 enumerable:true使其可以遍历
         

 

数据代理

 <!-- 
         1.Vue中的数据代理:
             通过vm对象来代理data对象中属性的操作(读/写)
         2. Vue中数据代理的好处:
             更加方便的操作data中的数据
         3.基本原理:
             通过Object.defineProperty()把data对象中所有属性添加到cn上,
             为每一个添加到cn上的属性都指定一个getter/setter
             在getter/setter内部去操作(读/写)data中对应的属性
      -->
     <script>
     
         
         const cn=new Vue({
             el:'#root',
             data:{
                 name:'ss',
                 address:'广东',
            }
        })
         //cn._data就是cn中的data
     </script>

 

事件处理

 <div id="root">
         <h1>你好,{{name}}</h1>
         <button @click="showInfo">点我提示</button>
         <!-- v-on:可简写成@ -->
         <button @click="showInfo2(66,$event)">点我提示2(传参 )</button>
     </div>
     <!-- 事件的基本使用:
             1.使用v-on:xxx或@xxx 绑定事件,其中xxx是事件名:
             2.事件的回调需要配置在methods对象中,最终会在vm上
             3.methods中配置的函数,不要用箭头函数,否则this就不是vm了
             4.methods中配置的函数,都是被Vue所管理的函数,this的指向是vm或组件实例对象:
             5.@click="demo"和@click="demo($event)"效果一致,但后者可以传参 -->
     <script>
      const vm=new Vue({
         el:"#root",
         data:{
             name:'cc',
        },
         methods:{
             showInfo(event){
                 //console.log(this)//此处的this是vm
                 alert('hello')
            },
             showInfo2(number,a){
                 //console.log(this)//此处的this是vm
                 alert(number)
                 console.log(a)
                 alert('hello')
            }
        }
      })
     </script>

 

事件修饰符

  <div id="root">
         <h1>你好,{{name}}</h1>
        <a href="http://www.baidu.com"@click.prevent="showInfo">点我提示信息</a>
     </div>
     <!--
         Vue中的事件修饰符:
         1.prevent:阻止默认事件 *
         2.stop:阻止事件冒泡 *
         3.once:事件只触发一次 *
         4.capture:使用事件的捕获模式(先捕获再冒泡)
         5. self:只有event.target是当前元素才触发事件
         6.passive:事件的默认为立即执行,无需等待回调执行完毕
      -->
 可连着写,例如@click.prevent.stop组织冒泡并不允许跳转

 

键盘事件

 <div id="root">
         <h1>你好,{{name}}</h1>
        <input type="text" placeholder="按下回车提交" @keyup.enter="showInfo">
     </div>
 若想只按下ctrl+y触发,可以写成@keyup.ctrl.y
     <!--
         1.Vue中常用到的按键别名
             1.回车=>enter
             2.删除=>delete(捕获'删除'和'退格'键)
             3.退出=>esc
             4.空格=>space
             5.换行=>tab (配合keydown适用)
             6.上=>up    
             7.下=>down
             8.左=>left
             9.右=>right
         2.Vue未提供别名的按键,可以使用按键原始的key值去绑定,但需要注意转为kebab-case(短线命名),两个单词组成的,如capslock要写成caps-lock
         3.系统修饰键(用法特殊):ctrl,alt,shift,meta
             (1).配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发
             (2).配合keydown使用:正常触发事件
         4.也可以通过keyCode(不推荐,以移除)
     -->

 

计算属性

 <div id="root">
         <h1>你好,{{name}}</h1>
        姓<input type="text" v-model="firstname">
        名<input type="text" v-model="lastname">
        全名:<span>{{fullname}}</span>
     </div>
     <!--
         计算属性:
             1.定义:要用的属性不存在,要通过已有的属性计算得来
             2.原理:底层借助了Object.defineproperty方法提供gatter和setter
             3.get函数什么时候执行?
                 (1).初次调用时
                 (2).当依赖数据更改时
             4.优势:与methods相比,内部缓存机制(复用),效率更高,调式方便
             5.备注:
                 1.计算属性最终会出现在vm上,直接读取使用即可
                 2.如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变
      -->
     <script>
      const vm=new Vue({
         el:"#root",
         data:{
             firstname:'cc',
             lastname:'yy',
             
        },
       computed:{
         fullname:{
             //此处的this是vm
             //get什么时候调用?1,初次读取时调用。2,所依赖的数据改变时发生调用(比如此处firstname和lastname改变时调用)
             get(){
                return this.firstname+'-'+this.lastname
            }
        }
      }
      })
      //computed计算
     </script>

计算属性简写

 确定只读不改,才能用简写
 computed:{
        fullname:function(){
            return this.firstname+'-'+this.lastname//function当get用
        }
      }

 

监视属性

 <body>
     <!--
         监视属性watch:
             1.当监视的属性变化时,回调函数自动调用,进行相关操作
             2.监视的属性必须存在,才能进行监视
             3.监视的两种写法
                 (1).new Vue时传入watch配置
                 (2).通过vm.$watch监视
      -->
     <div id="root">
        <h2>今天天气很{{info}}</h2>
        <button @click="change">切换天气</button>
     </div>
     <script>
         var vm=new Vue({
             el:"#root",
             data:{
                 isHot:true,
            },
             computed:{
                 info(){
                     return this.isHot==true?'热':'冷'
                }
            },
             methods:{
                 change(){
                     this.isHot=!this.isHot
                }
            },
             // watch:{
             //     isHot:{
             //         immediate:true,//初始化时调用一下
             //         // 当isHot发生改变时,handler被调用
             //         handler(newValue,oldValue){
             //             console.log('isHot修改了',newValue,oldValue)
             //         }
             //     }
             // }
        })
         vm.$watch('isHot',{
             immediate:true,//初始化时调用一下
                      //当isHot发生改变时,handler被调用
                     handler(newValue,oldValue){
                         console.log('isHot修改了',newValue,oldValue)
                      }
        })
     </script>
 </body>

 

(扩展)深度监视

 <body>
     <!--
         深度监视:
             (1).Vue中的watch默认不监视对象内部值的改变(一层)
             (2).配置deep:true可以监测对象内部的值改变(多层)
         备注:
             (1).Vue自身可以监视对象内部值的改变,但Vue提供的watch默认不可以
             (2).使用watch时根据数据的具体结构,决定是否采用深度监视
      -->
     <div id="root">
        <h2>今天天气很{{info}}</h2>
        <button @click="change">切换天气</button>
          <h3>a的值是:{{numbers.a}}</h3>
          <h3>b{{numbers.b}}</h3>
     <button @click="numbers.a++">点我a++</button>
     <button @click="numbers={a:666,b:888}">彻底替换number</button>
     </div>
     <script>
         const vm=new Vue({
             el:"#root",
             data:{
                 isHot:true,
                 numbers:{
                     a:1,
                     b:1
                },
            },
             computed:{
                 info(){
                     return this.isHot==true?'热':'冷'
                }
            },
             methods:{
                 change(){
                     this.isHot=!this.isHot
                }
            },
             watch:{
                 isHot:{
                     // 当isHot发生改变时,handler被调用
                     handler(newValue,oldValue){
                         console.log('isHot修改了',newValue,oldValue)
                    }
                },
                 //想只监测a,监视多级结构中某个值的变化
                 'numbers.a':{
                     handler(){
                         console.log("a改变")
                    }
                },
                 //监测整个numbers,这样写只有当整个numbers改变才会监视到
                 numbers:{
                     handler(){
                         console.log('111')
                    }
                },
                 //若想监测numbers里面的属性
                 numbers:{
                     deep:true,
                     handler(){
                         console.log('numbers改变')
                    }
                }
            }
        })
 
     </script>
 </body>

 

监视简写形式

 watch:{
                //简写前提,不需要immediate和deep,只有handle
                isHot(newValue,oldValue){
                    console.log('isHot修改了',newValue,oldValue)
                },
            }
             
  vm.$watch('isHot',function(newValue,oldValue){
            console.log('isHot修改了',newValue,oldValue)
        })

computed和watch之间的区别

  • computed能完成的事情,watch都可以完成

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

两个原则

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

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

 

绑定class样式

 <body>
     <div id="root">
         <!-- 绑定class样式,字符串写法,适用于:样式的类名不确定,需要动态绑定 -->
        <div class="base" :class="a" @click="change">{{name}}</div>
         <!--绑定class样式,数组写法,适用于:样式的类名不确定,需要动态绑定 -->
          <div class="base" :class="arr">{{name}}</div>
          <!-- 绑定class样式,对象写法,适用于要绑定的样式个数确定,名字也确定-->
          <div class="base" :class="classObj">{{name}}</div>
     </div>
     <script>
         const vm=new Vue({
             el:"#root",
             data:{
                name:'cc',
                a:'normal',
                arr:['happy','sad','normal'],
             //happy,sad都不用
                classObj:{
                 happy:false,
                 sad:false
                }
            },
             methods:{
                 change(){
                     const arr=['happy','sad','normal']
                     var x=Math.floor(Math.random()*3)
                     this.a=arr[x]
                }
            },
        })
         
     </script>
 </body>

 

绑定style样式

  <!-- 绑定style样式,对象写法 -->
  <div class="base" :style="styleObj">{{name}}</div>
 
  styleObj:{
                fontSize:'40px'
                }

 

条件渲染

 <body>
     <div id="root">
         <!-- v-show本质调整display,如果变化频率高用,因为节点还在 -->
         <h2 v-show="true">欢迎来到{{name}}</h2>
         <!-- v-if不显示时,结构都删除,有v-else-if和v-else,用法和if,else,else if一样,中间不能打断 -->
         <h2 v-if="true">欢迎来到{{name}}</h2>
         <!-- template模板,只能配合v-if -->
     </div>
     <script>
         const vm=new Vue({
             el:"#root",
             data:{
               name:'cc',
            },
        })
         
     </script>
 </body>

 

列表渲染

 <body>
     <!--
         v-for指令:
             1.用于展示列表数据
             2.语法:v-for="(item,index) in xxx" :key="yyy"
             3.可遍历:数组,对象,字符串,指定次数
      -->
     <div id="root">
         <ul>
             <li v-for="p in persons" :key="p.id">{{p.name}}-{{p.age}}</li>
         </ul>
     </div>
     <script>
         const vm=new Vue({
             el:"#root",
             data:{
               persons:[
                {id:'001',name:'张三',age:18},
                {id:'002',name:'李四',age:19},
                {id:'003',name:'王五',age:20}
              ]
            },
        })
         
     </script>
 </body>

 

Key作用和原理

 

 

列表过滤

filter不该变原数组,返回一个新数组

 <!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 src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
     <style>
         .base{
             height: 100px;
             width: 100px;
        }
         .happy{
             background-color: red;
        }
         .sad{
             background-color: gray;
        }
         .normal{
             background-color: black;
        }
     </style>
 </head>
 <body>
 
     <div id="root">
         <input type="text" placeholder="请输入名字" v-model="keyWord">
         <ul>
             <li v-for="(p,index) of filPersons" :key="p.id">
                {{p.name}}-{{p.age}}
             </li>
         </ul>
     </div>
     <script>
         const vm=new Vue({
             el:"#root",
             data:{
               keyWord:'',
               persons:[
                {id:'001',name:'马冬梅',age:18},
                {id:'002',name:'周冬雨',age:19},
                {id:'003',name:'周杰伦',age:20},
                {id:'004',name:'温兆伦',age:21},
              ],
               //filPersons:[]
            },
             // watch:{
             //     keyWord:{
             //         immediate:true,
             //         handler(val){
             //             this.filpersons=this.persons.filter((p)=>{
             //             return p.name.indexOf(val)>=0
             //         })
             //         }
             //     }
             // }
             computed:{
                 filPersons(){
                         return this.persons.filter((p)=>{
                          return p.name.indexOf(this.keyWord)>=0
                      })
                }
            }
        })
         
     </script>
 </body>
 </html>

列表排序

 

 

 
posted @ 2022-11-30 15:46  l希尔瓦娜斯l  阅读(99)  评论(0)    收藏  举报