1.组件注册
因为组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,例如 data、computed、watch、methods 以及生命周期钩子等。仅有的例外是像 el 这样根实例特有的选项。
1.1全局组件注册
注册全局组件—全局化组件应放在实例之前。
全局组件可以放在所有的vue实例中。
注册一个全局组件语法格式如下:
和 并不是一个组件,它们仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。
Vue.component(tagName, options)
tagName 为组件名,options 为配置选项。注册后,我们可以使用以下方式来调用组件:
<tagName></tagName>
Vue.component('child', {
// 声明 props
props: ['message'],
// 就像 data 一样,prop 可以用在模板内
// 同样也可以在 vm 实例中像 “this.message” 这样使用
template: '<span>{{ message }}</span>'
})
1.2注册局部组件
<div id="example">
<child message="hello!"></child>
</div>
<script type="text/javascript">
new Vue({
el: '#example',
components: {
child: {
props: ['message'],
template: '<span>{{ message }}</span>'
}
}
})
</script>
1.3属性驼峰式变化
HTML 特性不区分大小写。当使用非字符串模版时,名字形式为 camelCase 的 prop 用作特性时,需要转为 kebab-case(短横线隔开):
Vue.component('child', {
// camelCase in JavaScript
props: ['myMessage'],
template: '<span>{{ myMessage }}</span>'
})
<!-- kebab-case in HTML -->
<child my-message="hello!"></child>
注意事件名不遵从驼峰式变化:
<my-component v-on:myevent ="functionName"></my-component>
this.$emit('myEvent');
1.4字面量语法
因为它是一个字面 prop ,它的值以字符串 “1” 而不是以实际的数字传下去。如果想传递一个实际的 JavaScript 数字,需要使用 v-bind ,从而让它的值被当作 JavaScript 表达式计算:
<!-- 传递实际的数字 -->
<comp v-bind:some-prop="1"></comp>
<comp :some-prop="[1,2,3]"></comp>
1.5动态props
类似于用 v-bind 绑定 HTML 特性到一个表达式,也可以用 v-bind 绑定动态 props 到父组件的数据。每当父组件的数据变化时,也会传导给子组件:
<div id="example">
<div>
<input v-model="parentMsg">
<br>
<child v-bind:my-message="parentMsg"></child>
<!-- <child :my-message="parentMsg"></child>-->
</div>
</div>
<script type="text/javascript">
new Vue({
el: '#example',
data: {
parentMsg: 'Message from parent'
},
components: {
child: {
props: ['myMessage'],
template: '<span>{{myMessage}}</span>'
}
}
})
</script>
2.父子组件props down, events up
在 Vue.js 中,父子组件的关系可以总结为 props down, events up 。父组件通过 props 向下传递数据给子组件,子组件通过 events 给父组件发送消息。
3.父组件到子组件
在子组件标签上绑定自定义属性,值为父组件数据属性
4.子组件到父组件
在子组件标签上绑定自定义事件,值为父组件函数
子组件内自定义事件通过this.$emit(‘事件名’,val)来触发
5.实例
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
#parent{border: 1px solid red;}
#child{border: 5px solid orange;}
</style>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="app">
</div>
<script type="text/javascript">
Vue.component('Child', { //001全局组件的声明与挂载
data() {
return {
msg: 'this is child message'
}
},
props: ['childData'],
methods:{
sendToParant($event){
this.msg=$event.target.value;
this.$emit('toParent',this.msg);
}
},
template: `<div id='child'>
<h2>父到子传递来的数据:{{childData}}</h2>
<input type='text' v-model='childData'/>
<h2>子到父传递来的数据:</h2>
<input type='text' v-on:input='sendToParant($event)'/>
</div>`
}
);
Vue.component('Parent', { //001全局组件的声明与挂载
data() {
return {
msg: 'this is parent message',
msg2: '',
msg3:''
}
},
template: `<div id='parent'>
<h2>父组件数据:{{msg}}</h2>
<button @click='send'>父向子通信</button>
<Child :childData='msg2' @toParent='childHandler'/>
<h2> 子到父传递来的数据:{{msg3}} </h2>
</div>`,
methods: {
send() {
this.msg2 = this.msg;
},
childHandler(val){
console.log(val);
this.msg3=val;
}
}
});
//1.声明局部组件
var AppName = {
data: function() {
return {
msg: 'component msg',
isShow: 'show'
}
},
//03.使用
template: `<div>
<Parent/>
</div>`
}
var vm = new Vue({
el: '#app',
data() {
return {
}
},
//2.局部组件的挂载
components: {
AppName
},
//优先加载template,3.局部组件的使用
template: `<div>
<app-name></app-name>
</div>`
});
console.log(vm);
</script>
</body>
</html>
单向数据流
注意:
(1)prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。
(2)在 JavaScript 中对象和数组是引用类型,指向同一个内存空间,如果 prop 是一个对象或数组,在子组件内部改变它会影响父组件的状态。
购物车中数量按钮参照地址:https://c.runoob.com/codedemo/5353