-
Notifications
You must be signed in to change notification settings - Fork 137
Description
全局注册组件
Vue中的组件可以扩展 HTML 元素,封装可重用的代码,是Vue重要的一部分
//定义组件
var wsscat = Vue.extend({
template: "<div>I am wsscat</div>"
})
//注册组件
Vue.component('wsscat', wsscat)
var demo = new Vue({
el: '#demo',
data: {
name: 'wsscat',
}
})
这里注意的是extend和component方法要放在new Vue()之前,不然会报错
局部注册组件
当我们全局注册组件的时候,该组件在任何地方使用,我们也可以局部注册组件,就是在父组件定义即extend时候跟着注册子组件,那么该子组件就只能在父组件中使用
<body id="demo">
{{name}}
<wsscat>
<!--写在里面会被替换掉-->
<!--<wsscat-child></wsscat-child>
<wsscat-Child-Second></wsscat-Child-Second>-->
</wsscat>
</body>
<script>
var wsscatChild = Vue.extend({
template: "<p>I'm child</p>"
})
var wsscatChildSecond = Vue.extend({
template: "<span>I'm child2</span>"
})
//定义组件
var wsscat = Vue.extend({
template: "<div>I'm wsscat<wsscat-child></wsscat-child><wsscat-Child-Second></wsscat-Child-Second></div>",
replace: true,
components: {
//也可以这样写wsscatChild
'wsscatChild': wsscatChild,
'wsscatChildSecond': wsscatChildSecond
}
})
//注册组件
Vue.component('wsscat', wsscat)
var demo = new Vue({
el: '#demo',
data: {
name: 'wsscat',
}
})
</script>
注意下面两种写法等价,当键值对都是同一个的时候就可以这样写
components: {
wsscatChild: 'wsscatChild'
}
components: {
wsscatChild
}
局部注册中定义组件并使用
下面我们就把wsscatChildThird放在wsscat这个组件定义的时候定义并注册使用
var wsscatChild = Vue.extend({
template: "<p>I'm child</p>"
})
var wsscatChildSecond = Vue.extend({
template: "<p>I'm child2</p>"
})
//定义组件
var wsscat = Vue.extend({
template: "<div>I'm wsscat<wsscat-child></wsscat-child><wsscat-Child-Second></wsscat-Child-Second><wsscat-child-third></wsscat-child-third></div>",
replace: true,
components: {
//也可以这样写wsscatChild
'wsscatChild': wsscatChild,
'wsscatChildSecond': wsscatChildSecond,
'wsscatChildThird': {
template: "<p>I'm child3</p>"
}
}
})
编写模版
我们可以用script标签设置type="text/template",并且给一个id名
<script type="text/template" id="tpl">
<div>Hello {{name}}</div>
</script>
或者我们还可以用template标签定义这个模版
<template id="tpl">
<div>Hello {{name}}</div>
</template>
我们就可以在template属性绑定id名,就可以读取上面的模版
var wsscat = Vue.extend({
template: '#tpl',
data: function() {
return {
name: 'Wsscat'
}
}
})
组件中传递数据
在组件中我们可以在定义的时候用data属性绑定数据到模版上
注意这里我们使用函数返回一个对象把数据定义出来的
var wsscatChildSecond = Vue.extend({
template: "<p>I'm child2, I like {{skill}}</p>",
data: function() {
return {
skill: "javascript"
}
}
})
组件接收组件外的数据
我们可以用props获取组件所在id="demo"这个作用域下定义的name数值,由于组件wsscat中的name和id=demo的name是互不影响的,所以我们可以用这样的方法把name传进去给wsscat这个组件
var wsscat = Vue.extend({
template: '#tpl',
props:['msg'],
data: function() {
return {
name: 'Wsscat'
}
}
})
// 注册
Vue.component('wsscat', wsscat)
new Vue({
el: '#demo',
data: {
name: 'wsscats'
}
})
视图,记得msg这个属性前面要加上个冒号,其实就是等同于v-bind:msg
缩写为:msg
<div id="demo">
<wsscat :msg="name"></wsscat>
</div>
<script type="text/template" id="tpl">
<div>Hello {{name}}</div>
<div>{{msg}}</div>
</script>
父组件向子组件传递数据
我们只需要在子组件中加一个props属性,props属性接受一个数组,接受子组件标签上的属性,因为子组件上的属性父组件是可以控制的,我们就可以在子组件中获取到父组件的数据
例如下面<wsscat-child :test='sweet'></wsscat-child>
:test
相当于v-bind:test
加了冒号父组件的数据就会与子组件的数据实现双向数据绑定,当然父组件能控制子组件的值,但是子组件却不能影响父组件的值
var wsscat = Vue.extend({
template: "<input v-model='sweet' /><div>I'm wsscat<wsscat-child :test='sweet'></wsscat-child><wsscat-Child-Second></wsscat-Child-Second><wsscat-child-third></wsscat-child-third></div>",
data:function(){
return {
sweet:"你好",
}
},
replace:true,
components: {
//也可以这样写wsscatChild
'wsscatChild': wsscatChild,
'wsscatChildSecond': wsscatChildSecond,
'wsscatChildThird': {
template:"<p>I'm child3</p>"
}
}
})
v-bind:test``:test
默认单项绑定,父能影响子,子不能影响父v-bind:test.sync``:test.sync
父子互相能影响v-bind:test.once``:test.once
除了第一次赋值,父子互不影响
子组件可以用 this.$parent 访问它的父组件。根实例的后代可以用 this.$root 访问它。
参考文档
例如我们在第一个子组件wsscatChild的ready属性中添加函数,输出this.$parent,就可以在this.$parent.$data中看到父组件wsscat的name值
var wsscatChild = Vue.extend({
props: ['test'],
ready: function() {
console.log(this.$parent);
},
template: "<p>I'm child, {{test}}</p><input v-model='test' />"
})
尽管可以访问父链上任意的实例,不过子组件应当避免直接依赖父组件的数据,尽量显式地使用 props 传递数据。另外,在子组件中修改父组件的状态是非常糟糕的做法