参考Vue实战、官网
一、组件基础
1、组件概念
实现代码最高的复用性。引入了组件的概念。
2、基本使用
与指令、过滤器类似,需要注册后使用。同样注册有全局注册和局部注册两种。全局注册后任何Vue示例都可以使用。示例如下:
<body>
<script src="./vue.js"></script>
<!-- 使用组件 -->
<div id="app">
<my-component></my-component>
</div>
<script>
// 注册一个全局组件,第一个参数是标签名
Vue.component("my-component",{
template:`<div>全局组件</div>`
});
// 创建实例
var app = new Vue({
el:"#app",
});
//说明:
// template 必须是DOM结构
</script>
</body>
3、HTML限制
Vue组件模板可能会受到HTML限制,如
标签只允许等表格标签。这时直接使用组件是无效的。 |
这是可以使用is属性来挂载组件。示例如下:
<table>
<tbody is="my-component"></tbody>
</table>
tbody 在渲染时,会被替换为组件的内容。常见的限制元素还有
-
、
- 、。
4、数据选项
- data必须被定义为一个函数。
- data函数的返回值为一个对象
示例:
<body>
<script src="./vue.js"></script>
<!-- 使用组件 -->
<div id="app">
<my-component></my-component>
<my-component></my-component>
<my-component></my-component>
</div>
<script>
// 注册一个全局组件,第一个参数是标签名
Vue.component("my-component",{
template:`<button @click="counter++">{{counter}}</button>`,
data: function(){
return {counter:0};
}
});
// 创建实例
var app = new Vue({
el:"#app",
});
//说明:
// data必须被定义为一个函数。
// data函数的返回值为一个对象
</script>
</body>
二、props传递数据
1、基本使用
1)基本示例
父组件
向子组件
正向传递数据的过程通过props来实现。props的取值可以是字符串数组或者对象。
示例如下:
<body>
<script src="./vue.js"></script>
<div id="app">
<my-component message="来自父组件的数据"></my-component>
</div>
<script>
Vue.component("my-component",{
template:`<div>{{message}}</div>`,
props:['message'],
});
var app = new Vue({
el:"#app",
});
</script>
</body>
渲染结果为:
<div id="app"><div>来自父组件的数据</div></div>
2)注意事项
由于HTML特性不区分大小写,当使用DOM模板时,驼峰命名的props名称要转为短横杠命名。
props:["warningText"]
<my-component warning-text="提示信息"></my-component>
如果使用的是字符串模板可以忽略这些限制。
3)动态props
来自父组件的动态数据可以使用指令v-bind
来动态绑定props的值。
示例:使用v-model绑定数据。父组件的数据子组件实时响应并更新模板。
<body>
<script src="./vue.js"></script>
<div id="app">
<input type="text" v-model="parentMessage">
<my-component :message="parentMessage"></my-component>
</div>
<script>
Vue.component("my-component",{
template:`<div>{{message}}</div>`,
props:['message'],
});
var app = new Vue({
el:"#app",
data:{
parentMessage:"",
}
});
</script>
</body>
2、单向数据流
略。
3、数据验证
对props传入的类型进行检查。
三、子组件与父组件通信
- 子组件向父组件通过自定义事件通信。
- 子组件使用
$emit()
来触发事件,父组件用$on()
来监听子组件的事件。 - 父组件也可以直接在子组件的自定义标签上使用v-on来监听子组件触发的自定义事件。
1、v-on监听子组件
如果子组件$emit()触发的是一个自定义事件,那么父组件只能使用v-on监听。
示例:
<body>
<script src="./vue.js"></script>
<div id="app">
<p>总数:{{ total }}</p>
<my-component @increase="handleGetTotal" @reduce="handleGetTotal">
</my-component>
</div>
<script>
Vue.component("my-component", {
template: `
<div>
<button @click="handleIncrease">+1</button>
<button @click="handleReduce">-1</button>
</div>
`,
data: function () {
return {
counter: 0,
}
},
methods: {
handleIncrease: function () {
this.counter++;
this.$emit('increase', this.counter);
},
handleReduce: function () {
this.counter--;
this.$emit('reduce', this.counter);
}
}
});
var app = new Vue({
el: "#app",
data: {
total: 0,
},
methods: {
handleGetTotal: function (total) {
this.total = total;
}
}
});
</script>
</body>
渲染结果:
<div id="app"><p>总数:-3</p> <div><button>+1</button> <button>-1</button></div></div>
2、v-model监听子组件
如果子组件$emit()触发的是一个特殊的事件名input
,那么父组件就可以使用v-model监听。
示例:
<body>
<script src="./vue.js"></script>
<div id="app">
<p>总数:{{ total }}</p>
<my-component v-model="total">
</my-component>
</div>
<script>
Vue.component("my-component", {
template: `
<div>
<button @click="handleIncrease">+1</button>
<button @click="handleReduce">-1</button>
</div>
`,
data: function () {
return {
counter: 0,
}
},
methods: {
handleIncrease: function () {
this.counter++;
this.$emit('input', this.counter);
},
handleReduce: function () {
this.counter--;
this.$emit('input', this.counter);
}
}
});
var app = new Vue({
el: "#app",
data: {
total: 0,
},
methods: {
handleGetTotal: function (total) {
this.total = total;
}
}
});
</script>
</body>
四、非父子组件通信
1、利用中央事件总线bus
起两个组件中介的作用。
示例:
<body>
<script src="./vue.js"></script>
<div id="app">
{{ message }}
<component-a></component-a>
</div>
<script>
var bus = new Vue();
Vue.component("component-a", {
template: `<button @click="handleEvent">传递事件</button>`,
methods: {
handleEvent: function () {
bus.$emit('on-message', '来自组件component-a的内容');
},
}
});
var app = new Vue({
el: "#app",
data: {
message: '',
},
mounted () {
var _this = this;
bus.$on('on-message',function(msg){
_this.message = msg;
});
}
});
</script>
</body>
2、父链
3、子组件索引
五、插槽slot
1、作用域
1)showChild 绑定的是父组件的数据 。
<body>
<script src="./vue.js"></script>
<div id="app">
<child-component v-show="showChild"></child-component>
</div>
<script>
Vue.component('child-component',{
template:`<div>子组件</div>`
});
var app = new Vue({
el:'#app',
data:{
showChild:true
}
});
</script>
</body>
2)showChild 绑定的是子组件的数据
<body>
<script src="./vue.js"></script>
<div id="app">
<child-component></child-component>
</div>
<script>
Vue.component('child-component',{
template:`<div v-show="showChild">子组件</div>`
});
var app = new Vue({
el:'#app',
data:{
showChild:true
}
});
</script>
</body>
2、slot用法
1)单个Slot
在子组件内使用特殊的元素就可以为这个子组件开启一个slot(插槽),在父组件模板里,插入在子组件标签内的所有内容将替换子组件的标签即它的内容。
示例:
<body>
<script src="./vue.js"></script>
<div id="app">
<child-component>
<p>分发的内容</p>
<p>更多分发的内容</p>
</child-component>
</div>
<script>
Vue.component('child-component', {
template: `
<div>
<slot>
<p>如果父组件没有插入内容,我将作为默认出现</p>
</slot>
</div>`,
});
var app = new Vue({
el: '#app',
});
</script>
</body>
2)具名slot
给元素指定一个name后,可以分发多个内容,具名slot可以与单个slot共存。
示例:
<body>
<script src="./vue.js"></script>
<div id="app">
<child-component>
<h2 slot="header">标题</h2>
<p>分发的内容</p>
<p>更多分发的内容</p>
<div slot="footer">底部信息</div>
</child-component>
</div>
<script>
Vue.component('child-component', {
template: `
<div class="container">
<div class="header">
<slot name="header"></slot>
</div>
<div class="main">
<slot></slot>
</div>
<div class="footer">
<slot name="footer"></slot>
</div>
</div>`,
});
var app = new Vue({
el: '#app',
});
</script>
</body>
3、作用域插槽
作用域插槽是一种特殊的slot,使用一个可以复用的模板替换已渲染元素。示例:
<body>
<script src="./vue.js"></script>
<div id="app">
<child-component>
<template scope="props">
<p>来自父组件的内容</p>
<p>{{ props.msg }}</p>
</template>
</child-component>
</div>
<script>
Vue.component('child-component', {
template: `
<div class="container">
<slot msg="来自子组件的内容"></slot>
</div>`,
});
var app = new Vue({
el: '#app',
});
</script>
</body>
作用域插槽更具代表性的用例是列表组件,允许组件自定义应该如何渲染列表的每一项。
4、访问slot
略。
六、组件高级用法
1、递归组件
2、内联模板
3、动态组件
4、异步组件
最新的笔记更新在:
https://github.com/1097364388/learning
<全文结束>