Vue.js 学习9 组件
来源:互联网 发布:淘宝掌柜名能改吗 编辑:程序博客网 时间:2024/05/20 05:24
一、使用组件
1.注册
创建一个Vue实例:
new Vue({ el: '#some-element', // 选项})
要注册一个全局组件,可以使用Vue.component(tagName,options)
Vue.component('my-component', { // 选项})
自定义标签名尽量使用w3c规则(小写,并包含一个短杠)。
组件在注册之后,便可以在父实例的模块中以自定义元素的形式使用。要确保在初始化根实例之前注册了组件:
<div id="example"> <my-component></my-component></div>
// 注册Vue.component('my-component', { template: '<div>A custom component!</div>'})// 创建根实例new Vue({ el: '#example'})
2.局部注册
var Child = { template: '<div>A custom component!</div>'}new Vue({ // ... components: { // <my-component> 将只在父模板可用 'my-component': Child }})
3.DOM模板解析说明
当使用DOM作为模板时,会受到HTML的一些限制。如:
<table><my-row>...</my-row></table>
变通的方案是使用特殊的is属性:
<table><tr is="my-row"></tr></table>
但如果使用
二、构成组件
在Vue.js中,父子组件的关系可以总结为props down,events up。父组件通过props向下传递数据给子组件,子组件通过events给父组件发送消息。
三、Prop
1.使用Prop传递数据
组件实例的作用域是孤立的。这意味着不能(也不应该)在子组件的模板内直接引用父组件的数据。要让子组件使用父组件的数据,需要通过子组件的props选项。
Vue.component('child', { // 声明 props props: ['message'], // 就像 data 一样,prop 可以用在模板内 // 同样也可以在 vm 实例中像 “this.message” 这样使用 template: '<span>{{ message }}</span>'})
这样传入一个普通字符串:
<child message="hello!"></child>
2.camelCase VS kebab-case
Vue.component('child', { // camelCase in JavaScript props: ['myMessage'], template: '<span>{{ myMessage }}</span>'})
<!-- kebab-case in HTML --><child my-message="hello!"></child>
注意这里HTML不分大小写,所以使用的不是字符串模板,要把prop转换为kebab-case。
3.动态Prop
<div> <input v-model="parentMsg"> <br> <child v-bind:my-message="parentMsg"></child></div>
使用 v-bind 的缩写语法通常更简单:
<child :my-message="parentMsg"></child>
4.字面量语法 vs 动态语法
<!-- 传递了一个字符串 "1" --><comp some-prop="1"></comp>
这里使用字面量语法传递数值是不对的,它的值是字符串1而不是number。要传递一个实际number,需要使用v-bind。
<!-- 传递实际的 number --><comp v-bind:some-prop="1"></comp>
5.单向数据流
prop是单向绑定的,当父组件的属性变化时,将传导给子组件,但是不会反过来。
另外,每次更新父组件时,子组件的所有prop都会更新为最新值。这意味着不应该在子组件内部改变prop。
6.Prop验证
Vue.component('example', { props: { // 基础类型检测 (`null` 意思是任何类型都可以) propA: Number, // 多种类型 propB: [String, Number], // 必传且是字符串 propC: { type: String, required: true }, // 数字,有默认值 propD: { type: Number, default: 100 }, // 数组/对象的默认值应当由一个工厂函数返回 propE: { type: Object, default: function () { return { message: 'hello' } } }, // 自定义验证函数 propF: { validator: function (value) { return value > 10 } } }})
type可以是下面原生构造器:
- String
- Number
- Boolean
- Function
- Object
- Array
四、自定义事件
1.使用v-on绑定自定义事件
每个 Vue 实例都实现了事件接口(Events interface),即:
- 使用 $on(eventName) 监听事件
- 使用 $emit(eventName) 触发事件
<div id="counter-event-example"> <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="increment">{{ counter }}</button>', data: function () { return { counter: 0 } }, methods: { increment: function () { this.counter += 1 this.$emit('increment') } },})new Vue({ el: '#counter-event-example', data: { total: 0 }, methods: { incrementTotal: function () { this.total += 1 } }})
2.给组件绑定原生事件
<my-component v-on:click.native="doTheThing"></my-component>
3..sync修饰符
子组件的值会同步到父组件。
<comp :foo.sync="bar"></comp>
会被扩展为:
<comp :foo="bar" @update:foo="val => bar = val"></comp>
当子组件需要更新 foo 的值时,它需要显式地触发一个更新事件:
this.$emit('update:foo', newValue)
4.使用自定义事件的表单输入组件
<currency-input v-model="price"></currency-input>
Vue.component('currency-input', { template: '\ <span>\ $\ <input\ ref="input"\ v-bind:value="value"\ v-on:input="updateValue($event.target.value)"\ >\ </span>\ ', props: ['value'], methods: { // 不是直接更新值,而是使用此方法来对输入值进行格式化和位数限制 updateValue: function (value) { var formattedValue = value // 删除两侧的空格符 .trim() // 保留 2 小数位 .slice(0, value.indexOf('.') + 3) // 如果值不统一,手动覆盖以保持一致 if (formattedValue !== value) { this.$refs.input.value = formattedValue } // 通过 input 事件发出数值 this.$emit('input', Number(formattedValue)) } }})
5.非父子组件通信
有时候两个组件也需要通信(非父子关系)。在简单的场景下,可以使用一个空的 Vue 实例作为中央事件总线:
var bus = new Vue()
// 触发组件 A 中的事件bus.$emit('id-selected', 1)// 在组件 B 创建的钩子中监听事件bus.$on('id-selected', function (id) { // ...})
五、使用Slot分发内容
<child-component> {{ message }}</child-component>
Vue.component('child-component', { // 有效,因为是在正确的作用域内 template: '<div v-show="someChildProperty">Child</div>', data: function () { return { someChildProperty: true } }})
1.单个Slot
除非子组件模板包含至少一个 插口,否则父组件的内容将会被丢弃。当子组件模板只有一个没有属性的 slot 时,父组件整个内容片段将插入到 slot 所在的 DOM 位置,并替换掉 slot 标签本身。
最初在 标签中的任何内容都被视为备用内容。备用内容在子组件的作用域内编译,并且只有在宿主元素为空,且没有要插入的内容时才显示备用内容。
2.具名Slot
元素可以用一个特殊的属性 name 来配置如何分发内容。多个 slot 可以有不同的名字。具名 slot 将匹配内容片段中有对应 slot 特性的元素。
仍然可以有一个匿名 slot ,它是默认 slot ,作为找不到匹配的内容片段的备用插槽。如果没有默认的 slot ,这些找不到匹配的内容片段将被抛弃。
3.作用域插槽
作用域插槽是一种特殊类型的插槽,用作使用一个(能够传递数据到)可重用模板替换已渲染元素。
六、动态组件
通过使用保留的 元素,动态地绑定到它的 is 特性,我们让多个组件可以使用同一个挂载点,并动态切换。
keep-alive
如果把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染。为此可以添加一个 keep-alive 指令参数
七、杂项
1.编写可复用组件
<my-component :foo="baz" :bar="qux" @event-a="doThis" @event-b="doThat"> <img slot="icon" src="..."> <p slot="main-text">Hello!</p></my-component>
2.子组件索引
3.异步组件
在大型应用中,我们可能需要将应用拆分为多个小模块,按需从服务器下载。为了让事情更简单, Vue.js 允许将组件定义为一个工厂函数,动态地解析组件的定义。Vue.js 只在组件需要渲染时触发工厂函数,并且把结果缓存起来,用于后面的再次渲染。
4.高级异步组件
5.组件命名约定
6.递归组件
组件在它的模板内可以递归地调用自己,不过,只有当它有 name 选项时才可以
7.组件间的循环引用
8.内联模板
如果子组件有 inline-template 特性,组件将把它的内容当作它的模板,而不是把它当作分发内容。这让模板更灵活。
9.X-Templates
另一种定义模版的方式是在 JavaScript 标签里使用 text/x-template 类型,并且指定一个id。
10.对低开销的静态组件使用v-once
尽管在 Vue 中渲染 HTML 很快,不过当组件中包含大量静态内容时,可以考虑使用 v-once 将渲染结果缓存起来,就像这样:
Vue.component('terms-of-service', { template: '\ <div v-once>\ <h1>Terms of Service</h1>\ ... a lot of static content ...\ </div>\ '})
原文:
https://cn.vuejs.org/v2/guide/components.html
- Vue.js 学习9 组件
- Vue.js 学习(9) -- 组件*1*
- Vue.js 学习(9) -- 组件*2*
- vue.js组件学习记录
- Vue.js学习笔记:组件
- Vue.js学习系列(四十二)-- Vue.js组件
- vue.js学习03之组件
- vue.js学习04之组件2
- Vue.js学习笔记-1-组件
- vue.js学习之组件(上篇)
- vue.js学习之组件(下篇)
- vue.js学习之组件(下篇)
- 【Vue.js】-Vue.js组件
- Vue.js组件
- Vue.js笔记-组件
- Vue.js说说组件
- Vue.js 组件
- vue.js组件开发
- Mongodb基础操作
- 基金申请
- 生产者消费者
- Java 8 forEach 示例
- Python 如何安装库
- Vue.js 学习9 组件
- linux下/proc/sysrq-trigger详解
- 12_变量_成员变量和局部变量_常量_命名规范
- 欢迎使用CSDN-markdown编辑器
- 35、数组中的逆序对
- MAC 10.12.5 JDK+Eclipse安装
- B
- 设计模式(13)-Visitor 访问者模式
- linux awk命令详解