美文网首页
温故而知新之VUE(三)

温故而知新之VUE(三)

作者: lmmy123 | 来源:发表于2018-11-07 21:11 被阅读10次

    组件

    // 全局注册
    Vue.component('button-counter', {
    // data  选项必须是一个函数,这样每个实例才可以维护一份被返回的data对象的独立拷贝  
    data: function(){  
        return {
            count: 0
          }
      },
      template: '<button @click="count++"> {{ count }}</button>'
    })
    // 使用时
    <button-counter />
    
    通过Props向子组件传递数据
    Vue.component('blog-post', {
      props: ['post'],
      template: `
           <div class="blog-post">
              <p>{{ post.title }}</p>
          </div>
     `
    })
    
    通过事件向父级组件发送消息

    通过 this.$emit(fnName, data)发送数据
    组件上 on 绑定 fnName接收数据

    在组件上使用v-model
    <input v-model="searchText" />
    //等价于
    <input :value="searchText" @input="searchText=$event.target.value" />
    

    当用在组件上

    <custom-input  :value="searchText" @input="searchText=$event" />
    
    Vue.component('custom-input', {
      props: ['value'],
      template: `
         <input :value="value"  @input="$emit('input', $event.target.value)">
    `
    })
    
    // 现在可以使用v-model
    <custom-input v-model="searchText" />
    
    通过插槽分发内容(slot)
    动态组件
    // 组件会在currentComponent改变时改变
    <component v-bind:is = "currentComponent" ></component>
    
    解析DOM模板时的注意事项
    <table>
      <tr is="blog-pist-row"></tr>
    </table>
    

    如果我们从以下来源使用模板时,这条限制是不存在的

    • 字符串(例如: template:"")
    • 单文件组件(.vue)

    深入了解组件

    组件注册
    Vue.component(name, {
      
    })
    

    #组件名大小写

    • 使用kebab-case(短横线)
    • 使用PascalCase(驼峰式命名)
    局部注册
    var ComponentA = {  }
    new Vue({
      el: "#app",
      components: {
        ComponentA
      }
    })
    
    Props

    #大小写
    在HTML中使用短横线

    <blog-post post-title="hello"></blog-post>
    

    #Prop类型

    props: {
      title: String
    }
    
    // 即使数据是静态的,也需要用v-bind来绑定,告诉vue这是一个js表达式,而不是一个字符串
    <blog-post :comment-ids="[234,54,3]" />
    

    #单向数据流
    父组件通过props传递数据给子组件,自上向下流动
    #Prop验证

    props: {
      propA: [String,Number],
      propB: Number,
      propC: {
        type: String,
        default: "iing"
      },
     propD: {
      // 自定义验证函数
      validator: function(value){
        return ['success','warning'].indexOf(value) !==-1
        }
     }
    }
    

    #非Prop的特性
    #替换/合并已有的特性
    #禁用特性继承
    设置inheritAttrs: false

    Vue.component('my-componnet', {
      inheritAttrs: false
    })
    
    自定义事件

    事件名推荐使用短横线命名
    v-on:myEvent 会渲染成 v-on:myevent,所以导致myEvent不能被监听到
    #自定义组件的v-model
    2.2.0+新增

    Vue.component('base-checkbox', {
      model: {
        prop:"checked",
        event: "change"
      },
      props: {
         checked: Boolean
      },
      template: `
       <input type="checkbox" :checked="checked" @change="$emit('change', $event.target.checked)" />   
    
    })
    
    <base-checkbox v-model="msg" />
    

    #将原生事件绑定到组件

    // .native修饰符
    <base-checkbox v-on:focus.native="onFocus" />
    

    提供了一个$listeners属性,它是一个对象,里面包含了作用在这个组件上的所有监听器,
    #.sync修饰符
    2.3.0+新增

    插槽slot

    #具名slot

    <slot name="header"></slot>
    // 插入的内容
    <div slot="header">...</div>
    

    #插槽的默认内容

    <slot>default content</slot>
    

    #编译作用域
    父组件模板的所有东西都会在父级组件作用域内编译,子组件模板的所有东西都会在子级作用域内编译
    #作用域插槽
    2.1.0+新增

    动态组件&异步组件

    #在动态组件上使用keep-alive VS 使用is
    使用is:每次都会创建一个新的组件
    使用keep-alive:会缓存

    <keep-alive>
      <component :is="currentComponent"></component>
    </keep-alive>
    

    #异步组件
    实现按需加载

    // 结合webpack中的code-splitting功能一起使用
    Vue.component('async-webpack-example', function(resolve){
      //这个require语法会告诉webpack自动将你的构建代码切割成多个包,这些包会通过Ajax请求加载  
      require(['./my-async-component'], resolve)
    })
    

    或可以

    // 使用webpack2和ES6语法结合
    new Vue({
        components: {
            'my-component': ()=>import('./my-async-component')
        }
    })
    

    #处理加载状态
    2.3.0+新增

    const AsyncComponent = ()=> ({
        // 需要加载的组件
        component: import('./MyComponent.vue'),
       //异步组件加载时使用的组件
       loading: LoadingComponent,
       // 加载失败时使用的组件
       error: ErrorComponent,
      // 展示加载时组件的延时时间,默认值为200毫秒
      delay: 200,
      // 超时时间
      timeout: 3000
    })
    // 如果在vue-router上使用,需要vue-router在2.4.0+版本
    

    处理边界情况

    访问元素&组件

    #访问根实例

    this.$root // 根实例
    this.$parent // 父级组件
    
    <base-input ref="usernameInput" />
    // this.$refs.usernameInput  调用
    

    refs之后在组件渲染完成之后生效,并且他们不是响应式的,应该避免在模板或者计算属性中访问refs
    #依赖注入
    两个新的实例选项provide 和 inject
    provide: 允许我们指定想要提供给后代组件的数据和方法

    provide: function(){
      return {
        getMap: this.getMap
      }
    }
    
    // 在任何后代组件中,都可以使用inject 选项来接收指定的我们想要添加在实例上的属性/方法
    inject: ['getMap']
    

    依赖注入相对于$parent有优势,但缺点是造成组件之间的耦合度提高,中大型项目建议VUEX

    程序化的事件监听器

    方法:
    on(eventName, eventHandler) 侦听一个事件once(eventName, eventHandler) 一次性侦听一个事件
    $off(eventName, eventHandler) 停止侦听一个事件

    mounted: function(){
      this.picker = new Pikaday({
        field: this.$refs.input
      })
      // 监听 组件销毁前 销毁这个实例
      this.$once('hook:beforeDestroy', function(){
        picker.destroy()
      })
    }
    
    循环引用

    #递归组件
    通过name选项来调用自身
    注意跳出递归的条件,避免无限循环

    name : 'stack-overflow',
    template: '<div><stack-overflow /></div>'
    

    #组件之间的循环引用
    #内联模板
    inline-template

    控制更新

    #强制更新
    通过$forceUpdate
    通过v-once创建低开销的静态组件,当需要渲染大量静态内容时,不然没必要使用,也不应该过度使用

    相关文章

      网友评论

          本文标题:温故而知新之VUE(三)

          本文链接:https://www.haomeiwen.com/subject/yyjuxqtx.html