<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div id="app">
<my-cpn>my-cpn>
<my-cpn>my-cpn>
<my-cpn>my-cpn>
div>
<script src="../../js/vue.js">script>
<script>
//1、创建组件构造器对象
//``定义的字符可以换行
const cpnC=Vue.extend({
template:`
我是标题
内容
`
})
//2、注册组件 注意:组件不能定义在Vue后面
Vue.component('my-cpn',cpnC);
const app=new Vue({
el:'#app',
data:{
message:'你好',
sex:'123',
agree:false,
balls:[],
vegetable:'请选择',
fruits:[]
}
})
script>
body>
html>
组件化的基本运用:
const cpnC=Vue.extend({
template:`
我是标题
内容
`
})
注册方式一:
Vue.component('my-cpn',cpnC);//默认全局
注册方式二:
//局部组件
components:{
//cpn是使用标签时的标签名
cpn:cpnC
}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div id="app">
<cpn>cpn>
<cpnC11>cpnC11>
div>
<script src="../../js/vue.js">script>
<script>
//1、创建组件构造器对象1和2
const cpnC1=Vue.extend({
template:`
我是标题1
内容1
`
})
const cpnC11=Vue.extend({
template:`
我是标题11
内容11
`
})
const cpnC2=Vue.extend({
template:`
我是标题2
内容2
`,
components:{
cpnC1:cpnC1,
cpnC11:cpnC11
}
})
// //2、注册组件 注意:组件不能定义在Vue后面
// Vue.component('my-cpn',cpnC);
const app=new Vue({
el:'#app',
data:{
message:'你好',
sex:'123',
agree:false,
balls:[],
vegetable:'请选择',
fruits:[]
},
components:{
cpn:cpnC2
}
})
script>
body>
html>
运行结果:
在div外的cpnC11没有被包含
整理:
就是子组件注册时在 父组件定义的代码段注册
子组件不能再html代码中直接用
父组件中的会优先从父组件的compontent中找,若没有再去全局定义中找,找到替换编译
语法糖注册方式:
省去了extend
全局组件:
js:
Vue.component('cpnC1',{
template:`
我是标题
内容
`
})
html:
<conC1>conC1>
局部组件语法糖:
js:
components:{
'cnp2':{
template:`
我是标题2
内容2
`
}
}
html:
<cnp2>cnp2>
html代码:
<script type="text/x-template" id="fenli">
<div>
<h2>我是分离标题</h2>
<p>分离内容</p>
</div>
</script>
js代码:
//定义的局部组件,在Vue对象中的components中
components:{
'cnp3':{
template:'#fenli'
}
}
html代码:
<template id="fenli">
<div>
<h2>我是分离标题</h2>
<p>分离内容</p>
</div>
</template>
重要:组件内部不能访问实例(Vue)的data中的数据
组件中数据定义在components中的data中,注意这里的data返回的是一个方法(目的:闭包,当多次调用同一个组件的时候,不会数据错乱),区别于Vue实例的data
js:
//定义一个局部组件
components:{
'cnp3':{
template:'#fenli3',
data(){
return {
title:'我是data标题'
}
}
}
}
html:
<template id="fenli3">
<div>
<h2>{{title}}h2>
<p>数据data内容p>
div>
template>
<cnp3>cnp3>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>父子组件数据传递title>
head>
<body>
<div id="app">
<cnp3 :cmessage="message" :cmovies="movies">cnp3>
div>
<template id="fenli3">
<div>
<h2>{{cmovies}}h2>
<p>{{cmessage}}p>
div>
template>
<script src="../../js/vue.js">script>
<script>
const app=new Vue({
el:'#app',
data:{
message:'你好',
sex:'123',
movies:['海蜇王','海贼王','灌篮高手','火影忍者'],
},
components:{
'cnp3':{
template:'#fenli3',
data(){
return {
title:'我是data标题'
}
},
//父传子 props
props:['cmessage','cmovies']
}
}
})
script>
body>
html>
分析:
实现组件cnp3从Vue实例中获取movies、message数据
注册组件时添加props属性:
const app=new Vue({
el:'#app',
data:{
message:'你好',
sex:'123',
movies:['海蜇王','海贼王','灌篮高手','火影忍者'],
},
components:{
'cnp3':{
template:'#fenli3',
data(){
return {
title:'我是data标题'
}
},
//父传子 props
props:['cmessage','cmovies']
}
}
})
这是定义的局部组件,在Vue实例中注册的
然后在cnp3标签应用的时候动态绑定
<div id="app">
<cnp3 :cmessage="message" :cmovies="movies">cnp3>
div>
在组件cnp3中应用,这里用的是cmessage而非message
<template id="fenli3">
<div>
<h2>{{cmovies}}h2>
<p>{{cmessage}}p>
div>
template>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>父子组件子传父title>
head>
<body>
<div id="app">
<cnp3 @itemclick="cpnClick">cnp3>
div>
<template id="fenli3">
<div>
<h2>子组件h2>
<button v-for="item in categories" @click="btnclick(item)">{{item.name}}button>
div>
template>
<script src="../../js/vue.js">script>
<script>
const app=new Vue({
el:'#app',
methods:{
cpnClick(item){
console.log('------'+item.name)
}
},
data:{
message:'你好',
sex:'123',
movies:['海蜇王','海贼王','灌篮高手','火影忍者'],
},
components:{
'cnp3':{
template:'#fenli3',
data(){
return {
title:'我是data标题',
categories:[
{id:1,name:'热门推荐'},
{id:2,name:'电视剧'},
{id:3,name:'电影'},
{id:4,name:'综艺节目'},
]
}
},
//父传子 props
props:['cmessage','cmovies'],
methods:{
btnclick(item){
console.log(item);
//$emit方法是子传父的关键词,参数:标识符,参数
this.$emit('itemclick',item)
}
}
}
}
})
script>
body>
html>
执行结果:
热门推荐、电视剧、电影、综艺都是在子组件cnp3中的数据中,父组件中没有;当点击按钮热门推荐时——>触发
//$emit方法是子传父的关键词(发射),参数:标识符,参数
this.$emit('itemclick',item)
在父组件中进行接收
<div id="app">
<cnp3 @itemclick="cpnClick">cnp3>
div>
触发cpnClick方法——>
cpnClick(item){
console.log('------'+item.name)
}
打印item的name属性
<html lang="en">
<head>
<meta charset="UTF-8">
<title>父子组件子传父title>
head>
<body>
<div id="app">
<cnp3 :cmessage="message" :cmovies="movies">cnp3>
div>
<template id="fenli3">
<div>
<h2>子组件h2>
<button @click="btnclick">按钮button>
div>
template>
<script src="../../js/vue.js">script>
<script>
const app=new Vue({
el:'#app',
data:{
message:'你好',
sex:'123',
movies:['海蜇王','海贼王','灌篮高手','火影忍者'],
},
components:{
'cnp3':{
template:'#fenli3',
data(){
return {
title:'我是data标题'
}
},
//父传子 props
props:['cmessage','cmovies'],
methods:{
btnclick(){
//访问父组件 关键词$parent
console.log(this.$parent);
//访问跟组件
console.log(this.$root)
}
}
}
}
})
script>
body>
html>