1.组件注册
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>
</div>
<script src="../vue.js"></script>
<script>
Vue.component('button-counter', {
data: function() {
return {
count: 0
}
},
template: '<button @click="handle()" @keyup.enter="handle">点击了{{count}}次</button>',
methods: {
handle() {
this.count++;
}
}
});
//组件注册
var vm = new Vue({
el: '#app',
data: {
}
})
</script>
</body>
</html>
2.组件注册的注意事项
1. data必须是一个函数⚫分析函数与普通对象的对比
2. 组件模板内容必须是单个根元素⚫分析演示实际的效果
3. 组件模板内容可以是模板字符串⚫模板字符串需要浏览器提供支持(ES6语法)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<button-template></button-template>
<button-template></button-template>
<button-template></button-template>
</div>
<script src="../vue.js"></script>
<script>
//
/* 1. data必须是一个函数⚫分析函数与普通对象的对比
2. 组件模板内容必须是单个根元素⚫分析演示实际的效果
3. 组件模板内容可以是模板字符串⚫模板字符串需要浏览器提供支持(ES6语法)
*/
/* Vue.component("button-template", {
data: function() {
return {
count: 0,
}
},
template: "<button @click.prevent='handle'>点击了{{count}}次</button>",
methods: {
handle() {
this.count++
}
},
}) */
// ---------------------------------------
Vue.component("button-template", {
data: function() {
return {
count: 0,
}
},
template: `<div>
<button @click.prevent='handle'>点击了{{count}}次</button>
<button>测试</button>
</div>`,
methods: {
handle() {
this.count++
}
},
})
var vm = new Vue({
el: '#app',
data: {}
})
</script>
</body>
</html>
3.组件注册命名方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<button-template></button-template>
<button-template></button-template>
<button-template></button-template>
<hello-World></hello-World>
</div>
<script src="../vue.js"></script>
<script>
//
/*
组件注册注意事项
如果使用驼峰式命名 那么在使用组件的时候 只能在字符串模板中用驼峰的方式使用组件
但是 在普通的标签模板中 必须是使用短横线方式使用组件
*/
Vue.component('HelloWorld', {
data: function() {
return {
msg: 'helloWorld'
}
},
template: '<div>{{msg}}</div>'
})
Vue.component("button-template", {
data: function() {
return {
count: 0,
}
},
template: `<div>
<button @click.prevent='handle'>点击了{{count}}次</button>
<button>测试</button>
<HelloWorld></HelloWorld>
</div>`,
methods: {
handle() {
this.count++
}
},
})
var vm = new Vue({
el: '#app',
data: {}
})
</script>
</body>
</html>
4.局部组件注册
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<hello-world></hello-world>
<Hello-jay></Hello-jay>
<!-- <test-com></test-com> -->
</div>
<script src="../vue.js"></script>
<script>
// Vue.component("test-com", {
// template: "<div>Test<hello-world></hello-world></div>"
// });
/*
局部组件注册
局部组件只能在注册他的父组件中使用
*/
var HelloWorld = {
data: function() {
return {
msg: "hello World"
}
},
template: "<div>{{msg}}</div>"
};
var HelloJay = {
data: function() {
return {
msg: 'hello Jay'
}
},
template: "<div>{{msg}}</div>"
}
var vm = new Vue({
el: '#app',
data: {},
components: {
'hello-world': HelloWorld,
'hello-jay': HelloJay
}
})
</script>
</body>
</html>
5.数据的传递
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
{{pmsg}}
<menu-item title="来自父组件的值"></menu-item>
<menu-item :title="ptitle" content="hello"></menu-item>
</div>
<script src="../vue.js"></script>
<script>
// 父组件向子组件传值
Vue.component("menu-item", {
props: ['title', 'content'],
data: function() {
return {
msg: "子组件本身的数据"
}
},
template: '<div>{{msg+"--"+title+"--"+content}}</div>'
})
var vm = new Vue({
el: '#app',
data: {
pmsg: "父组件中的内容",
ptitle: '动态绑定属性'
}
})
</script>
</body>
</html>
6.props属性名规则
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
{{pmsg}}
<menu-item :menu-title="ptitle"></menu-item>
</div>
<script src="../vue.js"></script>
<script>
// 父组件向子组件传值
Vue.component("menu-item", {
props: ['menuTitle'],
data: function() {
return {
msg: "子组件本身的数据"
}
},
template: '<div>{{msg}}<third-item testTitle="hello"></third-item></div>'
})
Vue.component("third-item", {
props: ['testTitle'],
data: function() {
return {
msg: "子组件本身的数据"
}
},
template: '<div>{{testTitle}}</div>'
})
var vm = new Vue({
el: '#app',
data: {
pmsg: "父组件中的内容",
ptitle: '动态绑定属性'
}
})
</script>
</body>
</html>
7.父传子的属性值类型
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<menu-item :pstr="pstr" :pnum="12" :pboo=true :parr="parr" :pobj='pobj'></menu-item>
</div>
<script src="../vue.js"></script>
<script>
Vue.component('menu-item', {
props: ['pstr', 'pnum', 'pboo', 'parr', 'pobj'],
template: `<div>
<div>{{pstr+'---'+(12+pnum)+'--'+pboo}}</div>
<ul><li v-for="(item,index) in parr" :key="index">{{item}}</li><ul>
<div>
<span>{{pobj.name}}</span>
<span>{{pobj.age}}</span>
</div>
</div>`
})
var vm = new Vue({
el: '#app',
data: {
pmsg: '父组件中的内容',
pstr: 'hello',
parr: ['apple', 'orange', 'banana'],
pobj: {
name: 'lisi',
age: 12
}
}
})
</script>
</body>
</html>
8.子组件向父组件传值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<div :style='{fontSize:fontSize+"px"}'>{{pmsg}}</div>
<menu-item :parr="parr" @enlarge-text="handle()"></menu-item>
</div>
<script src="../vue.js"></script>
<script>
// 子组件向父组件传值 基本用法
// props传递数据原则 单向数据流
Vue.component('menu-item', {
props: ['parr'],
template: `<div>
<ul>
<li :key='index' v-for="(item,index) in parr">{{item}}</li>
</ul>
<button @click="parr.push('lemon')">点击</button>
<button @click="$emit('enlarge-text')">扩大组件中字体大小</button>
</div>`
})
var vm = new Vue({
el: '#app',
data: {
pmsg: '父组件中的内容',
parr: ['apple', 'orange', 'banana'],
fontSize: 10
},
methods: {
handle() {
this.fontSize += 5
}
}
})
</script>
</body>
</html>
9.兄弟组件之间的传值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<text-tom></text-tom>
<div>
<button @click="handle">销毁</button>
</div>
<text-jerry></text-jerry>
</div>
<script src="../vue.js"></script>
<script>
// 兄弟组件之间的数据传递
//提供事件中心
var hub = new Vue();
Vue.component('text-tom', {
data: function() {
return {
num: 0
}
},
template: `
<div>
<div>TOM:{{num}}</div>
<div>
<button @click="handle">点击</button>
</div>
</div>
`,
methods: {
handle: function() {
hub.$emit('jerry-event', 1)
}
},
mounted() {
//监听事件
hub.$on('tom-event', (val) => {
this.num += val
})
}
})
Vue.component('text-jerry', {
data: function() {
return {
num: 0
}
},
template: `
<div>
<div>Jerry:{{num}}</div>
<div>
<button @click="handle">点击</button>
</div>
</div>
`,
methods: {
handle: function() {
//触发兄弟组件的事件
hub.$emit('tom-event', 2)
}
},
mounted() {
//监听事件
hub.$on('jerry-event', (val) => {
this.num += val
});
}
})
var vm = new Vue({
el: "#app",
data: {},
methods: {
handle() {
hub.$off('tom-event');
hub.$off('jerry-event');
}
},
})
</script>
</body>
</html>
10.组件插槽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<alert-box>有bug发生</alert-box>
<alert-box>有一个警告</alert-box>
<alert-box></alert-box>
</div>
<script src="../vue.js"></script>
<script>
Vue.component('alert-box', {
template: `
<div>
<strong>ERROR:</strong>
<slot>默认内容<slot>
</div>
`
})
var vm = new Vue({
el: '#app',
data: {}
})
</script>
</body>
</html>
11.具名插槽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<base-layout>
<p slot="header">标题信息</p>
<p>主要内容1</p>
<p>主要内容2</p>
<p slot="footer">底部信息</p>
</base-layout>
<base-layout>
<template slot="header">
<p>标题信息1</p>
<p>标题信息2</p>
</template>
<p>主要内容1</p>
<p>主要内容2</p>
<template slot="footer">
<p>底部信息1</p>
<p>底部信息2</p>
</template>
</base-layout>
</div>
<script src="../vue.js"></script>
<script>
Vue.component('base-layout', {
template: `
<div>
<header>
<slot name="header"></slot>
</header>
<main>
<slot ></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
`
})
var vm = new Vue({
el: '#app',
data: {
}
})
</script>
</body>
</html>
12.作用域插槽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.current {
color: orange;
}
</style>
</head>
<body>
<div id="app">
<fruit-list :list="list">
<template slot-scope="slotProps">
<strong v-if='slotProps.info.id==2' class="current">{{slotProps.info.name}}</strong>
<span v-else>{{slotProps.info.name}}</span>
</template>
</fruit-list>
</div>
<script src="../vue.js"></script>
<script>
Vue.component('fruit-list', {
props: ['list'],
template: `
<div>
<li v-for="item in list">
<slot :info="item">{{item.name}}</slot>
</li>
</div>
`
})
var vm = new Vue({
el: '#app',
data: {
list: [{
id: 1,
name: 'apple'
}, {
id: 2,
name: 'orange'
}, {
id: 3,
name: 'banana'
}]
}
})
</script>
</body>
</html>