Vue学习

  • Post author:
  • Post category:vue




1.Vue

  1. 官方介绍

    Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

  2. 引入方式

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>



2.Vue拦截原理

当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。Object.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因

在这里插入图片描述

注意:

Object.defineProperty有以下缺点

1、无法监听es6的Set、Map 变化;

2、无法监听Class类型的数据;

3、属性的新加或者删除也无法监听;

4、数组元素的增加和删除也无法监听。

针对Object.defineProperty的缺点,ES6 Proxy都能够完美得解决,唯一的缺点就是,对IE不友好



3.Vue模板语法

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

      v-show v-if指令
      <div v-show="isShow">动态显示和隐藏</div>
      <div v-if="isCreated">动态创建和删除</div>

todolist

<body>
   <div id="box">
       <!-- 双向绑定的指令 -->
       <input type="text" v-model="mytext"/>
       <button @click="handleAdd()">add</button>

       <div v-show="!datalist.length">待办事项空空如也</div>
       <ul v-show="datalist.length">
           <li v-for="(item,index) in datalist">
               {{item}}--{{index}}
               <button @click="handleDel(index)">del</button> 
            </li>
       </ul>
   </div>
   <script>
       var vm = new Vue({
           el:"#box",
           data:{
            mytext:"11111",
            datalist:["111","222","333"]
           },
           methods:{
            handleAdd(){
                console.log("add",this.mytext)
                this.datalist.push(this.mytext)

                this.mytext = "" //清空value
            },
            handleDel(index){
                console.log("del",index)
                this.datalist.splice(index,1)
            }
           }
       })
   </script>
</body>

v-html指令

在这里插入图片描述

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



4.class与style

  1. 点击变色:
<body>
    <div id="box">
        <ul>
            <li v-for="(item,index) in datalist" :class=" current===index?'active':'' " @click="handleClick(index)">
                {{item}}
            </li>
        </ul>
    </div>

    <script>
        new Vue({
            el:"#box",
            data:{
                current:0,
                datalist:["1","2","3"]
            },
            methods:{
                handleClick(index){
                    console.log(index)
                    this.current = index
                }
            }
        })
    </script>
</body>
  1. vue2-class&style
<body>
  <div id="box">
     <div :class="classobj">动态切换class-1-对象</div>
     <div :class="classarr">动态切换class-2-数组</div>
     <div :style="styleobj">动态切换style-1-对象</div>
     <div :style="stylearr">动态切换style-2-数组</div>
  </div>

  <script>
      var vm = new Vue({
        el:"#box",
        data:{
          classobj:{
            aa:true,
            bb:true,
            cc:false
          },
          classarr:["aa","bb"],
          styleobj:{
            backgroundColor:'red'
          },
          stylearr:[{backgroundColor:"yellow"}]
        }
      })
      // vue2 解决方案, Vue.set(对象,属性,true) Vue.set(vm.classobj,"dd",true)
      // vue3 支持动态增加属性的拦截
  </script>
</body>
  1. vue3-class&style
    <script>
        var obj = {
            //函数式
            data(){
                return {
                    myname:"kerwin",
                    mytext:"",
                    classobj:{
                        aa:true,
                        bb:true,
                        cc:false
                    }
                }
            },
            methods:{
                handleAdd(){
                    console.log("add",this.mytext)
                    this.classobj.dd=true
                }
            }
        }
        var vm = Vue.createApp(obj).mount("#box")
    </script>



5.条件渲染

    <div v-if="isCreated">111111</div>
    <div v-else>222222</div> 
<body>
    <div id="box">
       <template v-if="isCreated"> 
            <div>11111111</div>
            <div>22222222</div>
            <div>33333333</div>
       </template>
    </div>

    <script>
        var vm = new Vue({
            el:"#box",
            data:{
                isCreated:true
            }
        })
        /*
            template 就是一个包装元素, 不会真正创建在页面上.
        */
    </script>
</body>



6.列表渲染

在这里插入图片描述

<body>
  <div id="box">
    <ul>
      <li v-for="(item,index) of datalist" :key="item">
        {{item}}--{{index}}
      </li>
    </ul>

    <ul>
      <li v-for="(item,key) of obj">
       {{key}} - {{item}}
      </li>
    </ul>

    <ul>
      <li v-for="item in 10">
        {{item}}
      </li>
    </ul>
  </div>
  <script>
     var vm = new Vue({
       el:"#box",
       data:{
         datalist:["1111","2222","3333"],
         obj:{
           name:"kerwin",
           age:100,
           location:"dalian"
         }
       }
     })
  </script>
</body>



7.模糊查询

<div id="box">
        <!-- input change事件区别 -->
      <input type="text" @input="handleInput" v-model="mytext"/>
      <ul>
          <li v-for="data in datalist" :key="data">
              {{data}}
          </li>
      </ul>
    </div>

    <script>
        var vm = new Vue({
            el:"#box",
            data:{
                mytext:"",
                datalist:["aaa","add","bbb","bbc","ccc","ddd","eee","ade"],
                originList:["aaa","add","bbb","bbc","ccc","ddd","eee","ade"]
            },
            methods:{
                handleInput(){
                    console.log("input",this.mytext)
                    // es5 filter 
                    setTimeout(()=>{
                        this.datalist = this.originList.filter(item=> item.includes(this.mytext) )

                    },2000)
                    // console.log(newlist)
                }
            }
        })

        var arr =["aaa","add","bbb","bbc","ccc","ddd","eee","ade"]

        var newlist = arr.filter(item=> item.includes("a") )

        console.log(newlist,arr)

    </script>

函数表达式方案

    <script>
        var vm = new Vue({
            el:"#box",
            data:{
                mytext:"",
                datalist:["aaa","add","bbb","bbc","ccc","ddd","eee","ade"],  
            },
            methods:{
                test(){
                    console.log("test--------------")
                    return this.datalist.filter(item=> item.includes(this.mytext) )
                }
            }
        })
    </script>



8.事件处理器

1、监听事件-直接触发代码

2、方法事件处理器-写函数名 handleClick

3、内联处理器方法-执行函数表达式 handleClick($event) $event 事件对象

<body>
    <div id="box" >
       {{count}}

       <button @click="handleAdd1($event,1,2,3)">add-1-函数表达式</button>
       <button @click="handleAdd2">add-2-函数名</button>

       <input type="text" @input="handleInput"/>
    </div>
    
    <script type="text/javascript">
        new Vue({
            el:"#box",
            data:{
                count:1
            },
            methods:{
                handleAdd1(evt,a,b,c){
                    console.log(evt,a,b,c)
                    this.count++
                },
                handleAdd2(evt){
                    this.count++
                    console.log(evt.target)
                },
                handleInput(evt){
                    console.log("input",evt.target.value)
                }
            }
        })
    </script>
</body>



9.事件修饰符

事件修饰符https://cn.vuejs.org/v2/guide/events.html

stop

prevent

capture

self

once

passive

模态框案例

<head>
    <style>
        #overlay {
            background: rgba(0, 0, 0, 0.6);
            width: 100%;
            margin: auto;
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
        }

        #center {
            background: #ffff;
            border-radius: 5px;
            padding-top: 15px;
            padding-left: 30px;
            padding-bottom: 15px;
            width: 290px;
            height: 160px;
            position: fixed;
            margin: auto;
            left: 0;
            right: 0;
            top: 0;
            bottom: 0;
        }
    </style>
</head>
<body>
    <!-- 模态框 -->
    <div id="box">
       <button @click="isShow=true">show</button>
       <div id="overlay" v-show="isShow" @click.self="isShow=false">
        <div id="center">
            <div>用户名:<input type="text"/></div>
            <div>密码:<input type="password"/></div>
            <div>
                <button>登录</button>
            </div>
        </div>
      </div>
    </div>

    <script>
        var vm = new Vue({
            el: "#box",
            data: {
                isShow: false,
            }
        })
    </script>
</body>



10.表单控件绑定

<body>
  <div id="box">
    {{mytext}}
    <textarea v-model="mytext"></textarea>
    <div>
      <div>用户名:<input v-model="mytext"/></div>
      <input type="checkbox" v-model="isRemember"/> 记住用户名
      <button @click="handleLogin">登录</button>
    </div>
    <div>
       <h2>注册页面-兴趣爱好</h2>
       <input type="checkbox" v-model="checkList" value="vue"/>   vue
       <input type="checkbox" v-model="checkList" value="react"/>   react
       <input type="checkbox" v-model="checkList" value="wx"/>   小程序
    </div>

    {{checkList}}
    <div>
      <h2>性别选择</h2>

      <input type="radio" v-model="select" value="a"/><input type="radio" v-model="select" value="b"/></div>
  </div>

  <script>
    var vm = new Vue({
      el: "#box",
      data: {
        mytext: localStorage.getItem("username"),
        isRemember:true,
        checkList:[],
        select:"a"
      },
      methods:{
        handleLogin(){
          if(this.isRemember){
            localStorage.setItem("username",this.mytext)
          }
    console.log(this.mytext,this.checkList,this.select)
        }
      }
    })
  </script>
</body>



11.表单修饰符

.lazy :失去焦点同步一次

.number :格式化数字

.trim : 去除首尾空格

<body>
    <div id="box">
       <!-- lazy修饰符 -->
        <input v-model.lazy="mytext"/>
        {{mytext}}

        <input type="number" v-model.number="myage"/>

        <input type="text" v-model.trim="myusername"/>
    </div>
   
    <script type="text/javascript">
      var vm = new Vue({
        el:"#box",
        data:{
          mytext:"",
          myage:0,
          myusername:""
        }
      })
    </script>
</body>



12.计算属性

计算属性是基于它们的依赖进行缓存的。

计算属性只有在它的相关依赖发生改变时才会重新求值

<body>
  <div id="box">
     {{ myname.substring(0,1).toUpperCase() + myname.substring(1) }}
     {{ myComputedName }}
     {{ myComputedName }}
     {{ myComputedName }}

     {{ myMethodName() }}
     {{ myMethodName() }}
     {{ myMethodName() }}
  </div>
  <script>
    //计算属性(防止模板过重,难以维护),负责逻辑放在计算属性中来写。
    // 计算属性 有缓存, 基于依赖的缓存
    var vm = new Vue({
      el:"#box",
      data:{
        myname:"zzz",
      },
      //方法:
      methods:{
        myMethodName(){
          console.log("myMethodName-方法")
          return this.myname.substring(0,1).toUpperCase() + this.myname.substring(1)
        }
      },
      //计算的
      computed:{
        myComputedName(){
          console.log("myMethodName-计算属性")

          return this.myname.substring(0,1).toUpperCase() + this.myname.substring(1)
        }
      }
    })
    /*
      0. data => 状态,被拦截。
      1. 方法==》 事件绑定, 逻辑计算。可以不用return,没有缓存
      2. 计算属性(重视结果)=》 解决模板过重问题,必须有return ,只求结果 ,有缓存,同步。
      3. watch (重视过程), 监听一个值的改变。 不用返回值 ,异步同步
    */
  </script>
</body>



13.watch

<body>
    <div id="box">
        <!-- input change事件区别 -->
      <input type="text" v-model="mytext"/>
      <ul>
          <li v-for="data in datalist" :key="data">
              {{data}}
          </li>
      </ul>
    </div>

    <script>
        var vm = new Vue({
            el:"#box",
            data:{
                mytext:"",
                datalist:["aaa","add","bbb","bbc","ccc","ddd","eee","ade"],
                originList:["aaa","add","bbb","bbc","ccc","ddd","eee","ade"]
            },
            watch:{
                mytext(newval){
                    console.log("改变了",newval)
                    setTimeout(()=>{
                        this.datalist = this.originList.filter(item=> item.includes(newval) )
                    },1000)
                }
            }
        })

    </script>
</body>



14.fetch-get

  1. fetch

    why:

    XMLHttpRequest 是一个设计粗糙的 API,配置和调用方式非常混乱,

    而且基于事件的异步模型写起来不友好。

    兼容性不好

    polyfill:https://github.com/camsong/fetch-ie8
//get
get  url路径  ?name=kerwin&age=100    
post body请求体 , 
(1)x-www-formurlencoded , name=kerwin&age=100
(2)json ,     `{"name":"kerwin",age:100}`



15.fetch-post

        // post-1
        fetch("**",{
             method:'post',
             headers: {
                "Content‐Type": "application/x‐www‐form‐urlencoded"
             },
            body: "name=kerwin&age=100",      
        }).then(res=>res.json()).then(res=>{console.log(res)});
      
        // post-2
         fetch("https://m.vip.com/server.html?rpc&method=pageCache&f=www&_=1563946036520",{
             method:'post',
             headers: {
                "Content‐Type": "application/json"
             },
             body: JSON.stringify({
                 name:"kerin",
                 age:100
             })
        }).then(res=>res.json()).then(res=>{console.log(res)});



16.axios

        axios.post("****","name=kerwin&age=100") // (1)
        axios.post("****",{name:"kerwin",age:100}) //(2)



17.猫眼数据

<body>
    <div id="box">
        <button @click="handleAjax">click-ajax</button>
        <ul>
            <li v-for="item in datalist" :key="item.id">
                <img :src="handleImg(item.img)"/>
                {{item.nm}}
            </li>
        </ul>
    </div>

    <script >
        new Vue({
            el:"#box",
            data:{
                datalist:[]
            },
            methods:{
                handleAjax(){
                    axios.get("./json/maoyan.json").then(res=>{
                        console.log(res.data.movieList)
                        this.datalist = res.data.movieList
//for 处理
                    })
                },
                handleImg(url){
                    return url.replace('w.h/','')+'@1l_1e_1c_128w_180h'
                }
            }
        })
    </script>
</body>




18.组件定义

组件化:

扩展 HTML 元素,封装可重用的代码

  1. 起名字 :js驼峰, html 链接符-
  2. dom片段 没有代码提示 没有高亮显示 – vue单文件组件解决
  3. css 只能写成 行内。- vue单文件组件解决
  4. template 包含一个根节点
  5. 组件是孤岛,无法直接访问外面的组件的状态或者方法。- 间接的组件通信来交流。
  6. 自定义的组件 data 必须是一个函数,
  7. 所有的组件都在一起, 太乱了-vue单文件组件解决
        //定义一个全局的组件
        Vue.component("kerwinNavbar",{
            //dom, js ,css
            template:`<section style="background:red;border:5px solid black;">
                <button @click="handleLeft">left</button>
                猫眼电影-{{myname}}
                <button @click="handleRight">right</button>
                <child></child>

                <kerwin-child></kerwin-child>
                
            </section>`,
            methods:{
                handleLeft(){
                    console.log("left")
                },
                handleRight(){
                    console.log("right")
                }
            },
            computed:{},
            watch:{},
            //data必须是函数写法
            data(){
                return {
                    myname:"11111111"
                }
            },
            //局部
            components:{
                "kerwinChild":{
                    template:`
                        <div>child-{{myname}}</div>
                    `,
                    data(){
                        return {
                            myname:"child-11111"
                        }
                    }
                }
            }
        })
        Vue.component("child",{
            template:`
                <div style="background:yellow">公司标语</div>
            `
        })
        //根组件
        new Vue({
            el:"#box",
            data:{

            }
        })



19.父传子

  <script>
    Vue.component("navbar",{
      props:{       
         myname:{
           type:String,
           default:""
         },
         myright:{
           type:Boolean,
           default:true
         },
         myparent:{
           type:String,
           default:""
         }
      },//接受myname属性, 属性验证, 默认属性

      template:`<div>
        <button>left</button>
        <span>{{myname}}--{{myparent}}</span>  
        <button v-show="myright">right</button>  
      </div>`
    })    
    new Vue({
      el:"#box",
      data:{
        parent:"11111111111111111111111111"
      }
    })//创建根组件
</script>



20.子传父

<body>
  <div id="box">   
    <navbar  @myevent="handleEvent"></navbar>
    <sidebar v-show="isShow" ></sidebar>
  </div>
  <script>
    Vue.component("navbar", {
      template: `
        <div style="background-color: red;">
          <button @click="handleClick()">点击</button>-导航栏
        </div>
      `,
      methods:{
        handleClick(){
          // console.log("子传父, 告诉父组件 ,取反您的isShow")
          this.$emit("myevent",1000000000)
        }
      }
    })
    Vue.component("sidebar", {
      template: `
      <div style="background-color: yellow;" >
        <ul>
          <li>11111</li>
          <li>11111</li>
        </ul>
      </div>
      `
    })
    new Vue({
      el: "#box",
      data: {
        isShow: true
      },
      methods:{
        handleEvent(data){
          console.log("父组件的定义的事件",data)
          this.isShow = !this.isShow
        }
      }

    })
  </script>
</body>



版权声明:本文为apple_73086122原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。