因为组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,例如 data、computed、watch、methods 以及生命周期钩子等。仅有的例外是像 el 这样根实例特有的选项。

组件基础:

全局组件:可以在任何(根)实例中使用的组件;

局部组件:只能在某一实例中使用的组件:

一、定义全局组件和局部组件的两种方法:

方法一:定义一个全局组件和局部组件

全局组件:

let like = Vue.extend({
template: `
<div>
<h2>全局组件定义方法一</h2>
<p>全局组件定义方法一内容</p>
</div>
`
}); Vue.component('like-com', like);

局部组件:

let like = Vue.extend({
template: `
<div>
<h2>局部组件定义方法一</h2>
<p>局部组件定义方法一内容</p>
</div>
`
}); new Vue({
el: '#app1',
components: {
'like-com': like
}
});

方法二:定义一个全局组件和局部组件

全局组件:

    Vue.component('like', {
template: `
<div>
<h2>这是一个全局组件</h2>
<p>全局组件内容省略!</p>
</div>
`
});

局部组件:

    new Vue({
el: '#app1',
components: {
'love': {
template: `
<div>
<h2>这是一个局部组件</h2>
<p>布局组件内容同样省略!</p>
</div>
`
}
}
});

方法三、使用template定义

<div id="app1">
<my-love></my-love>
</div> <template id="temp-com">
<div>
<h3>使用template定义的组件</h3>
<p>使用template定义的组件的内容!</p>
</div>
</template>

Vue.component('my-love', {
template: '#temp-com'
});

方法四、使用script定义

<div id="app1">
<my-love></my-love>
</div> <script type="text/template" id="temp-com">
<div>
<h3>使用template定义的组件</h3>
<p>使用template定义的组件的内容!</p>
</div>
</script>

Vue.component('my-love', {
template: '#temp-com'
});

方法五:在模块系统中局部注册

你使用了诸如 Babel 和 webpack 的模块系统。在这些情况下,我们推荐创建一个 components 目录,并将每个组件放置在其各自的文件中。

然后你需要在局部注册之前导入每个你想使用的组件。例如,在一个假设的 ComponentB.js 或 ComponentB.vue 文件中:

import ComponentA from './ComponentA'
import ComponentC from './ComponentC' export default {
components: {
ComponentA,
ComponentC
},
// ...
}

现在 ComponentA 和 ComponentC 都可以在 ComponentB 的模板中使用了。

二、父子组件:

let child1 = Vue.extend({
template: `
<p>子组件child1</p>
`
}); let child2 = Vue.extend({
template: `
<p>子组件child2</p>
`
}); Vue.component('like', {
components: {
'child-com1': child1,
'child-com2': child2
},
template: `
<div>
<child-com1></child-com1>
<child-com2></child-com2>
</div>
`
});

let child1 = Vue.extend({
template: `
<p>子组件child1</p>
`
}); let child2 = Vue.extend({
template: `
<p>子组件child2</p>
`
}); new Vue({
el: '#app1',
components: {
'child-app1': {
components: {
'child-com1': child1,
'child-com2': child2
},
template: `
<div>
<child-com1></child-com1>
<child-com2></child-com2>
</div>
`
}
}
});

三、父子组件通信:从父到子,用props属性绑定

<div id="app">
<my-comp :username="nickname"></my-comp>
</div>

Vue.component('my-comp', {
props: ['username'],
template: '<h3>{{ username }}</h3>'
}); new Vue({
el: '#app',
data: {
nickname: '小七'
}
})

五、平行组件传递数据:用空实例搭建桥梁

<div id="app">
<huahua></huahua>
<shuangdan></shuangdan>
</div>

    var Event = new Vue();

    Vue.component('huahua', {
template: `
<div>我说: <input type="text" @keyup="on_change" v-model="i_said"/></div>
`,
methods: {
on_change: function(){
Event.$emit('huahua-said-something', this.i_said);
}
},
data: function(){
return {
i_said: ''
}
}
}) Vue.component('shuangdan', {
template: '<div>花花说:{{huahua_said}}</div>',
data: function(){
return {
huahua_said: ''
}
},
mounted: function(){
var me = this;
Event.$on('huahua-said-something', function(data){
me.huahua_said = data;
})
}
}) new Vue({
el: '#app'
})

六、prop:

1、在 JavaScript 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变这个对象或数组本身将会影响到父组件的状态。

2、prop 会在一个组件实例创建之前进行验证,所以实例的属性 (如 data、computed 等) 在 default 或 validator 函数中是不可用的。

七、is:

解析 DOM 模板时的注意事项

有些 HTML 元素,诸如 <ul>、<ol>、<table> 和 <select>,对于哪些元素可以出现在其内部是有严格限制的。而有些元素,诸如 <li>、<tr> 和 <option>,只能出现在其它某些特定的元素内部。

这会导致我们使用这些有约束条件的元素时遇到一些问题。例如:

<table>
<blog-post-row></blog-post-row>
</table>

这个自定义组件 <blog-post-row> 会被作为无效的内容提升到外部,并导致最终渲染结果出错。幸好这个特殊的 is 特性给了我们一个变通的办法:

<table>
<tr is="blog-post-row"></tr>
</table>

再比如:

// ul下使用组件
<ul>
<li is="component-name"></li>
</ul>

//声明一个组件
new Vue({
components:{
'component-name':{
template:'<p>你好,这是一个示例</p>'
}
}
})

八、动态组件:使用:is在不同组件之间进行动态切换:

让多个组件使用同一个挂载点,并动态切换,这就是动态组件。通过 Vue 的 <component> 元素加一个特殊的 is 特性来实现。

    <style>
.tab-button {
padding: 6px 10px;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
border: 1px solid #ccc;
cursor: pointer;
background: #f0f0f0;
margin-bottom: -1px;
margin-right: -1px;
}
.tab-button:hover {
background: #e0e0e0;
}
.tab-button.active {
background: #e0e0e0;
}
.tab {
border: 1px solid #ccc;
padding: 10px;
}
</style>

    <button v-for="tab in tabs" @click="current_tab = tab" :class="['tab-button', {'ctive': current_tab === tab}]">{{tab}}</button>
<component :is="get_current_tab" class="tab"></component>

Vue.component('tab_home', {
template: `<div>Home component</div>`
}); Vue.component('tab_posts', {
template: `<div>Posts component</div>`
}); Vue.component('tab_archive', {
template: `<div>Archive component</div>`
}); var vm = new Vue({
el: '#app',
data: {
current_tab: 'Home',
tabs: ['Home', 'Posts', 'Archive']
},
computed: {
get_current_tab(){
return 'tab_' + this.current_tab.toLowerCase();
}
}
});

示例:

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<component :is="currentTab"></component>
<button @click="change">切换组件</button>
</div> <script src="https://cdn.bootcss.com/vue/2.5.17-beta.0/vue.js"></script>
<script>
let home = {template: "<h1>我是主页</h1>"};
let post = {template: "<h2>我是提交页</h2>"};
let archive = {template: "<h3>我是存档页</h3>"}; let vm = new Vue({
el: '#app',
data: {
index: 0,
tabs: ['home', 'post', 'archive']
},
computed: {
currentTab: function(){
return this.tabs[this.index];
}
},
methods: {
change: function(){
this.index = (++this.index)%3;
}
},
components: {
home,
post,
archive
}
});
</script>
</body>
</html>

也可以直接绑定到组件对象上:

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<component :is="currentTab"></component>
<button @click="change">切换组件</button>
</div> <script src="https://cdn.bootcss.com/vue/2.5.17-beta.0/vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
data: {
index: 0,
tabs: [
{
template: '<h1>我是主页</h1>'
},
{
template: '<h2>我是提交页</h2>'
},
{
template: '<h3>我是存档页</h3>'
}
]
},
computed: {
currentTab: function(){
return this.tabs[this.index];
}
},
methods: {
change: function(){
this.index = (++this.index)%3;
}
}
});
</script>
</body>
</html>

Vue.component('tab-home', {
template: '<div>Home component</div>'
})
Vue.component('tab-posts', {
template: '<div>Posts component</div>'
})
Vue.component('tab-archive', {
template: '<div>Archive component</div>'
}) new Vue({
el: '#dynamic-component-demo',
data: {
currentTab: 'Home',
tabs: ['Home', 'Posts', 'Archive']
},
computed: {
currentTabComponent: function () {
return 'tab-' + this.currentTab.toLowerCase()
}
}
})

  <component
v-bind:is="currentTabComponent"
class="tab"
></component>

九、在动态组件上使用 keep-alive:

重新创建动态组件的行为通常是非常有用的,但是在有些应用中,我们更希望那些标签的组件实例能够被在它们第一次被创建的时候缓存下来。为了解决这个问题,我们可以用一个 <keep-alive> 元素将其动态组件包裹起来。

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<keep-alive>
<component :is="currentTab"></component>
</keep-alive>
<button @click="change">切换组件</button>
</div> <script src="https://cdn.bootcss.com/vue/2.5.17-beta.0/vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
data: {
index: 0,
tabs: [
{
template: '<h1>我是主页</h1>'
},
{
template: '<h2>我是提交页</h2>'
},
{
template: '<h3>我是存档页</h3>'
}
]
},
computed: {
currentTab: function(){
return this.tabs[this.index];
}
},
methods: {
change: function(){
let len = this.tabs.length;
this.index = (++this.index)%len;
}
}
});
</script>
</body>
</html>

条件判断:

如果有多个条件性的子元素,<keep-alive> 要求同时只有一个子元素被渲染。

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<keep-alive>
<home v-if="index===0"></home>
<posts v-else-if="index===1"></posts>
<archive v-else></archive>
</keep-alive>
<button @click="change">切换组件</button>
</div> <script src="https://cdn.bootcss.com/vue/2.5.17-beta.0/vue.js"></script>
<script>
let vm = new Vue({
el: '#app',
data: {
index: 0,
},
components:{
home:{template:`<div>我是主页</div>`},
posts:{template:`<div>我是提交页</div>`},
archive:{template:`<div>我是存档页</div>`},
},
computed: {
currentTab: function(){
return this.tabs[this.index];
}
},
methods: {
change: function(){
let len = Object.keys(this.$options.components).length;//获取组件的个数
this.index = (++this.index)%len;
}
}
});
</script>
</body>
</html>

十、异步组件:

vue开发过程中,我们会做出特别多特别多的组件,包括login,header,footer,main等等。

这样使整个网站看起来就十分的庞大,当我们在打开网页的时候,突然一下子把这些所有的组件加载上来,这么多的请求全部同时开始请求,势必会造成网页打开很慢,使客户得到的是非常差劲的体验。

因此,vue为我们专门设立了异步组件,通过异步组件,我们可以得到两点好处:

1、用不到的组件不会加载,因此网页打开速度会很快,当你用到这个组件的时候,才会通过异步请求进行加载;

2、缓存组件,通过异步加载的组件会缓存起来,当你下一次再用到这个组件时,丝毫不会有任何的疑迟,组件很快会从缓存中加载出来。

为了简化,Vue 允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义。Vue 只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染。例如:

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<async-example></async-example>
</div> <script src="https://cdn.bootcss.com/vue/2.5.17-beta.0/vue.js"></script>
<script>
Vue.component('async-example', function (resolve, reject) {
setTimeout(function () {
// 向 `resolve` 回调传递组件定义
resolve({
template: '<div>I am async!</div>'
})
}, 2000)
}); let vm = new Vue({
el: '#app',
data: {
index: 0,
}
});
</script>
</body>
</html>

如你所见,这个工厂函数会收到一个 resolve 回调,这个回调函数会在你从服务器得到组件定义的时候被调用。你也可以调用 reject(reason) 来表示加载失败。这里的 setTimeout 是为了演示用的,如何获取组件取决于你自己。

一个推荐的做法是将异步组件和 webpack 的 code-splitting 功能一起配合使用:

Vue.component('async-webpack-example', function (resolve) {
// 这个特殊的 `require` 语法将会告诉 webpack
// 自动将你的构建代码切割成多个包,这些包
// 会通过 Ajax 请求加载
require(['./my-async-component'], resolve)
})

实例1:

假如你写一个test.vue文件,在<script>标签里,实际使用方法如下:

//test.vue的部分
<script>
import Vue from 'vue' //关键是以下这部分代码
//需要将引入的异步组件,赋值给变量searchSearch
//然后在下方components对象里,将变量正常添加进去,就可以使用异步组件了
//第一个参数是组件名,第二个是异步引入的方法
const searchSearch = Vue.component('searchSearch', function (resolve) {
require(['./service-search.vue'], resolve)
}) export default{
data(){
return {}
},
methods: {},
components: {
searchSearch: searchSearch
}
}
</script>

更简单的异步组件的使用方法:

<script>
export default{
data(){
return {}
},
methods: {},
components: {
searchSearch: function (resolve) {
//异步组件写法
require(['./service-search.vue'], resolve)
}
}
}
</script>

可以用到异步组件的地方:

1、组件中,组件中需要子组件的位置,我们就可以使用异步组件形式;

2、路由中,一般我们打开一个页面时,其总是会进入其中一个默认的路由,那么其他路由在用不到的时候就没必要继续加载,当跳转到当前路由的时候,再来加载,这里也是使用异步组件非常恰当的地方。

十一、在组件上使用 v-model:

<custom-input v-model="searchText"></custom-input>
<span>{{searchText}}</span>

Vue.component('custom-input', {
template: `<div><input :value="value" @input="$emit('input', $event.target.value)"/></div>`,
props: ['value']
}); new Vue({
el:"#app",
data:{
searchText: 'hello'
}
});

这里的 searchText 的值将会传入这个名为 value的 prop。同时当 <custom-input> 触发一个 input 事件并附带一个新的值的时候,这个 searchText 的属性将会被更新。

vue之component的更多相关文章

  1. 前端性能优化成神之路--vue组件懒加载(Vue Lazy Component )

    ---恢复内容开始--- 使用组件懒加载的原因 我们先来看看这样的一个页面,页面由大量模块组成,所有模块是同时进行加载,模块中图片内容较多,每个模块的依赖资源较多(包括js文件.接口文件.css文件等 ...

  2. Vue dynamic component All In One

    Vue dynamic component All In One Vue 动态组件 vue 2.x https://vuejs.org/v2/guide/components-dynamic-asyn ...

  3. vue & child component & props

    vue & child component & props vue pass data to child component https://vuejs.org/v2/guide/co ...

  4. Vue.js——component(组件)

    概念: 组件(Component)是自定义元素. 作用: 可以扩展HTML元素,封装可重用的代码. <div id="myView"> <!-- 把学生的数据循环 ...

  5. vue19 组建 Vue.extend component、组件模版、动态组件

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. [Vue] Use Vue.js Component Computed Properties

    You can add computed properties to a component to calculate a property on the fly. The benefit of th ...

  7. [Vue] Import component into page

    Components are one of the most powerful features of Vue. Let's take a look at how to write our first ...

  8. Vue组件component创建及使用

    组件化与模块化的区别 什么是组件:组件的出现,就是为了拆分Vue实例的代码量,能够让我们以不同的组件,来划分不同的功能模块 ,将来我们需要什么功能,就可以去调用对应的组件即可 组件化与模块化的不同: ...

  9. 怎样在 Vue 的 component 组件中使用 props ?

    1. 在注册一个组件时, 添加一个 props 属性, 将需要添加的 props 作为数组的元素进行添加, 比如下面的例子中, 我们添加了一个变量 name , 他就是一个 props, 我们可以通过 ...

随机推荐

  1. 帝国cms搜索关键字调用标签(showsearch)怎么用

    前面ytkah介绍了如何让帝国CMS7.2搜索模板支持动态标签调用,现在我们来说说怎么调用帝国cms搜索关键字调用标签(showsearch).在帝国cms后台那边的使用方法:[showsearch] ...

  2. 报错解决——-bash: wget: command not found

    本人用的是Mac本,在Mac中install的时候经常会用到wget,但是事先没有安装wget的话就会报上面的错误,解决方法就是安装wget. 安装wget 方法一:用传统的安装包方式安装 A - 从 ...

  3. SELinux介绍

    SELinux概念 安全加强的Linux,早期的Linux系统安全由系统管理员控制.SELinux就是一些安全规则的集合,类似于人类生活中的法律. DAC:   自由访问控制(以前的linux版本) ...

  4. 爆破root密码hash John the Ripper和hydra爆破ssh密码

    官方网站:http://www.openwall.com/john/ 下载:wget http://www.openwall.com/john/j/john-1.8.0.tar.gz 解压:tar - ...

  5. IPFS私链搭建及常用操作命令

    1. 共享密钥 同一个IPFS私链内的所有节点必须共享同一个密钥才能加入. 首先我们使用密钥创建工具,创建一个密钥. 下载地址:https://github.com/Kubuxu/go-ipfs-sw ...

  6. pd.concat/merge/join

    pandas的拼接分为两种: 级联:pd.concat, pd.append 合并:pd.merge, pd.join 一.回顾numpy.concatenate 生成1个6*3的矩阵,一个2*3的矩 ...

  7. Hinge Loss、交叉熵损失、平方损失、指数损失、对数损失、0-1损失、绝对值损失

    损失函数(Loss function)是用来估量你模型的预测值 f(x) 与真实值 Y 的不一致程度,它是一个非负实值函数,通常用 L(Y,f(x)) 来表示.损失函数越小,模型的鲁棒性就越好. 损失 ...

  8. Go linux 实践4

    这是目前学习的最难的Go demo例子 ***************************************** 如果能看懂,你就出师了,我的任务也就结束了 **************** ...

  9. 44.JS--hover事件防重复效果

    遇到一种情况,就是运用hover事件的时候,会出现对象(主要是图片)闪动现象.主要是由于hover事件重复触发导致这一现象. html: <p class="smallImg" ...

  10. CSU 1849 Comparing answers(数学矩阵)

    Comparing answers 离散数学真的要好好学啊:一个邻接矩阵(这个矩阵一定是n×n的方阵,n是图的节点个数),表示的是从i到j有几条通路的时候,矩阵的1次方就代表从从i到j长度为1的路径通 ...