第五节:Vue组件component
文章目录
目录
component
注册全局组件 Vue中方法
components
注册局部组件 钩子函数
props:[]
传值
$emit
传递参数
$parent
获取父组件中参数
1、component 注册全局组件
component
注册全局组件 Vue中的方法注册组件的时候需要注意:
如果为驼峰命名法的时候,需要使用 - 来隔开;
语法:
// 注册组件:【组件名,组件的方法】 Vue.component('aSideBar', { // 组件的模版 template: `<div class='div1'> <h1>这个是即将被挂载的组件 {{info}} </h1> </div>`, data () { return { info: '这个是组件自己内容的值' } } })
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<h1>{{about}}</h1>
<p>{{author}}</p>
<!-- <p>ID:{{user.id}} & name:{{user.name}}</p> -->
<!-- 插入组件 -->
<a-side-bar></a-side-bar>
</div>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
<script>
Vue.component('aSideBar', {
// 组件的模版
template: `<div class='div1'>
<h1>这个是即将被挂载的组件 {{info}} </h1>
</div>`,
data () {
return {
info: '这个是组件自己内容的值'
}
}
})
new Vue({
el: '#app',
data: {
about: 'component 注册全局组件',
author: 'xiaoge',
user: {
id: 1,
name: "张三"
}
}
})
</script>
</body>
</html>
用render函数替代template ,就像使用原生js一样去拼接标签然后生成模板
语法:
render:function(createEl){// 第一参数为生成VNode的函数 return createEl( ...... ); }, createEL函数:生成的就是一个提供给Vue组件生成DOM虚拟DOM;其实简单来说虚拟DOM就是把一个正真的DOM的一些必要的信息,比如标签名,标签属性等等单独存储起来,然后通过一些处理,更具这些信息来生成一个正真的DOM 参数:createEl(string | object, [object ,] string | VNode | array) 第一参数 标签名<string> 组件参数对象<object> 第二参数(可选) 模板参数对象<object> 第三参数 标签中的文本<string> 子节点<VNode> 多个内容组成的数组<array> createEl( 'div', { class:'box' }, [ 'hello~', createEl({template:'<i></i>'}) ] ); 第二参数模板设置对象的属性: { class: ['a', {b: true}], // 等同 v-bind:class style: {color: 'red'}, // 等同 v-bind:style attrs: {goudan: '大锤'}, // 设置普通的标签属性 props: {p: 'data'}, // 等同 v-bind:p domProps: {innerHTML:'abc'}, // 设置DOM属性 on: {testFn:()=>{}}, // 等同 v-on: nativeOn: {click:() =>{}}, // 监听原生事件 key: 'myKey', // 等同 v-bind:key ref: 'myRef' // 等同 v-bind:ref }
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id='app'>
<base-head></base-head>
</div>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
<script>
/*
语法:createEl(
el,
{
class: ['a', {b: true}], // 等同 v-bind:class
style: {color: 'red'}, // 等同 v-bind:style
attrs: {goudan: '大锤'}, // 设置普通的标签属性
props: {p: 'data'}, // 等同 v-bind:p
domProps: {innerHTML:'abc'}, // 设置DOM属性
on: {testFn:()=>{}}, // 等同 v-on:
nativeOn: {click:() =>{}}, // 监听原生事件
key: 'myKey', // 等同 v-bind:key
ref: 'myRef' // 等同 v-bind:ref
},
[
'当前节点的内容 container ',
createEl({template:'<i></i>'})
]
);
*/
Vue.component('base-head', {
render: function (createEl) {// 第一参数为生成VNode的函数
return createEl(
'div',
{
style: { color: 'red' },
props: { p: 'data' },
},
[
'这个是 createEL 的数据'
]
);
},
data () {
return {
p: "123456"
}
},
methods: {
myKey: function () {
console.log("this is myKey function")
}
}
});
new Vue({
el: '#app'
});
// 表单事件
</script>
</body>
</html>
2、components 注册局部组件
components
注册局部组件 Vue中钩子函数注册组件的时候需要注意:
如果为驼峰命名法的时候,需要使用 - 来隔开;
语法:
<a-side-bar></a-side-bar> components: { aSideBar: { data () { return { info: '这个是组件自己内容的值' } }, template: `<div class='div1'> <h1>这个是即将被挂载的组件 {{info}} </h1> </div>`, } }
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<h1>{{about}}</h1>
<p>{{author}}</p>
<p>ID:{{user.id}} & name:{{user.name}}</p>
<!-- 插入组件 -->
<a-side-bar></a-side-bar>
</div>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
about: 'components 注册局部组件',
author: 'xiaoge',
user: {
id: 1,
name: "张三"
}
},
components: {
aSideBar: {
data () {
return {
info: '这个是组件自己内容的值'
}
},
template: `<div class='div1'>
<h1>这个是即将被挂载的组件 {{info}} </h1>
</div>`,
}
}
})
</script>
</body>
</html>
3、props:[]传值
props:[]
传递参数
component
、components
全局组件和局部组件中都带有data
参数 那么就牵涉到子组件使用父组件中的参数或者父组件使用子组件中的参数,props
是父组件传递参数给子组件的关键词,props 负责接受父组件传递过来的参数。 如果为驼峰命名法的时候,需要使用 - 来隔开;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<!--html给子组件传值-->
<div id='app'>
<!-- app有自己的data -->
<h1>{{title}}</h1>
<div>{{about}}</div>
<hr>
<!-- h-nav也有自己的data -->
<h-nav :title='"这里是子组件"' :des-name='param'></h-nav>
</div>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
<script>
/* 父子组件通讯(传值):父组件向子组件传值,子组件接受值,实现组件与组件之间进行通讯(非父子组件通讯)
组件的形成:html + css + js */
let vm = new Vue({
el: '#app',
data: {
about: '父组件向子组件传值,子组件接受值,实现组件与组件之间进行通讯',
title: '这里是父组件的标题',
param: '这里是传递的参数'
},
components: {
hNav: {
data () {
return {
ablout: '这里是子组件的标题',
}
},
template: `<div>
<h2>{{ablout}}</h2>
<div>{{title}} </div>
<div>{{desName}} </div>
</div>`,
//接收父组件传达过来的值。
props: ['title', 'desName'],
}
}
})
</script>
</body>
</html>
4、父组件给子组件传值
props:[]
传递参数 父组件传递参数给子组件
***传递参数如果为驼峰命名法的时候,需要使用 - 来隔开;***如:
props: ["firstParam", "params"], <xiaoge-parents :first-param='"来自原型的第一个参数"' :params="'来自原型的第二个参数'"> </xiaoge-parents>
第一种写法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<!--html给子组件传值-->
<div id='app'>
<!-- app有自己的data -->
<h1>{{title}}</h1>
<div>{{about}}</div>
<hr>
<!-- h-nav也有自己的data -->
<xiaoge-parents :first-title='"来自原型的第一个参数"' :doudou="'来自原型的第二个参数'"> </xiaoge-parents>
</div>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
<script>
/* 父子组件通讯(传值):父组件向子组件传值,子组件接受值,实现组件与组件之间进行通讯(非父子组件通讯)
组件的形成:html + css + js */
let vm = new Vue({
el: '#app',
data: {
about: '父组件向子组件传值,子组件接受值,实现组件与组件之间进行通讯',
title: '这里是原始DOM',
param: '来自原型的第二个参数'
},
components: {
xiaogeParents: {
data () {
return {
parentTitle: "这里是 xiaogeParents 节点"
}
},
props: ["firstTitle", "doudou"],
template: `<div>
<h1>{{parentTitle}}</h1>
<p>{{firstTitle}}</p>
<p>{{doudou}}</p>
<hr>
<xiaoge-child :first-param='"这是第一个参数"' :params='"这是第二个参数"'></xiaoge-child>
</div>
`,
components: {
xiaogeChild: {
data () {
return {
childTitle: '这里是 xiaogeChild 节点'
}
},
props: ["firstParam", "params"],
template: `<div>
<h1>{{childTitle}}</h1>
<p>{{firstParam}}</p>
<p>{{params}}</p>
</div>`,
}
}
}
}
})
</script>
</body>
</html>
第二种写法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<!--html给子组件传值-->
<div id='app'>
<!-- app有自己的data -->
<h1>{{title}}</h1>
<div>{{about}}</div>
<hr>
<!-- h-nav也有自己的data -->
<xiaoge-parents :first-title='"来自原型的第一个参数"' :doudou="'来自原型的第二个参数'"> </xiaoge-parents>
</div>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
<script>
/* 父子组件通讯(传值):父组件向子组件传值,子组件接受值,实现组件与组件之间进行通讯(非父子组件通讯)
组件的形成:html + css + js */
// 定义局部组件
// 子组件
let child = {
xiaogeChild: {
data () {
return {
childTitle: '这里是 xiaogeChild 节点'
}
},
template: `<div>
<h1>{{childTitle}}</h1>
<p>{{firstParam}}</p>
<p>{{params}}</p>
</div>`,
props: ["firstParam", "params"]
}
}
// 父组件
let parent = {
xiaogeParents: {
data () {
return {
parentTitle: "这里是 xiaogeParents 节点"
}
},
props: ["firstTitle", "doudou"],
template: `<div>
<h1>{{parentTitle}}</h1>
<p>{{firstTitle}}</p>
<p>{{doudou}}</p>
<hr>
<xiaoge-child :first-param='"这是第一个参数"' :params='"这是第二个参数"'></xiaoge-child>
</div>
`,
components: child
}
}
/* 父子组件通讯(传值):父组件向子组件传值,子组件接受值,实现组件与组件之间进行通讯(非父子组件通讯)
组件的形成:html + css + js */
let vm1 = new Vue({
el: '#app',
data: {
about: '父组件向子组件传值,子组件接受值,实现组件与组件之间进行通讯',
title: '这里是原始DOM',
param: '来自原型的第二个参数'
},
components: parent
})
</script>
</body>
</html>
5、多个组件写法
components
:组件中针对组件的几种赋值方式 组件可以使用components
钩子函数实现,也可以以变量的形式实现,当以变量形式出现时需要判断是否为组件 使用指令::is=”变量名“
判读变量是否为组件 如果是组件则调用组件显示,反之不显示。个人推荐使用
components
钩子函数形式使用组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<h1>{{about}}</h1>
<component-a></component-a>
<component-b></component-b>
<component-c></component-C>
<!-- is():判断是否有该对象 -->
<component :is="ABC"></component>
</div>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
<script>
let componentA = {
data () {
return {
aboutA: "这个是A组件"
}
},
template: `<div>
<h2> {{aboutA}} </h2>
</div>`
}
let componentB = {
data () {
return {
aboutB: "这个是B组件"
}
},
template: `<div>
<h2> {{aboutB}} </h2>
</div>`
}
let componentD = {
data () {
return {
aboutD: "这个是D组件"
}
},
template: `<div>
<h2> {{aboutD}} </h2>
</div>`
}
let vm = new Vue({
el: '#app',
data: {
about: "这是多个组件的写法",
ABC: componentD
},
components: {
//如果键值与键名相同的情况下,es6简写;
componentA,
componentB: componentB,
componentC: {
template: `<div>
<h2>{{aboutC}}</h2>
</div>`,
data () {
return {
aboutC: "这个是C组件"
}
}
},
}
})
</script>
</body>
</html>
6、$emit
、 $parent
传递参数
$emit
方法调用该事件并传参 如果需要在父组件中绑定事件,需要使用$emit并传递参数
$parent
获取父组件中参数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<h2>{{about}}</h2>
<p>SUM:{{ total }}</p>
<p>return:{{res}}</p>
<button-counter :total="total" v-on:increment="incrementTotal"></button-counter>
<button-counter v-on:increment="incrementTotal"></button-counter>
</div>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
<script>
// 父组件中调用子组件时绑定事件,在子组件中使用$emit方法调用该事件并传参
let vm = new Vue({
el: '#app',
data: {
about: "$emit 子组件给父组件赋值",
total: 0,
res: 0
},
methods: {
incrementTotal: function (value) {
this.res = value
this.total++
}
},
components: {
buttonCounter: {
data () {
return {
counts: 0
}
},
template: `<button v-on:click="incrementHandler">{{ counts }}</button>`,
methods: {
incrementHandler: function () {
this.counts++
console.log(this.$parent.total)
this.$emit('increment', this.counts)
}
}
}
}
})
</script>
</body>
</html>