一、自定义组件
1、组件命名
A、dom模板
在HTML模板中始终使用kebab-case命名组件
<kebab-cased-component> </kebab-cased-component>
B、字符串模板
比如script标签模板、js内联模板、.vue组件,可以使用kebab-case(短横线分隔命名)、camelCase(驼峰式命名)或PascalCase(单词首字母大写命名)。
2、组件通信
prop是单向绑定的,父组件的属性变化时,会使用prop给子组件传数据,反过来不会,这样可以避免子组件修改父组件的状态,而子组件通过自定义事件系统和父组件通信。简言之,父组件通过prop给子组件发数据,子组件通过事件给父组件发消息。
兄弟组件通信,新建空的vue实例,用$emit()和$on()实现,复杂的情况可以用状态管理模式vuex。
A、全局注册
<div id="J_app"> <ol> <my-tasks v-for="item in tasks" v-bind:todo="item" v-bind:key="item.id"> </my-tasks> </ol> </div> Vue.component('my-tasks', { props: ['todo'], template: '<li>{{ todo.text }}</li>' }) var vapp = new Vue({ el: '#J_app', data: { tasks: [ { id: 0, text: '学习webpack' }, { id: 1, text: '学习postcss' }, { id: 2, text: '学习vuejs' } ] } })
B、局部注册
<div id="J_app"> <ol> <my-tasks v-for="item in tasks" v-bind:todo="item" v-bind:key="item.id"> </my-tasks> </ol> </div> var Child ={ props: ['todo'], template: '<li>{{ todo.text }}</li>' } var vapp = new Vue({ el: '#J_app', data: { tasks: [ { id: 0, text: '学习webpack' }, { id: 1, text: '学习postcss' }, { id: 2, text: '学习vuejs' } ] }, components:{ 'my-tasks': Child } })
//父组件传值给子组件 <my-tasks v-bind:子组件的值="父组件的数据"></my-tasks>
3、data选项
构造Vue实例时传入的各种选项大多数都可以在组件里使用,只有data例外,data必须是函数。
<div id="J_app"> <simple-counter></simple-counter> <simple-counter></simple-counter> <simple-counter></simple-counter> </div> Vue.component('simple-counter', { template: '<button v-on:click="counter += 1">{{ counter }}</button>', data: function () { return { counter: 0 } } }) var vapp = new Vue({ el: '#J_app' })
4、组件作用域
父组件模板的内容在父组件作用域内编译,子组件模板的内容在子组件作用域内编译。
5、如果组件中包含大量静态内容,可以用v-once指令缓存渲染结果。
Vue.component('terms-of-service', { template: ' <div v-once> <h1>Terms of Service</h1> ...很多静态内容... </div> ' })
6、单文件组件
二、自定义事件
每个Vue实例都实现了事件接口,使用$on(eventName)监听事件,使用$emit(eventName)触发事件。
<div id="J_app"> <p>{{ total }}</p> <button-counter v-on:increment="incrementTotal"></button-counter> <button-counter v-on:increment="incrementTotal"></button-counter> </div> Vue.component('button-counter', { template: '<button v-on:click="incrementCounter">{{ counter }}</button>', data: function () { return { counter: 0 } }, methods: { incrementCounter: function () { this.counter += 1 this.$emit('increment') } } }) var vapp = new Vue({ el: '#J_app', data: { total: 0 }, methods: { incrementTotal: function () { this.total += 1 } } })
三、vue内置组件
1、列表过渡组件
.each-item { display: inline-block; margin-right: 10px; } .list-enter-active, .list-leave-active { transition: all 1s; } .list-enter, .list-leave-to /* .list-leave-active for below version 2.1.8 */ { opacity: 0; transform: translateY(30px); } <div id="J_transition_component"> <button v-on:click="add">Add</button> <button v-on:click="remove">Remove</button> <transition-group name="list" tag="p"> <span v-for="item in items" v-bind:key="item" class="each-item"> {{ item }} </span> </transition-group> </div> var vcompapp = new Vue({ el: '#J_transition_component', data: { items: [1,2,3,4,5,6,7,8,9], nextNum: 10 }, methods: { randomIndex: function () { return Math.floor(Math.random() * this.items.length) }, add: function () { this.items.splice(this.randomIndex(), 0, this.nextNum++) }, remove: function () { this.items.splice(this.randomIndex(), 1) } } })
四、UI组件
1、综合
http://www.wheelsfactory.cn/#/home?filter=vue
https://github.com/vuejs/awesome-vue#components--libraries
2、PC端
A、eleme
http://element.eleme.io/#/zh-CN
https://github.com/ElemeFE/element
B、iview
https://www.iviewui.com/
https://github.com/iview/iview
3、移动端
A、weex
http://weex-project.io/cn/guide/
https://github.com/alibaba/weex
B、vux
https://vux.li/demos/v2/?x-page=v2-doc-home#/
https://github.com/airyland/vux
C、eleme
http://mint-ui.github.io/
https://github.com/ElemeFE/mint-ui