组件(Vue核心)
是html,css,与js的集合体,为该集合体命名,用该名字服用html,css与js组成的集合体,复用性
组件分类:
1.跟组件:new Vue() 生成的组件
2.局部组件:{},内部采用的是vue语法
3.全局组件:Vue.component('组件名' ,{}),{}内部采用的是Vue语法
定义一个根组件
一个页面中可以由多个根组件,出现一次就要new一次,根组件与根组件之间没有关系
new Vue({
el:'#d1',
data:{},
template:'<p>我可以更改自己内部的内容</p>'
});
定义一个全局组件
<div id="d2">
<co-img></co-img>
</div>
Vue.component('co-img',{
template:'<div class="c1"><h2>我想显示出来</h2><img src="img/111.jpg" alt=""></div>'
});
new Vue({
el:'#d2'
})
定义一个局部组件
<div id="d3">
<local></local>
</div>
let local = {
template:'<div class="c1"><img src="img/222.jpeg" alt=""></div>'
};
new Vue({
el:'#d3',
components:{
local
}
});
全局组件与局部组件的区别:
1.全局组件不需要进行注册,在开始的时候已经全部加载完成了,局部组件需要注册,使用一次加载一次
组件的特点:
1.组件都有管理组件html页面结果的template实例成员
2.根组件都是作为最顶层父组件,局部与全局组件作为子组件,也可以称为其他局部与全局组件的父组件
3.子组件的数据需要隔离(数据组件化,每一个组件拥有自己数据的独立名称空间)
4.局部组件必须注册后才能使用,全局组件不需要注册,提倡使用局部组件
5.组件中出现的所有变量(模板中,逻辑中),由该组件自己提供管理
6.局部全局和跟组件都是一个vue实例,一个实例对应一套html,css,js架构,所以实例就是组件
总结:根组件,可以不明确 template,template默认采用挂载点页面结构,如果设置的template,挂载点内部的内容无效,因为会被替换成template中的信息
解释:html,body标签不能被替换,所以不能作为挂载点
组件中的大写换到html中使用 - 来替换,以为html不识别大写,遇到大写就换成 -小写
localTag ==> local-tag
组件化
使产生的每个组件有自己独立的名称空间,互相之间不进行干扰,
1.定义一个函数data,使函数有一个返回值
2.对这个返回值进行操作
// 定义一个局部组
let local = {
template:'<div class="c1" @click="fn"><img src="img/222.jpeg" alt=""><h4>我被点击了{{count}}次</h4></div>',
data(){ // 局部或全局组件,一个组件可能会被复用多次,每个组件都应该有自己的独立的变量名称空间
return{
count:0
}
}, // 数据需要组件化,作为方法的返回值(方法执行之后会产生一个局部作用域)
methods:{
fn(){
console.log(11111);
this.count ++
}
}
};
组件传参 --- 父传子
1.子组件可以通过props自定义组件属性(采用反射机制,需要填写字符串,但是使用时可以直接作为变量)
2.子组件会在父组件中渲染,渲染时将父组件的变量名绑定给子组件的自定义书属性,可以将变量值传递给子组件
总结:
1.先在script中定义一个数组,将需要进行循环的值都放在数组中,
2.在对应的标签中使用for循环,通过自定义属性将k进行返回,
3.在data中定义属性
4.使用props对k值进行接收并处理,按照反射的方式,会将k所对应的值取出
5.在组件中进行取值的时候,可以直接取值,不需要再使用this
6.自定义属性可以接收变量
<div id="d3">
<local v-for="img in image" :img="img"></local>
</div>
let image = [
{
name:'我是222',
img:'img/222.jpeg'
} ,
{
name:'我是111',
img:'img/111.jpg'
}
];
let local = {
props:['img'],
template:'<div class="c1" @click="fn"><img :src="img.img" alt=""><h4>我{{img.name}}被点击了{{count}}次</h4></div>',
data(){
return{
count:0
}
},
methods:{
fn(){
this.count ++
}
}
};
new Vue({
el:'#d3',
data:{
image
},
components:{
local
},
});
组件传参 --- 子传父
自定义组件标签的事件:
自定义事件是属于子组件的,子组件在父组件中渲染并绑定事件方法,所以事件方法由父组件来实现
子组件如何触发自定义事件:this.$emit('自定义事件名', 触发事件回调的参数们)
子组件触发自定义事件,携带出子组件的内容,在父组件中实现自定义事件的方法,拿到子组件传递给父组件的消息
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>子传父</title>
</head>
<body>
<div id="app">
<h1>{{ h1 }}</h1>
<h3>{{ h3 }}</h3>
<tag @action="actionFn"></tag>
<hr>
<tag2 @h1a="aFn1" @h3a="aFn3"></tag2>
</div>
</body>
<script src="js/vue.js"></script>
<script>
let tag = {
template: `
<div>
<input type="text" v-model="t1">
<input type="text" v-model="t2">
<button @click="changeTitle">修改标题</button>
</div>
`,
data() {
return {
t1: '',
t2: '',
}
},
methods: {
changeTitle() {
if (this.t1 && this.t2) {
// console.log(this.t1, this.t2);
this.$emit('action', this.t1, this.t2);
this.t1 = '';
this.t2 = '';
}
}
}
};
let tag2 = {
template: `
<div>
主标题内容:<input type="text" v-model="t1" @input="t1Fn">
子标题内容:<input type="text" v-model="t2">
</div>
`,
data() {
return {
t1: '',
t2: '',
}
},
methods: {
t1Fn() {
this.$emit('h1a', this.t1);
}
},
watch: {
t2 () {
this.$emit('h3a', this.t2);
}
}
};
new Vue({
el: '#app',
data: {
h1: '主标题',
h3: '子标题'
},
components: {
tag,
tag2,
},
methods: {
actionFn(a, b, c) {
// console.log('触发了', a, b, c);
this.h1 = a;
this.h3 = b;
},
aFn1(a) {
if (!a) {
this.h1 = '主标题';
return;
}
this.h1 = a;
},
aFn3(a) {
if (!a) {
this.h3 = '子标题';
return;
}
this.h3 = a;
},
}
})
</script>
</html>