Skip to content

组件 #3

@Wscats

Description

@Wscats

全局注册组件

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 传递数据。另外,在子组件中修改父组件的状态是非常糟糕的做法

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions