Vue基础(2)

1.表单修饰符

  • .lazy(限制实时传入服务器) 失去焦点之后才能更新
  • .number(限制输入的为数字)
  • .trim(去掉首尾字符是空格)
  <body>
    <div id="box">
      <input type="text" v-model.lazy='mytext'>
      {{mytext}}

      <!-- <input type="text" v-model.number='mynumber'> -->
      <input type="number" v-model='mynumber'>
      {{mynumber}}

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

2.axios与fetch实现数据请求

(1)fetch

why:
XMLHttpRequest是一个设计粗糙的API,配置和调用方式非常混乱,而且基于事件的异步模型写起来不友好。
兼容性不好
polyfill:
https://github.com/camsong/fetch-ie8

  <body>
    <div id="box">
      <button @click='handleClick()'>获取影片信息</button>
      <ul>
        <li v-for='data in dataList'>
          <h3>{{data.name}}</h3>
          <img :src="data.poster" alt="">
        </li>
      </ul>
    </div>
    <script>
      new Vue({
        el:"#box",
        data:{
          dataList:[]
        },
        methods:{
          handleClick(){
            fetch('./json/test.json').then(res=>res.json()).then(res=>{
                 console.log(res.data.films)
                 this.dataList=res.data.films
             })
          }
        }
      })
    </script>
  </body>

注意:fetch请求默认是不带cookie的,需要设置fetch(url,{credentials:‘include’})

(2) axios(第三方库)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="../js/vue.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  </head>
  <body>
    <div id="box">
      <button @click='handleClick()'>正在热映</button>
      <ul>
        <li v-for='data in dataList'>
          <h3>{{data.name}}</h3>
          <img :src="data.poster" alt="">
        </li>
      </ul>
    </div>
    <script>
      new Vue({
        el:"#box",
        data:{
          dataList:[]
        },
        methods:{
          handleClick(){
            axios.get('./json/test.json').then(res=>{
              console.log(res.data.data.films) //axios 自动包装data属性 res.data
              this.dataList=res.data.data.films
            }).catch(err=>{
              console.log(err)
            })
          }
        }
      })
    </script>
  </body>
</html>

3.计算属性

  • 计算属性,定义在computed里面,定义起来像函数一样,使用起来像属性一样
  • 计算属性要比普通方法的性能要高
  • 多次调用时,方法都会重新执行一遍,计算属性只计算一遍,会缓存,使用缓存
  <body>
    <div id="box">
      <!-- {{myname.substring(0,1).toUpperCase() + myname.substring(1)}}  -->
      <p>计算属性:{{getMyName}}</p>
      <p>普通方法:{{getMyNameMethod()}}</p>
      <br>
      <div>
        <p>计算属性:{{getMyName}}</p>
        <p>普通方法:{{getMyNameMethod()}}</p>
      </div>
    </div>
    <script>
      new Vue({
        el:"#box",
        data:{
          myname:'xiaoming'
        },
        methods:{
          getMyNameMethod(){
            console.log("getMyNameMethod-方法调用")
            return this.myname.substring(0,1).toUpperCase() + this.myname.substring(1)
          }
        },
        computed:{
          getMyName(){
            console.log("getMyName-计算属性调用")
            return this.myname.substring(0,1).toUpperCase() + this.myname.substring(1)
          } //依赖的状态改变了,计算属性会重新计算一遍
        }
      })
    </script>
  </body>

计算属性模糊查询

  <body>
    <div id="box">
      <input type="text" v-model="mytext">
      <ul>
        <li v-for='data in getMyDataList'> 
          {{data}}
        </li>
      </ul>
    </div>
    <script>
      var vm = new Vue({
        el:"#box",
        data:{
          mytext:"",
          dataList:['aaa','abb','bbb','ccc','cdd','ddd','dee'],
        },
        computed:{
          getMyDataList(){
            return this.dataList.filter(item=>item.indexOf(this.mytext)>-1)
          }
        }
      })
    </script>
  </body>

4.虚拟dom与diff算法

  1. 同层级对比
  2. 同key值对比
  3. 同组件对比

5.组件化开发

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

  • 全局定义组件(作用域隔离),不能访问new Vue里面的方法和属性
  • 在哪个组件的模板之中,就是谁的孩子
  • navbar是根组件的孩子,child是navbar的孩子
    sidebar是根组件的孩子,child是sidebar的孩子
  • 全局定义的孩子,谁都可以访问
  <body>
    <div id="box">
      <navbar></navbar>
      <sidebar></sidebar>
    </div>
    <script>
      Vue.component('navbar',{
        template:`
        <div>
          <button @click="handleback()">返回</button>
            navbar
          <button>主页</button>
          <child></child>
          <navbarchild></navbarchild>
        </div>`,
        methods:{
          handleback(){
            console.log('back');
          }
        },
        // 局部组件定义
        components:{
          navbarchild:{
            template:`<div>navbar-child-只能在navbar组件中使用</div>`
          }
        }
      })

      Vue.component('child',{
        template:'<div>child组件-全局定义</div>'
      })

      Vue.component('sidebar',{
        template:`
        <div>
          sidebar组件
          <child></child>
        </div>`
      })

      new Vue({
        el:"#box",
      })//根组件 root component
    </script>
  </body>

组件的编写方式与Vue实例的区别

  1. 自定义组件需要有一个root element,不一定是div标签
  2. 父子组件的data是无法共享
  3. 组件可以有data,methods,computed…但是data必须是一个函数

6.组件通信

  1. 父子组件传值(props down,events up)
  2. 属性验证
    props:{name:Number}
    Number,String,Boolean,Array,Object,Function,null(不限制类型)
  3. 事件机制
a.使用$.on(eventName)监听事件
b.使用$emit(eventName)触发事件
  1. ref
    <innput ref='mytext'> this.$refs.mytext

  2. 事件总线
    var bus=new Vue();
    *mounted生命周期种进行监听

(1)父传子

  <body>
    <div id="box">
      <navbar myname='home' :myshow='false'></navbar>
      <navbar myname='list' :myshow='true'></navbar>
      <navbar :myname='parentname' :myshow='true'></navbar>

    </div>
    <script>
      Vue.component('navbar',{
        template:`
        <div>
          <button>返回</button>
           navbar--{{myname}}
          <button v-show='myshow'>首页</button>
        </div>`,
        // props:['myname','myshow']  //接受父组件传来的属性
        // 属性验证
        props:{
          myname:String,
          myshow:Boolean
        }
      })
      new Vue({
        el:"#box",
        data:{
          parentname:"父组件的状态"
        }
      })
    </script>
  </body>

(2)子传父

  <body>
    <div id="box">
      父组件
      <child @myevent='handleEvent($event)'></child>
    </div>
    <script>
      // 子组件
      Vue.component('child',{
        template:`<div>
            child组件
            <button @click='payMoney()'>click</button>
          </div>`,
        data(){
          return{
            childname:'子组件的状态'
          }
        },
        methods:{
          payMoney(){
            this.$emit('myevent',this.childname) //分发事件
          }
        }
      })
      new Vue({
        el:"#box",
        methods:{
          handleEvent(ev){
            console.log("父组件收到钱了",ev)
          }
        }
      })
    </script>
  </body>

子传父案例

  <body>
    <div id="box">
     <!-- <button @click='isShow=!isShow'>click</button> -->
     <navbar @myevent='handleEvent'></navbar>
      <sidebar v-show='isShow'></sidebar>

    </div>
    <script>
      Vue.component('navbar',{
        template:`<div>
          navbar
          <button @click='handleClick'>navbar-button</button>
        </div>`,
        methods:{
          handleClick(){
            this.$emit("myevent");
          }
        }
      }),
      Vue.component('sidebar',{
        template:`<div style='background:yellow;width:200px;'>
          <ul>
            <li>1111</li>
            <li>1111</li>
            <li>1111</li>
          </ul>
          </div>`
      })
      new Vue({
        el:"#box",
        data:{
          isShow:false
        },
        methods:{
          handleEvent(){
            this.isShow=!this.isShow;
          }
        }
      })
    </script>
  </body>

(3)ref通信

  1. ref放在标签上,拿到的是原生节点
  2. ref放在组件上,拿到的是组件对象
    ref可以绑多个
  <body>
    <div id="box">
      <input type="text" ref='mytext'>
      <button @click='handleAdd'>add</button>

      <child ref='mychild'></child>
    </div>
    <script>
      // 子组件
      Vue.component("child",{
        template:`<div>
          child
        </div>`,
        data(){
          return {
            childname:"子组件的状态"
          }
        },
        methods:{
          add(data){
            console.log("子组件的方法",data)
          }
        }
      })
      var vm = new Vue({
        el:"#box",
        data:{

        },
        methods:{
          handleAdd(){
            console.log("1111",this.$refs.mychild.childname);
            this.$refs.mychild.add('孩子听话')
          }
        }
      })
    </script>
  </body>

(4)非父子通信-事件总线

  <body>
    <div id="box">
      <weixinauthor></weixinauthor>
      <weixinuser></weixinuser>
    </div>
    <script>
      var bus=new Vue(); //空vue实例 就是中央事件总线

      Vue.component("weixinauthor",{
        template:`<div style='background:blue'>
          我是微信公众号作者
          <input type='text' ref='mytext'>
          <button @click='handleClick()'>发布</button>
        </div>`,
        methods:{
          handleClick(){
            bus.$emit('weixinmessage',this.$refs.mytext.value)
          }
        }
      })

      Vue.component('weixinuser',{
        // 合适的位置先订阅好 bus.$on
        template:`<div style='background:yellow'>
          我是一个微信用户
        </div>`,
        mounted(){
          bus.$on("weixinmessage",(data)=>{
            console.log('收到推送了',data)
          })
          console.log("生命周期函数-当前组件的dom创建完成之后就会调用")
        }
      })

      new Vue({
        el:"#box",
      })
    </script>
  </body>

(5)动态组件

<component>元素,动态地绑定多个组件到它的is属性
<keep-alive>保留状态,避免重新渲染
  <body>
    <div id="box">
      <keep-alive>
        <component :is='who'></component>
      </keep-alive>
      <footer>
        <ul>
          <li><a @click="who='home'">首页</a></li>
          <li><a @click="who='list'">列表页</a></li>
          <li><a @click="who='shopcar'">购物车页面</a></li>
        </ul>
      </footer>
    </div>
    <script>
      var vm = new Vue({
        el:"#box",
        data:{
          who:'home'
        },
        components:{
          'home':{
            template:`<div>home<input type='text'></div>`
          },
          'list':{
            template:`<div>list</div>`,
          },
          'shopcar':{
            template:`<div>shopcar</div>`,
          }
        }
      })
    </script>
  </body>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值