Vue 组件
组件
一、组件
<div id="app">
<p>{{ msg }}</p>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
/*
* 1. 组件:有html,css,js,三部分组成的独立单位,可以类似于变量,重复使用
* 2. 组件其实就是vue实例(对象), 一个组件就是一个vue实例(对象)
* 3. new Vue({}) 产生的是一个实例对象,所以也是一个组件,我们称之为根组件
* 一个页面建议只出现一个根组件(项目开发模式下,一个项目建议只出现一个根组件)
* 4. 组件的html页面结构由 template实例成员提供
* template提供的html结构用来构建虚拟DOM
* 真实DOM最终被虚拟DOM替换
* 根组件一般不提供template,就由挂载点el来提供构建虚拟Dom的页面结构
* 根组件如果提供了template,还需要设置挂载点作为替换占位,template模板有且只有一个根标签
*
* */
let c1 = '';
new Vue({
el: '#app',
data: {
msg: 'vue组件',
c1: 'red'
},
template:
`
<div id="app1">
<p :style="{color: c1}">{{ msg }}</p>
<p @click="clickAction">{{ msg }}</p>
</div>
`,
methods: {
clickAction() {
console.log(this.msg)
}
}
})
</script>
总结:
- 组件:组件由html,css,js三部分组成的独立单位,类似于变量,可以重复使用
- 使用: 组件就是vue实例对象, 一个组件就是一个vue实例对象,通过new Vue({ })创建的对象,就是一个组件,也称之为根组件
- 一个页面建议只出现一个根组件,在项目开发模式下,一个项目建议只出现一个根组件
- 组件的html页面结构由template实例成员提供
- template提供html结构用来构建虚拟的DOM,真实的DOM最终会被虚拟的DOM替换,所以说不能将html和body作为根组件
- 根组件一般不提供template,都是由挂载点el来提供构建虚拟DOM页面结构,如果根组件提供了template,还需要设置挂载点作为替换占位,template模板有且只有一个根标签
二、子组件
<body>
<div id="app">
<!--在根组件template中加载的组件,称之为根组件的子组件-->
<my-Tag></my-Tag>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
/*
* 1. 定义组件
* 2. 注册组件
* 3. 使用组件
* */
// 1.定义组件 如何定义子组件:组件就是一个普通对象,内部采用vue语法结构,被vue注册解释后,就会成为vue组件
let myTag = {
template: `
<div>
<h3>子组件</h3>
<p>我是自定义的子组件</p>
</div>`,
};
// 了解:全局组件,不要注册就可以直接使用
Vue.component('tag', {
template: `
<div>
<h3>全局组件</h3>
<p>我是自定义的全局组件</p>
</div>
`,
});
new Vue({
el: '#app',
components: {
// 注册组件
myTag
}
})
</script>
总结
-
子组件: 在根组件template中加载的组件,称之为根组件的子组件
-
使用:定义组件,注册组件,使用组件
-
创建局部组件(创建对象):let myTage =
-
注册组件:new Vue({el:'#app', components:{ myTag //注册主键}})
-
使用组件:
<div id="app"> <!--在根组件template中加载的组件,称之为根组件的子组件--> <my-Tag></my-Tag> </div>
- 使用组件注意,如果创建组件对象时使用了驼峰命名,是使用组件时候使用杠- 进行分开,子组件才可以生效
-
全局组件:不需要注册直接使用
// 了解:全局组件,不要注册就可以直接使用 Vue.component('tag', { template: ` <div> <h3>全局组件</h3> <p>我是自定义的全局组件</p> </div> `, }); <div id="app"> <!--在根组件template中加载的组件,称之为根组件的子组件--> <tag></tag> </div>
三、子组件其他使用
<style>
.wrap {
width: calc(200px * 4 + 80px);
margin: 0 auto;
user-select: none;
}
.box {
width: 200px;
height: 260px;
/*border: 1px solid black;*/
background-color: rgba(10, 200, 30, 0.5);
border-radius: 10px;
float: left;
margin: 10px;
}
.box img {
width: 100%;
/*height: 200px;*/
border-radius: 50%;
}
.box p {
text-align: center;
}
</style>
</head>
<body>
<div id="app">
<!--在根组件template中加载的组件,称之为根组件的子组件-->
<div class="wrap">
<tag></tag>
<tag></tag>
<tag></tag>
<tag></tag>
</div>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
/*
* 1. 定义组件
* 2. 注册组件
* 3. 使用组件
* */
let titleTag = {
template: `
<p>
<b>
这是一种纯二哈
</b>
</p>
`
};
let tag = {
template: `
<div class="box">
<img src="img/001.jpg" alt="">
<title-tag></title-tag>
<p @click="fn">
锤他: <b>{{ num }}</b>下
</p>
</div>
`,
data() {
/*
* 1. 能被复用的组件(除了根组件),数据也要做局部化处理,
* 因为复用组件后组件的数据是相互独立的
* 2. data的值为绑定的方法的返回值,返回值是存放在数据字典中的*/
return {
num: 0,
a:1
}
},
methods: {
fn() {
this.num++
}
},
components: {
titleTag
}
};
new Vue({
el: '#app',
components: {
// 注册组件
tag
}
})
</script>
总结:
-
子组件除了组件能够被复用以外,数据也需要做局部化的处理,因为每一个组件复用后,组件的数据是相互独立的
-
在复用数据data中的是绑定方法的返回值,返回值要存放在字典中,返回的数据是键值对,每复用一次组件,就相当于产生一份自己的数据,与其他组件互不干扰,data:的数据是通过return返回的键值对
eg: data() { return { num: 0 } },
-
每次复用一次组件,数据data需要做局部化处理,相当于每次复用一次组件就产生一个对象,产生不相干的各个名称空间
四、组件传参父传子
<style>
.wrap {
width: calc(200px * 4 + 80px);
margin: 0 auto;
user-select: none;
}
.box {
width: 200px;
height: 260px;
/*border: 1px solid black;*/
background-color: rgba(10, 200, 30, 0.5);
border-radius: 10px;
float: left;
margin: 10px;
}
.box img {
width: 160px;
height: 160px;
border-radius: 50%;
margin: 0 auto;
display: block;
}
.box p {
text-align: center;
}
</style>
</head>
<body>
<div id="app">
<!--在根组件template中加载的组件,称之为根组件的子组件-->
<div class="wrap">
<tag v-for="(dog, i) in dogs" :dog="dog" v-bind:a="2"></tag>
</div>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
let dogs = [
{title: '二哈1号', img: 'img/1.jpg',},
{title: '二哈2号', img: 'img/2.jpg',},
{title: '二哈3号', img: 'img/3.jpg',},
{title: '二哈4号', img: 'img/4.jpg',},
{title: '二哈1号', img: 'img/1.jpg',},
{title: '二哈2号', img: 'img/2.jpg',},
{title: '二哈3号', img: 'img/3.jpg',},
{title: '二哈4号', img: 'img/4.jpg',},
];
let tag = {
// 在组件内部就可以通过设置自定义属性,拿到外部选择子组件提供给属性的值
props:['dog','a'],
template: `
<div class="box">
<img :src="dog.img" :alt="a">
<p>{{ dog.title }}</p>
<p @click="fn">
锤他: <b>{{ num }}</b>下
</p>
</div>
`,
data() {
return {
num: 0,
a: 1
}
},
methods: {
fn() {
this.num++;
// console.log(this.a);
}
},
};
new Vue({
el: '#app',
data: {
dogs,
},
components: {
// 注册组件
tag
}
})
</script>
总结:
- 组件传参-父传子:将根组件的数据传给子组件 eg: props:['dog','a'],
- 子组件所使用的数据在父组件中产生,在子组件中使用
- 通过在父组件中渲染子组件的时候,子组件绑定自定义属性v-bind对应的值为父组件中的数据
- 子组件中绑定的自定义属性,子组件通过props反射机制获取绑定的属性值(采用字符串反射机制)
- 使用,通过props声明获取的属性,可以直接作为变量来使用父组件中的数据
五、组件传参子传父
<style>
ul {
list-style: none;
}
.d-btn {
font-size: 12px;
width: 15px;
display: inline-block;
}
.d-btn:hover {
color: red;
cursor: pointer;
}
</style>
</head>
<body>
<div id="app">
<input type="text" v-model="msg">
<button @click="send_msg">留言</button>
<ul>
<tag v-for="(msg, i) in comment" :comment="msg" :index="i" @fn="deleteMsg"></tag>
</ul>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
let tag = {
props: ['comment', 'index'],
template: `
<li >
<i class="d-btn" @click="fun">x</i>
<b>{{ comment }}</b>
</li>
`,
methods: {
fun() {
// 点击要删除的信息,告诉父级要删除的是第几条数据记录,疑问comments在父级中
// 需要告诉父级删除的是那一个记录
this.$emit('fn', this.index)
},
},
};
new Vue({
el: '#app',
data: {
msg: '',
comment: localStorage.comment ? JSON.parse(localStorage.comment) : []
},
methods: {
send_msg() {
if (this.msg) {
this.comment.push(this.msg);
this.msg = ""
localStorage.comment = JSON.stringify(this.comment)
}
},
deleteMsg(i) {
// splice参数:开始索引操作长度,操作的结果
this.comment.splice(i, 1)
localStorage.comment = JSON.stringify(this.comment)
}
},
components: {
tag,
}
});
// localStorage,sessionStorage不能直接存储数组和对象,需要序列化为json
localStorage.arr = JSON.stringify([1, 2, 3]);
let res = JSON.parse(localStorage.arr);
console.log(res, res[2]);
</script>
eg2:
<body>
<div id="app">
<h1>{{ title }}</h1>
<tag @fn="msg"></tag>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
let tag = {
data() {
return {
modify_title: '',
}
},
template: `
<p >
<input v-model="modify_title"> {{modify_title}}
</p>
`,
watch: {
modify_title() {
//将修改的数据传父类级组件,可以传递多个值给父级组件
console.log(1);
this.$emit('fn', this.modify_title, 'adf')
},
},
};
new Vue({
el: '#app',
data: {
title: '父级初始内容',
},
methods: {
// 可以传递多个
msg(s, a) {
console.log(s, a);
this.title = s ? s : '父级初始内容'
}
},
components: {
tag,
}
});
</script>
总结:
- 组件数据传参-子传父:通过方式事件请求的方式进行数据传递 eg: this.$emit('fn', this.index)
- 通过在子组件中创建的函数通过 this.$emit('函数名', 参数),传递给父组件,第一个参数为自己定义的函数不能是事件函数(@fn='fun')在标签中绑定函数不需要括号传参,他会自动将数据传递,第二参数为要传递的真实数据,可以传送多个值
- ,localStorage,sessionStorage在前台浏览器中,不能直接存储数组和对象,需要将数据序列化为json数据
六、总结
-
组件:
- 组件:组件由html,css,js三部分组成的独立单位,类似于变量,可以重复使用
- 使用: 组件就是vue实例对象, 一个组件就是一个vue实例对象,通过new Vue({ })创建的对象,就是一个组件,也称之为根组件
- 一个页面建议只出现一个根组件,在项目开发模式下,一个项目建议只出现一个根组件
- 组件的html页面结构由template实例成员提供
- template提供html结构用来构建虚拟的DOM,真实的DOM最终会被虚拟的DOM替换,所以说不能将html和body作为根组件
- 根组件一般不提供template,都是由挂载点el来提供构建虚拟DOM页面结构,如果根组件提供了template,还需要设置挂载点作为替换占位,template模板有且只有一个根标签
-
子组件
-
子组件: 在根组件template中加载的组件,称之为根组件的子组件
-
使用:定义组件,注册组件,使用组件
-
创建局部组件(创建对象):let myTage =
-
注册组件:new Vue({el:'#app', components:{ myTag //注册主键}})
-
使用组件:
<div id="app"> <!--在根组件template中加载的组件,称之为根组件的子组件--> <my-Tag></my-Tag> </div>
- 使用组件注意,如果创建组件对象时使用了驼峰命名,是使用组件时候使用杠- 进行分开,子组件才可以生效
-
全局组件
// 了解:全局组件,不要注册就可以直接使用 Vue.component('tag', { template: ` <div> <h3>全局组件</h3> <p>我是自定义的全局组件</p> </div> `, }); <div id="app"> <!--在根组件template中加载的组件,称之为根组件的子组件--> <tag></tag> </div>
-
-
子组件数据复用
-
子组件除了组件能够被复用以外,数据也需要做局部化的处理,因为每一个组件复用后,组件的数据是相互独立的
-
在复用数据data中的是绑定方法的返回值,返回值要存放在字典中,返回的数据是键值对,每复用一次组件,就相当于产生一份自己的数据,与其他组件互不干扰
eg: data() { return { num: 0 } },
-
每次复用一次组件,数据data需要做局部化处理,相当于每次复用一次组件就产生一个对象,产生不相干的各个名称空间
-
-
组件数据传参-父传子
- 组件传参-父传子:将根组件的数据传给子组件 eg: props:['dog','a'],:'dog'是绑定的属性,通过绑定属性的方式进行数据传递
- 子组件所使用的数据在父组件中产生,在子组件中使用
- 通过在父组件中渲染子组件的时候,子组件绑定自定义属性v-bind对应的值为父组件中的数据
- 子组件中绑定的自定义属性,子组件通过props反射机制获取绑定的属性值(采用字符串反射机制)
- 使用:通过props声明获取的属性,可以直接作为变量来使用父组件中的数据
-
组件数据传参-子传父
- 组件数据传参-子传父:通过方式事件请求的方式进行数据传递 eg: this.$emit('fn', this.index)
- 通过在子组件中创建的函数通过 this.$emit('函数名', 参数),传递给父组件,第一个参数为自己定义的函数不能是事件函数(@fn='fun')在标签中绑定函数不需要括号传参,他会自动将数据传递,第二参数为要传递的真实数据
- ,localStorage,sessionStorage在前台浏览器中,不能直接存储数组和对象,需要将数据序列化为json数据