温故而知新之VUE(三)

组件

// 全局注册
Vue.component('button-counter', {
// data  选项必须是一个函数,这样每个实例才可以维护一份被返回的data对象的独立拷贝  
data: function(){  
    return {
        count: 0
      }
  },
  template: ''
})
// 使用时

通过Props向子组件传递数据
Vue.component('blog-post', {
  props: ['post'],
  template: `
       

{{ post.title }}

` })
通过事件向父级组件发送消息

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

在组件上使用v-model

//等价于

当用在组件上



Vue.component('custom-input', {
  props: ['value'],
  template: `
     
`
})

// 现在可以使用v-model

通过插槽分发内容(slot)
动态组件
// 组件会在currentComponent改变时改变

解析DOM模板时的注意事项

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

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

深入了解组件

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

#组件名大小写

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

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


#Prop类型

props: {
  title: String
}
// 即使数据是静态的,也需要用v-bind来绑定,告诉vue这是一个js表达式,而不是一个字符串

#单向数据流
父组件通过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: `
      

})

#将原生事件绑定到组件

// .native修饰符

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

插槽slot

#具名slot


// 插入的内容
...

#插槽的默认内容

default content

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

动态组件&异步组件

#在动态组件上使用keep-alive VS 使用is
使用is:每次都会创建一个新的组件
使用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 // 父级组件

// this.$refs.usernameInput  调用

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

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

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

程序化的事件监听器

方法:
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: '
'

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

控制更新

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

你可能感兴趣的:(温故而知新之VUE(三))