组件
组件就是:扩展 HTML 元素,封装可重用的代码,目的是复用
例如:有一个轮播图,可以在很多页面中使用,一个轮播有js,css,html
组件把js,css,html放到一起,有逻辑,有样式,有html
组件的分类:
- 全局组件:可以放在根中,可以在所有组件中使用
- 局部组件:只能在当前组件中使用
组件也有8个生命周期钩子
全局组件
elementui,提供给咱们很多全局组件
创建全局组件
-
注意事项
-
- 变量在data中必须return出去
- 组件的使用不能直接写在body中,必须在标签中
- 全局组件是使用Vue.component定义的,可以在全局任意组件中使用
模板
<body>
<div>
<组件名></组件名>
</div>
</body>
<script>
Vue.component('组件名', {
template: `组件样式`,
data(){
return {
// 变量必须return出去
变量名:'变量值',
}
},
// 方法写在里面
methods:{
函数(){
执行体
}
}
})
</script>
实例
<body>
<div>
<child></child>
</div>
</body>
<script>
Vue.component('child', {
template: `<div>
<button @click="back">后退</button>
{{ title }}
<button>前进</button>
</div>`,
data(){
return {
title:'首页',
}
},
methods:{
back(){
console.log('退了')
}
}
})
</script>
局部组件
-
注意事项
-
- 局部组件是定义在某个组件内,可以定义多个,只能在它父组件中使用,不能到别的地方使用
- 局部组件是定义在某个组件内的:components,只能用在当前组件中
- 组件可以嵌套定义和使用,局部组件就在组件的嵌套
模板
局部组件也可以直接写在根组件的components
,以k:v键值对的形式
<body>
<div id="id">
<局部组件名></局部组件名>
</div>
</body>
<script>
let 局部组件名={
template: `模板样式`,
data(){
return {
变量:"变量值",
}
},
methods:{}
}
let vm = new Vue({
el:'绑定的id或class',
data:{},
components:{
局部组件名
}
})
</script>
实例
<body>
<div id="c1">
<res></res>
</div>
</body>
<script>
let res={
template: `<img :src="url" alt="">`,
data(){
return {
url:"http://pic.imeitou.com/uploads/allimg/230331/7-230331110I0.jpg",
}
},
methods:{}
}
let vm = new Vue({
el:'#c1',
data:{},
components:{
res
}
})
</script>
组件间通信
- 父组件被数据传递给子组件
- 通过自定义属性实现
- 1.在子组件中自定义属性,使用属性指令绑定父组件的变量
- 2.在子组件中,使用props接受
['属性名','属性名2']
- 如果props是个对象可以通过键值对限制属性的类型
props:{属性名:类型}
- 如果props是个对象可以通过键值对限制属性的类型
- 3.在父组件中,使用子组件时添加属性名即可,
<子组件名 :属性="属性名"></子组件名>
- 子组件把数据传递给父组件
- 通过自定义事件实现
- 1.在父组件里给子组件自定义事件
<子组件 @父事件="父函数">
- 2.在子组件中写一个函数,函数中
this.$emit('父事件', this.子组件中的变量)
,执行函数就会传给父组件 - 3.在父组件中的函数接受,
函数(接受参数){执行体}
,其中接收的参数就是子组件中的变量值
父传子
<body>
<div id="app">
<h1>组件的使用</h1>
<hr>
<lqz :url="url" :myshow="true"></lqz>
<hr>
</div>
</body>
<script>
var lqz = {
template: `
<div>
<h1>我是局部组件</h1>
<img :src="url" alt="" height="400px">
<button @click="handleCheck">点我看myshow类型</button>
</div>`,
data() {
return {}
},
methods: {
handleCheck() {
console.log(this.myshow)
console.log(typeof this.myshow)
}
},
props: ['url', 'myshow']
}
// 根组件
var vm = new Vue({
el: '#app',
data: {
url: 'http://pic.imeitou.com/uploads/allimg/230331/7-230331110I0.jpg',
},
components: {
lqz
}
})
</script>
子传父
<body>
<div id="c1">
<res @namechange="GetUsername"></res>
子组件的username:{{username}}
</div>
</body>
<script>
let res={
template: `<input type="text" v-model="username" @input="handleChange">`,
data() {
return {
username:''
}
},
methods: {
handleChange(){
console.log('执行改变')
this.$emit('namechange',this.username)
}
},
}
vm = new Vue({
el: '#c1',
data: {
username:'',
},
methods:{
GetUsername(username){
console.log(username)
this.username= username
}
},
components: {
res,
},
})
</script>
ref属性
ref属性,vue提供的,写在标签上
- 可以写在普通标签:在vue中使用
this.$refs.名字
拿到dom对象,可以原生操作 - 可以写在组件上:在vue中使用
this.$refs.名字
拿到[组件]对象,组件属性,方法直接使用即可
动态组件
在父组件中写一个标签,并在标签中定义一个is标签
<component :is="who"></component>
component标签的is属性等于组件名字,这里就会显示这个组件
案例
点击按钮切换组件
<body>
<div id="c1">
<button class="btn btn-success" @click="who='home'">主页</button>
<button class="btn btn-success" @click="who='book'">图书</button>
<button class="btn btn-success" @click="who='user'">信息</button>
<hr>
<component :is="who"></component>
</div>
</body>
<script>
let home={
template: `<div>主页</div>`,
}
let book={
template: `<div>图书</div>`,
}
let user={
template: `<div>信息</div>`,
}
vm = new Vue({
el: '#c1',
data: {
who:'home'
},
methods:{},
components: {
home,
book,
user
},
})
</script>
keep-alive
是一对标签<keep-alive></keep-alive>
,将动态组件包裹起来,动态组件保持存活,在使用动态组件的时候保持组件在被切换前的状态
实例
<body>
<div id="c1">
<button class="btn btn-success" @click="who='home'">主页</button>
<button class="btn btn-success" @click="who='user'">信息</button>
<hr>
<keep-alive> <component :is="who"></component> </keep-alive>
</div>
</body>
<script>
let home={template: `<div><p>主页</p><p><input type="text"></p></div>`,}
let user={template: `<div>信息</div>`,}
vm = new Vue({
el: '#c1',
data: {
who:'home'
},
methods:{},
components: {
home,
user
},
})
</script>
插槽
一般情况下,编写完1个组件之后,组件的内容都是写死的,需要加数据 只能去组件中修改,扩展性很差
然后就出现了插槽这个概念,只需在组件中添加<slot></slot>
,就可以在body的组件标签中添加内容
不具名插槽
使用步骤:
- 在组件的html的任意位置,放个标签
<slot></slot>
- 后期在父组件使用该组件时
<子组件名>放内容</子组件名>
- 放的内容,就会被渲染到slot标签中,如果slot标签有多个,多个都会渲染
具名插槽
使用步骤:
- 组件中可以留多个插槽,命名,在组件slot标签上名义属性
slot name="字符串"></slot>
- 在父组件中使用时,指定某个标签渲染到某个插槽上
将使用的标签定义属性<p slot="字符串"></p>
实例
<body>
<div id="c1">
<home>
<div>不具名插槽</div>
<div slot="name">具名插槽</div>
</home>
</div>
</body>
<script>
let home = {
template: `<div>
<p>主页</p>
<slot></slot>
<p><input type="text"></p>
<slot name="name"></slot>
</div>`,
}
vm = new Vue({
el: '#c1',
data: {
who: 'home'
},
methods: {},
components: {
home,
},
})
</script>