注册

注册一个全局组件:Vue.component(tagName, options)

Vue.component('my-component', {
template: '<div>A custom component!</div>'
})
<div id="example">
<my-component></my-component>
</div> new Vue({
el: '#example'
}) 局部注册:通过组件实例选项注册
var Child = {
template: '<div>A custom component!</div>'
}
new Vue({
el: '#example',
components: {//<my-component> 将只在父模板可用
'my-component': Child
}
})

使用is属性:

<table>
<tr is="my-row"></tr>
//==<my-row>...</my-row>,table下标签有HTML的限制可以换用is的形式
</table>

使用模板,这些限制将不适用:

  1. <script type="text/x-template">

  2. JavaScript 内联模板字符串

  3. .vue 组件

data必须是一个函数,并且,如果返回一个公共的变量,实例之间将共享数据。

props://prop 是单向绑定的

<child my-message="hello!"></child>
//当使用的不是字符串模板,camelCased (驼峰式) 命名的 prop 需要转换为相对应的 kebab-case (短横线隔开式) 命名:
Vue.component('child', {
props: ['myMessage'],
template: '<span>{{ myMessage }}</span>'
})
动态prop:
<div>
<input v-model="parentMsg">
<child :my-message="parentMsg"></child>
</div>
 props 传递所有的属性,绑定一个对象:

todo: {
text: 'Learn Vue',
isComplete: false
}
<child v-bind="todo"></child>
<!-- 传递实际的 number -->
<comp v-bind:some-prop=""></comp>
props验证

原生构造器类型:
StringNumberBooleanFunctionObjectArraySymbol
type 也可以是一个自定义构造器函数,使用 instanceof 检测。 Vue.component('example', {
props: {
// 基础类型检测 (`null` 意思是任何类型都可以)
propA: Number,
// 多种类型
propB: [String, Number],
// 必传且是字符串
propC: {
type: String,
required: true
},
// 数字,有默认值
propD: {
type: Number,
default:
},
// 数组/对象的默认值应当由一个工厂函数返回
propE: {
type: Object,
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
return value >
}
}
}
})

非prop属性,也允许加入到属性,(如一些第三方组件,可以把属性直接添加到组件上 ,不需要事先定义 prop)

<bs-date-input data-3d-date-picker="true"></bs-date-input>

从父组件传来的属性值,如class会和组件模板定义的同名属性合并

自定义事件

<div id="counter-event-example">
<p>{{ total }}</p>
<button-counter v-on:increment="incrementTotal"></button-counter> //$on用来监听increment事件
<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:
}
},
methods: {
incrementCounter: function () {
this.counter +=
this.$emit('increment') //$emit用来触发increment事件,调用incrementTotal方法
}
},
})
new Vue({
el: '#counter-event-example',
data: {
total:
},
methods: {
incrementTotal: function () {
this.total +=
}
}
})

.native 修饰符

//在某个组件的根元素上监听一个原生事件。可以使用 .native 修饰 v-on
<my-component v-on:click.native="doTheThing"></my-component>

.sync 修饰符

//双向绑定,只是作为一个编译时的语法糖
<comp :foo.sync="bar"></comp>

自定义的表单输入组件

货币筛选器
html:
<div id="app">
<currency-input label="Price" v-model="price"></currency-input>
<currency-input label="Shipping" v-model="shipping"></currency-input>
<currency-input label="Handling" v-model="handling"></currency-input>
<currency-input label="Discount" v-model="discount"></currency-input>
<p>Total: ${{ total }}</p>
</div> js:
Vue.component('currency-input', {
template: '\
<div>\
<label v-if="label">{{ label }}</label>\
$\
<input\
ref="input"\
v-bind:value="value"\
v-on:input="updateValue($event.target.value)"\
v-on:focus="selectAll"\
v-on:blur="formatValue"\
>\
</div>\
',
props: {
value: {
type: Number,
default:
},
label: {
type: String,
default: ''
}
},
mounted: function () {
this.formatValue()
},
methods: {
updateValue: function (value) {
var result = currencyValidator.parse(value, this.value)
if (result.warning) {
this.$refs.input.value = result.value
}
this.$emit('input', result.value)
},
formatValue: function () {
this.$refs.input.value = currencyValidator.format(this.value)
},
selectAll: function (event) {
setTimeout(function () {
event.target.select()
}, )
}
}
}) new Vue({
el: '#app',
data: {
price: ,
shipping: ,
handling: ,
discount:
},
computed: {
total: function () {
return ((
this.price * +
this.shipping * +
this.handling * -
this.discount *
) / ).toFixed()
}
}
})

自定义组件的v-model,默认一个组件的 v-model 会使用 value 属性和 input 事件,但是诸如单选框、复选框之类的输入类型把 value 属性用作了别的目的。这时需要设置组件的model选项来指定prop和event

<my-checkbox v-model="foo" value="some value"></my-checkbox>
Vue.component('my-checkbox', {
model: {
prop: 'checked',
event: 'change'
},
props: {
checked: Boolean,
// this allows using the `value` prop for a different purpose
value: String
},
// ...
})

编译的作用域:

<child-component v-show="someChildProperty"></child-component>
//someChildProperty存在于父作用域

Vue.component
('child-component', {
// someChildProperty存在于子作用域
template: '<div v-show="someChildProperty">Child</div>',
data: function () {
return {
someChildProperty: true
}
}
})

内容分发:插槽

<div>
<h2>我是子组件的标题</h2>
<slot>
只有在没有要分发的内容时才会显示。
</slot>
 <slot name="footer"></slot>
//具名插槽
</div>
<div>
<h1>我是父组件的标题</h1>
<my-component>
<p>这是一些初始内容</p>
<p>这是更多的初始内容</p>
<p slot="footer">这里有一些联系信息</p>
</my-component>
</div>
作用域插槽://子组件的内容可以在父组件指定
父:
<my-awesome-list :items="items">
<!-- 作用域插槽也可以是具名的 -->
<template slot="item" scope="props">
<li class="my-fancy-item">{{ props.text }}</li>
</template>
</my-awesome-list> 子:
<ul>
<slot name="item"
v-for="item in items"
:text="item.text"
>
<!-- 这里写入备用内容 -->
</slot>
</ul>

动态组件 

var vm = new Vue({
el: '#example',
data: {
currentView: 'home'
},
components: {
home: { /* ... */ },
posts: { /* ... */ },
archive: { /* ... */ }
}
}) <component v-bind:is="currentView">
<!-- 组件在 vm.currentview 变化时改变! is指向的组件名随之变化-->
</component>

如果把切换出去的组件保留在内存中, keep-alive,可以保留它的状态或避免重新渲染

<keep-alive>
<component :is="currentView">
<!-- 非活动组件将被缓存! -->
</component>
</keep-alive>

子组件索引:ref 为子组件指定一个索引 ID

<div id="parent">
<user-profile ref="profile"></user-profile>
</div> var parent = new Vue({ el: '#parent' }) // 直接访问子组件
var child = parent.$refs.profile

异步组件

全局异步组件:
Vue.component(
'async-webpack-example',
() => import('./my-async-component')
) 局部异步组件:
new Vue({
// ...
components: {
'my-component': () => import('./my-async-component')
}
}) 高级异步组件://当一个异步组件被作为 vue-router 的路由组件使用时,这些高级选项都是无效的,因为在路由切换前就会提前加载所需要的异步组件
const AsyncComp = () => ({
// 需要加载的组件。应当是一个 Promise
component: import('./MyComp.vue'),
// loading 时应当渲染的组件
loading: LoadingComp,
// 出错时渲染的组件
error: ErrorComp,
// 渲染 loading 组件前的等待时间。默认:200ms。
delay: ,
// 最长等待时间。超出此时间则渲染 error 组件。默认:Infinity
timeout:
})

组件命名约定:

当注册组件 (或者 props) 时,可以使用 kebab-case,camelCase,或 PascalCase。

// 在组件定义中
components: {
// 使用 kebab-case 形式注册
'kebab-cased-component': { /* ... */ },
// register using camelCase
'camelCasedComponent': { /* ... */ },
// register using PascalCase
'PascalCasedComponent': { /* ... */ }
}

在 HTML 模板中,请使用 kebab-case 形式:

<!-- 在 HTML 模板中始终使用 kebab-case -->
<kebab-cased-component></kebab-cased-component>
<camel-cased-component></camel-cased-component>
<pascal-cased-component></pascal-cased-component>

如果组件未经 slot 元素传递内容,你甚至可以在组件名后使用 / 使其自闭合<my-component/>

递归组件:

组件在它的模板内可以递归地调用自己,不过,只有当它有 name 选项时才可以

Vue.component('stack-overflow', {
template: '<div><stack-overflow></stack-overflow></div>'
})
父组件tree-folder
<p>
<span>{{ folder.name }}</span>
<tree-folder-contents :children="folder.children"/>
</p> 子组件tree-folder-contents:
<ul>
<li v-for="child in children">
<tree-folder v-if="child.children" :folder="child"/>
<span v-else>{{ child.name }}</span>
</li>
</ul>
循环引用时,需向注明模块化管理系统循环引用的组件间的处理优先级: beforeCreate: function () {
this.$options.components.TreeFolderContents = require('./tree-folder-contents.vue').default
}

内联模板

如果子组件有 inline-template 特性,组件将把它的内容当作它的模板,而不是把它当作分发内容。这让模板更灵活,不推荐。

<my-component inline-template>
<div>
<p>These are compiled as the component's own template.</p>
<p>Not parent's transclusion content.</p>
</div>
</my-component>

模板x-template:

//x-template:
<script type="text/x-template" id="hello-world-template">
<p>Hello hello hello</p>
</script>
Vue.component('hello-world', {
template: '#hello-world-template'
})

v-once,缓存模板

Vue.component('terms-of-service', {
template: '\
<div v-once>\
<h1>Terms of Service</h1>\
... a lot of static content ...\
</div>\
'
})

 

vue-8-组件的更多相关文章

  1. vue.js组件化开发实践

    前言 公司目前制作一个H5活动,特别是有一定统一结构的活动,都要码一个重复的轮子.后来接到一个基于模板的活动设计系统的需求,便有了下面的内容.借油开车. 组件化 需求一到,接就是怎么实现,技术选型自然 ...

  2. 如何理解vue.js组件的作用域是独立的

    vue.js组件的作用域是独立,可以从以下三个方面理解: 1.父组件模板在父组件作用域内编译,父组件模板的数据用父组件内data数据:2.子组件模板在子组件作用域内编译,子组件模板的数据用子组件内da ...

  3. Vue 子组件向父组件传参

    直接上代码 <body> <div id="counter-event-example"> <p>{{ total }}</p> & ...

  4. VUE.JS组件化

    VUE.JS组件化 前言 公司目前制作一个H5活动,特别是有一定统一结构的活动,都要码一个重复的轮子.后来接到一个基于模板的活动设计系统的需求,便有了下面的内容.借油开车. 组件化 需求一到,接就是怎 ...

  5. Vue动态组件

    前面的话 让多个组件使用同一个挂载点,并动态切换,这就是动态组件.本文将详细介绍Vue动态组件 概述 通过使用保留的 <component> 元素,动态地绑定到它的 is 特性,可以实现动 ...

  6. vue中组件的四种方法总结

    希望对大家有用 全局组件的第一种写法 html: <div id = "app"> <show></show></div> js: ...

  7. 如何抽象一个 Vue 公共组件

    之前一直想写一篇关于抽象 Vue 组件的随笔,无奈一直没想到好的例子.恰巧最近为公司项目做了一个数字键盘的组件,于是就以这个为例聊聊如何抽象 Vue 的组件. 先上 Demo 与 源码.(demo最好 ...

  8. vue的组件和生命周期

    Vue里组件的通信 通信:传参.控制.数据共享(A操控B做一个事件) 模式:父子组件间.非父子组件 父组件可以将一条数据传递给子组件,这条数据可以是动态的,父组件的数据更改的时候,子组件接收的也会变化 ...

  9. 为什么VUE注册组件命名时不能用大写的?

    这段时间一直在弄vue,当然也遇到很多问题,这里就来跟大家分享一些注册自定义模板组件的心得 首先"VUE注册组件命名时不能用大写"其实这句话是不对的,但我们很多人开始都觉得是对的, ...

  10. vue的组件化运用(数据在两个组件互传,小问题总结)

    一.vue的组件化应用 首先,知道有哪些相关的属性需要用到,再慢慢去理解,运用. 1.两个vue页面 2. slot占位符(可用可不用) 3.props内置属性 4.watch监听函数 5.impor ...

随机推荐

  1. 协方差分析 | ANCOVA (Analysis of Covariance)

    If you are worried about leaving out covariates you could regress out them first and analyse the res ...

  2. mismatch详解

    mismatch到底只是一个碱基替换,还是也包括了插入缺失? If two sequences in an alignment share a common ancestor, mismatches ...

  3. javascript ----> Immediately-Invoked Function Expression (IIFE)(翻译)

    http://benalman.com/news/2010/11/immediately-invoked-function-expression/ 如果你没有注意到,我对术语有一点点坚持. 所以,在听 ...

  4. Python自学:第二章 修改字符串的大小写 titile.()、upper()、lower()

    title.():首字母大写 upper():全大写 lower():全小写 ada lovelace:人名,传控计算机创始人 name = "ada lovelace" prin ...

  5. 浅谈微服务架构、容器技术与K8S

    关注嘉为科技,获取运维新知 企业应用系统:从单体应用走向微服务架构:从裸金属走向容器. 如果在诸多热门云计算技术诸如容器.微服务.DevOps.OpenStack等之中,找出一个最火的方向,那么可能非 ...

  6. 数组方法map(映射),reduce(规约),foreach(遍历),filter(过滤)

    数组方法map(映射),reduce(规约),foreach(遍历),filter(过滤) map()方法返回一个由原数组中每一个元素调用一个指定方法后返回的新数组 reduce()方法接受一个函数作 ...

  7. Confluence 6 为一个空间应用一个主题

    主题允许你对 Confluence 的外表和显示进行自定义.你的 Confluence 空间管理员可以到 The Atlassian Marketplace 上下载主题. 一旦一个主题被安装到 Con ...

  8. Digital Deletions HDU - 1404

    Digital deletions is a two-player game. The rule of the game is as following. Begin by writing down ...

  9. python记录_day18 反射 判断函数与方法

    一.三个内置函数 1.issubclass(a, b)  判断a类是否是b类的子类 class Foo: pass class Zi(Foo): pass class Sun(Zi): pass pr ...

  10. sqlite3 删除数据

    cx = sqlite3.connect("c:/数据库地址") # 打开数据库cu = cx.cursor()# delete the rowcu.execute("d ...