代码编织梦想

数组的响应式监听

list[0] 下标去操作数组 页面不会实时更新(这也是vue2的一个bug)

(修改原数组)这些都会触发 数组的响应式
push pop unshift shift splice sort reverse
(不修改原数组) 不会触发
map reduce forEach filter
concat slice

<!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>
  
</head>
<body>
    <!-- 
        需求:
        添加新用户,点击按钮使添加到的新用户加入list数组,并显示出来
    
    -->
    <div id="app">
        <!-- v-model双向数据的绑定 -->
        <input type="text" v-model="query">
        <button @click="addPerson">添加新用户</button>
        <ul>
      <li v-for="person in list"  :key="person.id">
        {{person.name}}<input type="text">
      </li>
        </ul>

    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
   <script>
       new Vue({
           el:"#app",
           data(){
       
               return{
                query:'',
                list:[ 
                    {id:'0001',name:'朱雀·'},
                    {id:'0002',name:'丸子'},
                    {id:'0003',name:'锦鲤'},
                    {id:'0004',name:'夏至'}
                ]
                
               }
           },
           methods: {
            addPerson(){
                // this.list.push({
                //     id:'0005',
                //     name:this.query
                // })
                // this.list.unshift({
                //     id:'0005',
                //     name:this.query
                // })
                this.list.reverse()
            }

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

对象的响应式监听

增加属性 不会被响应式监听到
删除属性 也不会被响应式监听到

<!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>
  
</head>
<body>
    <!-- 
        需求:
        添加新用户,点击按钮使添加到的新用户加入list数组,并显示出来
    
    -->
    <div id="app">
      
    <h2>姓名:{{person.name}}</h2>
    <p>年龄:{{person.age}}</p>
    <p>标签:{{person.tag}}</p>
    <button @click="person.name='大宝贝'">修改对象name值</button>
    <button @click="person.tag='美女'">添加对象tag属性值</button>
    <button @click="deletePerson">删除对象age属性值</button>
</div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
   <script>
       new Vue({
           el:"#app",
           data(){
       
               return{
                query:'',
                person:{
                    name:'王小二',
                    age:45,
                }
                
               }
           },
           methods: {
            deletePerson(){
                delete this.person.age,
                console.log(this.person)
          
            }

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

使用Vue.set 或者 vm.$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>
  
</head>
<body>
    <!-- 
        需求:
        添加新用户,点击按钮使添加到的新用户加入list数组,并显示出来
    
    -->
    <div id="app">
      
    <h2>姓名:{{person.name}}</h2>
    <p>年龄:{{person.age}}</p>
    <p>标签:{{person.tag}}</p>
    <button @click="person.name='大宝贝'">修改对象name值</button>
    <button @click="addTag">添加对象tag属性值</button>
    <button @click="deletePerson">删除对象age属性值</button>
</div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
   <script>
       new Vue({
           el:"#app",
           data(){
       
               return{
                query:'',
                person:{
                    name:'王小二',
                    age:45,
                }
                
               }
           },
           methods: {

            addTag(){
                this.$set(this.person,'tag','美女')
            },
            deletePerson(){
                delete this.person.age,
                console.log(this.person)
          
            }

           }
        
       })


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

函数在外部进行操作(这种方法一般很少用的)

<!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>
  
</head>
<body>
    <!-- 
        需求:
        添加新用户,点击按钮使添加到的新用户加入list数组,并显示出来
    
    -->
    <div id="app">
      
    <h2>姓名:{{person.name}}</h2>
    <p>年龄:{{person.age}}</p>
    <p>标签:{{person.tag}}</p>
    <button @click="person.name='大宝贝'">修改对象name值</button>
    <button @click="addTag">添加对象tag属性值</button>
    <button @click="deletePerson">删除对象age属性值</button>
</div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
   <script>
    let  person={
                    name:'王小二',
                    age:45,
                }
       new Vue({
           el:"#app",
           data(){
       
               return{
                query:'',
                person,
                
               }
           },
           methods: {

            addTag(){
                this.$set(this.person,'tag','美女')
            },
            deletePerson(){
                delete this.person.age,
                console.log(this.person)
          
            }

           }
        
       })
      Vue.set(person,'tag','帅哥')  //直接可以看到tag内部信息

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

双向数据绑定指令

使用v-model 来实现表单元素和数据的双向绑定
绑定value值

<input type="text" v-model:value="query">
简写为
<input type="text" v-model="query">
双向的数据  input输入内容  改变 query值  query值发生变化  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>
</head>
<body>
    <div id="app">
       <input type="text" v-model:value="query">
       <p>{{query}}</p>

    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
   <script>
    
       new Vue({
           el:"#app",
           data(){
               return{
                   query:'',
               }
           }
       })
   </script>
</body>
</html>

原生js实现(很麻烦)

1.先去获取input
2.获取value值
3.获取p标签
4.把value值 innerHTML的方式 给p
5. input 监听 input事件 内容发生变化 触发p.innerHTML

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>
</head>
<body>
    <div id="app">
       <input type="text" v-bind:value="query" v-on:input="changeQuery">
       <p>{{query}}</p>

    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
   <script>
    
       new Vue({
           el:"#app",
           data(){
               return{
                   query:'默认值',
               }
           },
           methods: {
            changeQuery(event){
                this.query = event.target.value
            }
           },
           
       })
   </script>
</body>
</html>                                                                                                                                      

绑定对象

<!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>
</head>
<body>
    <div id="app">
        <!-- 
     当输入的是多条数据的时候,需要一个对象进行接收比如queryForm

         -->
       <input type="text" v-model="queryForm.username">
       <input type="password" v-model="queryForm.password">
       <input type="submit" @click="submit">

    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
   <script>
    
       new Vue({
           el:"#app",
           data(){
               return{
                   queryForm:{
                    username:"",
                    password:""
                   }
               }
           },
           methods: {
            changeQuery(event){
                this.query = event.target.value
            },
            submit(){
                console.log(this.queryForm)
            }
           },
           
       })
   </script>
</body>
</html>

绑定复选框的情况

// 绑定复选框
绑定值  checked 非数组时 : 绑定值为  布尔值
  <input type='checkbox' v-model='checked'>
  checked:false
<!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>
</head>
<body>
    <div id="app">
        <!-- 绑定复选框 -->
        <input type="checkbox" v-model="checked">足球<br>
        <!-- 当你点击足球的这个复选框的时候,checked='true' -->
        <input type="checkbox">篮球
    
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
   <script>
    
       new Vue({
           el:"#app",
           data(){
               return{
                  checked:'',
               }
           },
           methods: {
         
           },
           
       })
   </script>
</body>
</html>

绑定值 checked 是数组时,要定义一下value的值,不然数组里面的值为null

<!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>
</head>
<body>
    <div id="app">
        <!-- 绑定复选框 -->
        <input type="checkbox" v-model="checked" value="足球"><br>
        <input type="checkbox" v-model="checked" value="篮球"><br>
        <input type="checkbox" v-model="checked" value="羽毛球"><br>
        <input type="checkbox" v-model="checked" value="兵乓球"><br>
    
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
   <script>
    
       new Vue({
           el:"#app",
           data(){
               return{
                  checked:[],
               }
           },
           methods: {
         
           },
           
       })
   </script>
</body>
</html>

绑定单选框 (得写value值)

绑定值为value值 或 option 内的内容

<!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>
</head>
<body>
    <div id="app">
     打篮球:<input type="radio" v-model="picked" value="打篮球"><br>
     睡觉:<input type="radio" value="睡觉" v-model="picked">
     <p>{{picked}}</p>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
   <script>
    
       new Vue({
           el:"#app",
           data(){
               return{
                 picked:''
               }
           },
           methods: {
         
           },
           
       })
   </script>
</body>
</html>

下拉选框

<!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>
</head>
<body>
    <div id="app">
    <select v-model="picked">
        <option>篮球</option>
        <option>足球</option>
        <option>排球</option>
    </select>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
   <script>
    
       new Vue({
           el:"#app",
           data(){
               return{
                 picked:''
               }
           },
           methods: {
         
           },
           
       })
   </script>
</body>
</html>

多选下拉


<!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>
</head>
<body>
    <div id="app">
    <select v-model="picked" multiple>
        <option>篮球</option>
        <option>足球</option>
        <option>排球</option>

    </select>
            <p>{{picked}}</p>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
   <script>
    
       new Vue({
           el:"#app",
           data(){
               return{
                 picked:''
               }
           },
           methods: {
         
           },
           
       })
   </script>
</body>
</html>

v-model修饰词

.lazy
<!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>
</head>
<body>
    <div id="app">
        <!-- 
            需求:等input输入完毕之后,P标签再发生改变,而不是实时地发生改变
         -->
  
     <input type="text" v-model.lazy="query">
 
            <p>{{query}}</p>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
   <script>
    
       new Vue({
           el:"#app",
           data(){
               return{
                query:''
               }
           },
           methods: {
         
           },
           
       })
   </script>
</body>
</html>
.number

尽力把 绑定内容变为 数值

  1. 一开始是 中文或者符号 绑定值是字符串
  2. 一开始 绑定 数字 是 后面 以 parseFloat 为准 改为数值

<!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>
</head>
<body>
    <div id="app">
        <!-- 
            需求:等input输入完毕之后,P标签再发生改变,而不是实时地发生改变
         -->
         <!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>
         </head>
         <body>
             <div id="app">
                 <!-- 
                     需求:等input输入完毕之后,P标签再发生改变,而不是实时地发生改变
                  -->
           
              <input type="text" v-model.number="query">
               <button @click="fn">进行计算</button>
                     <p>{{num}}</p>
             </div>
             <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
            <script>
             
                new Vue({
                    el:"#app",
                    data(){
                        return{
                         query:'',
                         num:1
                        }
                    },
                    methods: {
                            fn(){
                                console.log(this.query)
                             this.num =this.query+this.num
                            }
                    },
                    
                })
            </script>
         </body>
         </html>
   
.trim
<!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>
</head>
<body>
    <div id="app">
        <!-- 
            需求:等input输入完毕之后,P标签再发生改变,而不是实时地发生改变
         -->
         <!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>
         </head>
         <body>
             <div id="app">
                 <!-- 
                     需求:等input输入完毕之后,P标签再发生改变,而不是实时地发生改变
                  -->
           
              <input type="text" v-model.trim="query">
                     <p>{{query}}</p>
             </div>
             <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
            <script>
             
                new Vue({
                    el:"#app",
                    data(){
                        return{
                         query:''

                        }
                    },
                    methods: {
                           
                    },
                    
                })
            </script>
         </body>
         </html>  

总结

input text v-model 收集的是value值 用户输入
input radio 收集的也是value值 需要给radio配置 value值
input checkbox 绑定数据 非数组 收集到的是 布尔值 (适合一个复选框)
绑定数组时 收集到的就是checkbox value值 (需要配置value值)
修饰符:.lazy .number .trim

自定义指令

实现自定义的一些功能

全局注册指令:所有实例下都可以使用 此指令

Vue.directive(directivename,fnObj) //fnObj是指令对象


       <!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>
         </head>
         <body>
             <div id="app">
              <input type="text" v-focus="123">
             </div>
             <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
            <script>
                  // v-focus  
                //          指令名不需要带v-,但是用的时候  需要带
                Vue.directive('focus',(el,binding) =>{
                    // el 使用指令的节点对象
                    //  binding 绑定值对象
                    console.log(el)
                    console.log(binding)
                    // 让节点具有焦点
                    el.focus()//无法触发焦点,得用钩子函数
                })
                new Vue({
                    el:"#app",
                    data(){
                        return{
                      

                        }
                    },
                    methods: {
                           
                    },
                    
                })
           
            </script>
         </body>
         </html>
钩子函数

常用的三个钩子
bind 指令与元素成功绑定时调用
inserted 指令所在的元素 插入页面的时候使用
updated 有更新 更新之后使用


    <!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>
      </head>
      <body>
          <div id="app">
           <input type="text" v-focus="123">
          </div>
          <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
         <script>
               // v-focus  
             //          指令名不需要带v-,但是用的时候  需要带
             Vue.directive('focus',{
                 bind(el,binding){
                     console.log('bind -- 指令与元素成功绑定时调用')
                 },
                 inserted(el,binding){
                     el.focus() //得在 input在页面中渲染才触发
                     console.log('inserted -- 指令所在的元素被插入页面时调用')
                 },
                 update(){
                     console.log('在包含组件的VNode及其组件的VNode 更新后调用')
                 }

             })
            
             new Vue({
                 el:"#app",
                 data(){
                     return{
                   

                     }
                 },
                 methods: {
                        
                 },
                 
             })
        
         </script>
      </body>
      </html>

局部注册指令 供当前容器使用
 //    简便写法:但是不知道为什么 我的可以触发焦点
    directives:{
        focus(el,binding){
            console.log("自定义指令----1")
            el.focus()//无法触发,原因是 这里相当于  bind钩子内调用
       
        }

    },

需要使用其他钩子函数的时候
new Vue({
el:“#app”,
directives:{
focus:{
inserted(el,binding){
el.focus()
}
}

    },
       data(){
           return{
         

           }
       },
       methods: {
              
       },
       
   })

``html

Document
```
Vue选项配置项
computed 计算属性

计算属性:进行加工处理之后的数据

<!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>
    <style>
     
    </style>
</head>
<body>
    <div id="app">
        <!-- 
            需求:实现每个名字的首字母要大写
         -->
         <!-- <p>{{person.split(' ').map(item=>{
              return item[0].toUpperCase()+item.slice(1)    
        }).join(" ")}}</p>    -->
        <p> {{personUpper}}</p>
    <p>{{person}}</p>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
   <script>
       new Vue({
           el:"#app",
           data(){
               return{
                   person:'xiao zhu zhu'
               }
           },
           methods: {
          

           },
         computed:{
            // 需要加工的数据  personUpper 的值  就是  return的值
            // 可以通过vm查看
            personUpper(){// 再此定义的全部都是  属性  而不是函数
                return this.person.split(' ').map(item=>{
                 return  item[0].toUpperCase()+item.slice(1)    
                  }).join(" ")
            }
            // 这样子写 默认  只有 getter

         }
        
       })
   </script>
</body>
</html>
<!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>
    <style>
     
    </style>
</head>
<body>
    <div id="app">
        <!-- 
            需求:实现每个名字的首字母要大写
         -->
         <!-- <p>{{person.split(' ').map(item=>{
              return item[0].toUpperCase()+item.slice(1)    
        }).join(" ")}}</p>    -->
        <p> {{personUpper}}</p>
          <p>{{person}}</p>
          <button @click="fn">我想修改personUpper的值</button>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
   <script>
       new Vue({
           el:"#app",
           data(){
               return{
                   person:'xiao zhu zhu'
               }
           },
           methods: {
            fn(){
                // console.log(this.personUpper)
                // this.personUpper = 'Xiao Zha Zha'  报错:ersonUpper" was assigned to but it has no setter.
            //   这样子写   默认  只有  getter

            }


           },
         computed:{
            // 需要加工的数据  personUpper
            // 可以通过vm查看
            personUpper(){// 再此定义的全部都是  属性  而不是函数
                return this.person.split(' ').map(item=>{
                 return  item[0].toUpperCase()+item.slice(1)    
                  }).join(" ")
            }

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

在某些情况 需要设置 计算属性的值时 我们需要用到 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>
    <style>
     
    </style>
</head>
<body>
    <div id="app">
        <input type="text" v-model="person.firstname">
        <input type="text" v-model="person.lastname"><br>
        <hr>
        <input type="text" v-model="personUpper">
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
   <script>
       new Vue({
           el:"#app",
           data(){
               return{
                   person:{
                    firstname:'xiao',
                    lastname:'zhu'
                   }
               }
           },
           methods: {
       

           },
         computed:{
            personUpper:{
                get(){ //当访问personUpper计算属性值时   会触发get函数
                    return this.person.firstname+'---'+this.person.lastname
                },
                set(newValue){// 修改personUpper计算属性值  = 赋值时  会触发set函数  新的值  会被newValue接收到
                    console.log(newValue)
                    let arr = newValue.split('---')
                    this.person.firstname = arr[0],
                    this.person.lastname = arr[1]

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

computed 缓存性
在不使用computed的情况下,实现以上的功能

<!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>
    <style>
     
    </style>
</head>
<body>
    <!-- 在没有computed配置项时候,我们该如何实现以上的功能呢? -->
    <div id="app">
        <input type="text" v-model="person.firstname">
        <input type="text" v-model="person.lastname"><br>
        <hr>
        <input type="text" v-model="handlePerson()">
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
   <script>
       new Vue({
           el:"#app",
           data(){
               return{
                   person:{
                    firstname:'xiao',
                    lastname:'zhu'
                   }
               }
           },
           methods: {
            handlePerson(){
                return this.person.firstname+'---'+this.person.lastname
            }
       

           },
        //  computed:{
        //     personUpper:{
        //         get(){ //当访问personUpper计算属性值时   会触发get函数
        //             return this.person.firstname+'---'+this.person.lastname
        //         },
        //         set(newValue){// 修改personUpper计算属性值  = 赋值时  会触发set函数  新的值  会被newValue接收到
        //             console.log(newValue)
        //             let arr = newValue.split('---')
        //             this.person.firstname = arr[0],
        //             this.person.lastname = arr[1]

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

分析原因 第一次访问 personUpper 的时候 调用 getter 这个值会被缓存起来
第二次访问 personUpper 的时候 使用 缓存值
getter 函数 只有两个时机会执行
1. 第一次访问 计算属性 的时候
2. 依赖的数据(data内的数据)发生变化的时候,其他的普通数据,不会触发

 computed:{
            personUpper:{
                get(){ //当访问personUpper计算属性值时   会触发get函数
                   console.log('computed')
                   console.log(this.num) //当改变num的值的时候会触发getter函数
                    return this.person.firstname+'---'+this.person.lastname
                },
                set(newValue){// 修改personUpper计算属性值  = 赋值时  会触发set函数  新的值  会被newValue接收到
                    console.log(newValue)
                    let arr = newValue.split('---')
                    this.person.firstname = arr[0],
                    this.person.lastname = arr[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>
    <style>
     
    </style>
</head>
<body>
    <!-- computed的缓存 -->
    <div id="app">
        <input type="text" v-model="person.firstname">
        <input type="text" v-model="person.lastname"><br>
        <hr>
        {{handlePerson()}}____{{handlePerson()}}____{{handlePerson()}}<br>
       {{personUpper}}____ {{personUpper}} ____ {{personUpper}}
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
   <script>
       new Vue({
           el:"#app",
           data(){
               return{
                   person:{
                    firstname:'xiao',
                    lastname:'zhu'
                   }
               }
           },
           methods: {
            handlePerson(){
                console.log('method')//打印了三次
                return this.person.firstname+'---'+this.person.lastname
            }
       

           },
         computed:{
            personUpper:{
                get(){ //当访问personUpper计算属性值时   会触发get函数
                   console.log('computed')//打印了一次
                    return this.person.firstname+'---'+this.person.lastname
                },
                set(newValue){// 修改personUpper计算属性值  = 赋值时  会触发set函数  新的值  会被newValue接收到
                    console.log(newValue)
                    let arr = newValue.split('---')
                    this.person.firstname = arr[0],
                    this.person.lastname = arr[1]

                }
            }
          
         }
        
       })
   </script>
</body>
</html>
对比一下 method 和 computed
  1. 调用上 method 要加()(除了作为事件函数) 计算属性不需要加()执行 而是直接使用
  2. method 函数有没有返回值都可以 computed 必须要有 return 值
  3. method 没有缓存性 computed 有缓存性
  4. 在工具内 有computed选项 可以看到计算值 (便于观察数据)
  5. 处理值 computed 比method 更专业高效
watch
   // 为啥没对象无法被监听
            person(newValue,oldValue){
                   console.log(newValue,oldValue)
            }
<!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>
    <style>
     
    </style>
</head>
<body>
    <!-- computed的缓存 -->
    <div id="app">
        <input type="text" v-model="person.firstname">
        <input type="text" v-model="person.lastname"><br>
        被监听{{num}}次
        <hr>
        <button @click="changeStr">改变str的值</button>
        <button @click="changeNum">改变num的值</button>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
   <script>
      const vm= new Vue({
           el:"#app",
           data(){
               return{
                str:'你好',
                num:1,
                   person:{
                    firstname:'xiao',
                    lastname:'zhu',
                    Info:{
                       hobby:'学习'
                    }
                   }
               }
           },
           methods: {
            changeStr(){
                this.str+="!"
            },
            changeNum(){
                  this.num++
            //  console.log('改变num!!!')
            }
           },
           watch:{
            //监视数据的变化 
            // 监听基础数据类型,可以被监听
            str(newValue,oldValue){
                console.log(newValue,oldValue)
            },
            num(){ 
                console.log('改变num!!!')
             
            },
            // 为啥没对象无法被监听
            // 监听对象的某个属性,属性是基础类型的时候
            'person.firstname':function(newValue,oldValue){
                  this.num++,
                   console.log(newValue,oldValue)
            },
            // 对象写法 需要开启某个属性  属性是基础值类型的情况
            person:{
            //   监听函数
            handler(newValue,oldValue){
                console.log(newValue,oldValue)
            },
            // 深度监听
            deep:true,
            }

           }
      
         
        
       })
    //    console.log(vm)
   </script>
</body>
</html>
vue2 对数组 不监听

生命周期

又名 生命周期回调函数 生命周期函数 生命钩子函数

beforeCreate
 //在创建实例之前 但未初始化   创建实例成功!!!
        beforeCreate(){
            console.log('容器:'+this.$el);//undefined
            console.log('数据:'+this.str)//undefined
        },
created

应用:你可以在这里 请求数据 或者 做一些页面初始化的事情

  // data 和method 等数据都可以使用了  但是 el的挂载还没有做 不能访问页面dom
        created(){ //常用来异步请求数据
            //alert('你好好!!')
            console.log('容器:'+this.$el);
            console.log('数据:'+this.str)
        }
beforeMount
beforeMount() {
            //alter(11111)
            console.log('容器:'+this.$el);
            console.log('数据:'+this.str)
         },
mounted
  mounted() {
           let txt = document.querySelector('#txt');
           console.log(txt);
           txt.focus()
        },
beforeUpdate
 beforeUpdate(){
           console.log('数据发生了变化,但虚拟dom还没更新完成');
       },
updated
   updated(){
          console.log('数据已经发生了变化,视图也已经更新完毕')
      }
    
beforeDestroy
beforeDestroy() {
         // 在vue3内 改为 beforeUnmount
           console.log('待销毁状态  虽然内容配置项数据都可以使用  但是更新不会引发变化')
     },
destroyed
 ```js
  destroyed() {
        // 在vue3内 改为了 unmounted
        console.log('已经被销毁')

    }, destroyed() {
        // 在vue3内 改为了 unmounted
        console.log('已经被销毁')

    },
 ```

总结:就是在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>
    <style>
     
    </style>
</head>
<body>
    <!-- computed的缓存 -->
    <div id="app">
        <input type="text" v-model="person.firstname">
        <input type="text" v-model="person.lastname"><br>
        <hr>
        {{num}}<br>
        {{str}}<br>
        <button @click="logout">点击销毁</button>
        <!-- <button @click="changeStr">改变str的值</button>
        <button @click="changeNum">改变num的值</button> -->
    <hr>
    <input type="text" id="txt">
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
   <script>
      const vm= new Vue({
           el:"#app",
           data(){
               return{
                str:'你好',
                num:1,
                   person:{
                    firstname:'xiao',
                    lastname:'zhu',
                    Info:{
                       hobby:'学习'
                    }
                   }
               
           }
        },
        methods: {
            logout(){
              this.$destroy();//vue2的销毁api
             // this.#unmout();//vue3的销毁api
            }
        },
        //在创建实例之前 但未初始化   创建实例成功!!!
        beforeCreate(){
            console.log('容器:'+this.$el);//undefined
            console.log('数据:'+this.str)//undefined
        },
        // data 和method 等数据都可以使用了  但是 el的挂载还没有做 不能访问页面dom
        created(){ //常用来异步请求数据
            //alert('你好好!!')
            console.log('容器:'+this.$el);
            console.log('数据:'+this.str)
        },
// 在挂载开始之前被调用  当前  模板被编译完成了  但是 还没有 渲染到页面中去

         beforeMount() {
            //alter(11111)
            console.log('容器:'+this.$el);
            console.log('数据:'+this.str)
         },
        //  这里 页面开始渲染 可以操作dom 了 在vue3的改变后 异步请求
       // 数据...一些操作  都放在mounted里面来做
         mounted() {
            let txt = document.querySelector('#txt');
            console.log(txt);
            txt.focus()
         },
        //data数据发生变化时 触发视图更新 移除事件监听器  适宜在这里访问 未更新前的dom
        beforeUpdate(){
            console.log('数据发生了变化,但虚拟dom还没更新完成');
        },
        updated(){
            console.log('数据已经发生了变化,视图也已经更新完毕')
        },
        beforeDestroy() {
            // 在vue3内 改为 beforeUnmount
              console.log('待销毁状态  虽然内容配置项数据都可以使用  但是更新不会引发变化')
        },
        destroyed() {
            // 在vue3内 改为了 unmounted
            console.log('已经被销毁')

        },
       })
    //    console.log(vm)
   </script>
</body>
</html>

组件

组件就是把一个网页分割成独立的小的模块,然后通过把模块进行组合,构建成一个大型的应用

单文件组件 只有一个组件 html css js 都在这个文件内
非单文件组件 可有多个组件
全局注册
!! 得先注册子组件 再生成 vm实例对象 
创建子组件  
const child = Vue.extend({
      //除了 el 其他任意配置项都可以用  
      name: 'child',
      data() {
        return {
          msg: 123
        }
      },
      // 写组件的html内容 
      template: `<h1>我是child子组件</h1>`
    })

//全局注册子组件  自定义组件名  组件对象  
    Vue.component('child', child)

    const vm = new Vue({
      name: 'app',
      el: '#app',
      data() {
        return {}
      }
    })

语法糖的写法 省略 Vue.extend() 在使用 child组件时 内部会自己调用

const child = {
      name: 'child',
      data() {
        return {
          msg: 123
        }
      },
      // 写组件的html内容 
      template: `<h1>我是child子组件</h1>`
    }
   Vue.component('child', child)

view model  vm new Vue() 产生的  老大哥 管理一切 小弟 

子组件实例对象  简称 vc  
<!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>
    <style>
     
    </style>
</head>
<body>
    <div id="app">
            <child></child>
            <child></child>
            <child></child>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
   <script>

    //    得先注册子组件  再生成vm实例对象
    // 创建子组件
       const child = Vue.extend({
        // 除了el其他任意配置项都可以用
        name:'child',
        data(){
            return{
                msg:123
            }
        },
        //写组件的html内容
        template:`<h1>我是child子组件</h1>`

       })
    //    全局注册子组件  自定义组件名  组件对象
       Vue.component('child',child)
       const vm = new Vue({
           el:"#app",
           data(){
               return{
                   bool:true,
               }
           },
           methods: {
          

           }
        
       })
       console.log(vm)
   </script>
</body>
</html>
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_57858263/article/details/130882173

vite的使用-爱代码爱编程

私人博客 许小墨のBlog —— 菜鸡博客直通车 系列文章完整版,配图更多,CSDN博文图片需要手动上传,因此文章配图较少,看不懂的可以去菜鸡博客参考一下配图! 系列文章目录 前端系列文章——传送

打包和优化-爱代码爱编程

私人博客 许小墨のBlog —— 菜鸡博客直通车 系列文章完整版,配图更多,CSDN博文图片需要手动上传,因此文章配图较少,看不懂的可以去菜鸡博客参考一下配图! 系列文章目录 前端系列文章——传送