一、组件
1、什么是组件
在Vue.js中,组件是构建用户界面的可重用和独立的模块。每个Vue组件都封装了自己的模板、逻辑和样式,使得代码可以更加模块化、可维护性更高。通过组件化,你可以将界面拆分成独立的、可复用的部分,每个部分都有自己的功能和样式,这样可以更容易地管理复杂的界面,并且提高了代码的可读性和可维护性。
通俗来说,组件就是把一个很大的界面拆分为多个小的界面, 每一个小的界面就是一个组件,将大界面拆分成小界面就是组件化。而组件化开发指的就是根据封装的思想,把页面上可重用的 UI 结构封装为组件,从而方便项目的开发和维护。
2、组件的分类
- 按作用范围分类
- 全局组件:项目中所有地方都可以的组件称为全局组件
- 局部组件(私有组件):仅有该组件才能使用的组件称为局部组件
- 按照用途来分
- 页面组件
- 自定义组件
工程化开发之后:1个组件 就是1个xx.vue
。 在vue 中规定:组件的后缀名是 .vue。之前接触到的 App.vue 文件本质上就是一个 vue 的组件。
以CSDN为例,如果使用组件化开发的话:
3、组件的内容
在Vue中,一个组件可以包括以下内容:
-
模板(Template):定义了组件的结构和布局,使用HTML和Vue的模板语法来描述界面的外观。
-
脚本(Script):包含了组件的逻辑,例如数据处理、事件处理、生命周期钩子等。通常使用JavaScript或TypeScript编写。
-
样式(Style):定义了组件的样式,可以使用CSS、Sass、Less等来编写。
通过组件,你可以将页面划分成多个独立的部分,每个部分都有自己的功能和样式,并且可以在需要的地方进行重复使用。其中,每个组件中必须包含 template 模板结构,而 script 行为和 style 样式是可选的组成部分。
(1)template
- 当前组件的DOM结构,需要定义到template标签的内部
template:`
<div>
<h1>{{ message }}</h1>
<button @click="changeMessage">Change Message</button>
</div>
`
注意:
- template 是 vue 提供的容器标签,只起到包裹性质的作用,它不会被渲染为真正的 DOM 元素,后面的 v-slot 会使用到这个标签
- template 中只能包含唯一的根节点
(2)script
- 之后与组件相关的data数据、methods方法等,都需要定义到export default所导出的对象中
data() {
return {
message: 'Hello, Vue!'
};
},
methods: {
changeMessage() {
this.message = 'Hello, World!';
}
}
注意:
.vue 组件中的 data 必须是函数
vue 规定:.vue 组件中的 data 必须是一个函数,不能直接指向一个数据对象。
因此在组件中定义 data 数据节点时,下面的方式是错误的,但是在根组件这样写是可以的
data:{ count:0 }
(3)style
- 还是按照css的语法来写就好
<style>
h1 {
color: blue;
}
</style>
总的来说,Vue组件是Vue.js框架中用于构建用户界面的独立模块,它们可以被组合和嵌套,从而构建出复杂的界面。
二、组件使用
1、全局组件
全局组件是在Vue应用程序中全局注册的组件,可以在应用的任何地方使用。一旦注册为全局组件,它就可以在整个应用程序中的任何Vue实例的模板中使用。
(1)注册全局组件
在Vue中,你可以使用Vue.component
方法来注册全局组件。例如:
// 全局注册一个名为 'my-component' 的组件
Vue.component('my-component', {
// ... 组件的选项
})
(2)使用全局组件
一旦注册为全局组件,你可以在任何Vue实例的模板中使用它:
<template>
<div>
<my-component></my-component>
</div>
</template>
(3)完整示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./JS/vue.js"></script>
</head>
<body>
<div id="app">
<h1>全局组件的使用</h1>
<button @click="handleClick">点我</button>
<hr>
<xiao></xiao>
<hr>
<h1>我是全局组件</h1>
<xiao></xiao>
</div>
</body>
<script>
// 1、定义全局组件
Vue.component('xiao', {
template: `<div>
<h1>{{ name }}</h1>
<button @click="handleClick">点我换名字</button>
</div>`,
data() {
return {
name: 'xiao'
}
},
methods: {
handleClick() {
this.name = '彭于晏'
}
}
})
var vm = new Vue({
el: '#app',
data: {},
methods: {
handleClick() {
alert('美女吧')
}
}
})
</script>
</html>
2、局部组件
局部组件是在Vue实例(或者其他组件)的组件选项中注册的组件。它只能在注册它的实例或者组件内部使用。
(1)注册局部组件
在Vue实例或者其他组件中,你可以通过components
选项来注册局部组件。例如:
<template>
<div>
<my-local-component></my-local-component>
</div>
</template>
<script>
// 通过ES6的import将自定义的组件引入进来
import MyLocalComponent from './MyLocalComponent.vue';
export default {
// 注册组件
components: {
'my-local-component': MyLocalComponent
}
}
</script>
(2)使用局部组件
一旦在实例或者组件中注册了局部组件,你可以在该实例或者组件的模板中使用它:
<template>
<div>
<my-local-component></my-local-component>
</div>
</template>
(3)完整示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./JS/vue.js"></script>
</head>
<body>
<div id="app">
<h1>局部组件的使用</h1>
<button @click="handleClick">点我</button>
<hr>
<xiao></xiao>
</div>
</body>
<script>
var xiao = {
template: `
<div>
<h2>我是局部组件</h2>
</div>
`,
data() {
return {}
},
methods: {}
}
var vm = new Vue({
el: '#app',
data: {},
methods: {
handleClick() {
alert('美女吧')
}
},
components: {
xiao:xiao
}
})
</script>
</html>
3、全局和局部混合使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./JS/vue.js"></script>
</head>
<body>
<div id="app">
<h1>局部组件的使用</h1>
<button @click="handleClick">点我</button>
<hr>
<child></child>
</div>
</body>
<script>
var xiao = {
template: `
<div>
<h2>我是局部组件</h2>
</div>
`,
data() {
return {}
},
methods: {}
}
// 全局组件
Vue.component('child', {
template: `
<div>
<h1>我是全局组件</h1>
<xiao></xiao>
<xiao></xiao>
<xiao></xiao>
</div>
`,
// 局部组件
components: {
// 第一种方法
// xiao: {
// template: `
// <div>
// <h2>我是局部组件</h2>
// </div>
// `,
// data() {
// return {}
// },
// methods: {}
// }
// 第二种方法
xiao
}
})
var vm = new Vue({
el: '#app',
data: {},
methods: {
handleClick() {
alert('美女吧')
}
},
components: {
xiao
}
})
</script>
</html>
4、总结
- 全局组件可以在整个应用程序中的任何地方使用,而局部组件只能在注册它的实例或者组件内部使用。
- 全局组件适合用于在整个应用中频繁使用的通用组件,而局部组件适合用于特定页面或者组件内部的组件。
- 全局组件的注册是通过
Vue.component
方法进行,而局部组件的注册是通过组件选项中的components
属性进行。 - 注意:组件中的数据,事件在没有额外参数的影响下都是独立的
了解elementui:
- Element UI是一个基于Vue.js的组件库,提供了丰富的UI组件,如按钮、表格、弹窗等,可以帮助开发者快速构建美观、功能完善的前端界面。
- 使用Element UI不仅可以减少开发工作量,而且它的组件都经过优化和测试,在性能和用户体验方面表现较好。
- 通过引入Element UI的全局组件,开发者可以更加高效地开发出具有一致风格的界面。
三、组件间通信
1、父子通信之父传子-自定义属性
(1)父组件向子组件通信的步骤
- 在父组件中定义变量
data: {
'url': './img/a.jpg'
}
- 把变量传递个子组件 ==> 自定义属性:myurl
<Child1 :myurl="url"></Child1>
- 在子组件中,拿到属性
props:['myurl']
- 以后在子组件中使用父组件的属性
this.myurl
(2)完整示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./JS/vue.js"></script>
<script src="./JS/axios.js"></script>
</head>
<body>
<div id="app">
<h1>组件间通信之父传子:自定义属性</h1>
<h2>父组件中的名字{{myname}}</h2>
<div style="background-color: pink">
<child :name="myname" yy="xx"></child>
</div>
</div>
</body>
<script>
// 全局组件
Vue.component('child', {
template: `
<div>
<h2>我是child组件</h2>
<h3>父组件传递给子组件的{{ name }}---{{ yy }}</h3>
</div>`,
data() {
return {}
},
props: ['name', 'yy']
})
var vm = new Vue({
el: '#app',
data: {
myname: '彭于晏'
},
})
</script>
</html>
运行结果:
2、父子通信之子传父---自定义事件
(1)子组件向父组件通信的步骤
- 在父组件中定义变量,用来接收子组件传入的变量
data: {
text:''
},
- 在父组件使用子组件时候,自定义事件 myevent,名字随便取
<Child1 @myevent="handleMyEvent"></Child1>
- 在父组件中定义函数,跟自定义事件绑定
handleMyEvent(childText){
this.text=childText
}
- 在子组件中 ==> 触发自定义事件执行
this.$emit('自定义事件名字',this.mytext)
(2)完整示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./JS/vue.js"></script>
<script src="./JS/axios.js"></script>
</head>
<body>
<div id="app">
<h1>组件间通信之子传父:自定义事件</h1>
<h2>我是父组件</h2>
子组件传给父组件的值===> {{p_name}}
<hr>
<div style="background-color:pink">
<child @myevent="handleEvent"></child>
</div>
</div>
</body>
<script>
// 全局组件
Vue.component('child', {
template: `
<div>
<h2>我是child组件</h2>
<input type="text" v-model="name">--> {{name}}
<button @click="handleSend">传给父</button>
</div>`,
data() {
return {
name:''
}
},
methods:{
handleSend(){
this.$emit('myevent',this.name)
}
}
})
var vm = new Vue({
el: '#app',
data: {
p_name:''
},
methods: {
handleEvent(name){
// name 是子组件中调用this.$emit('myevent',this.name)传过来的
this.p_name = name
}
},
})
</script>
</html>
运行结果:
3、ref属性(父子通信)
- ref 是个属性, 如果在普通的DOM元素上,引用指向的就是该DOM元素;
- 如果在子组件上,引用的指向就是子组件实例,然后父组件就可以通过 ref 主动获取子组件的属性或者调用子组件的方法
(1)放在普通标签上
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./JS/vue.js"></script>
<script src="./JS/axios.js"></script>
</head>
<body>
<div id="app">
<h2>ref属性放在普通标签上</h2>
<input type="text" v-model="name" ref="myinput">
<img src="./img/2.jpg" alt="" ref="myimg">
<button @click="handleClick">点我执行代码</button>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
name: ''
},
methods: {
handleClick() {
console.log(this.$refs)
// 根据ref指定的名字,取出原生dom对象,然后就可以操作dom对象了
var i = this.$refs['myinput']
console.log(i)
i.value = "你好"
// 改图片
var i = this.$refs['myimg']
i.src = './img/3.jpg'
}
}
})
</script>
</html>
(2)放在组件上
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./JS/vue.js"></script>
<script src="./JS/axios.js"></script>
</head>
<body>
<div id="app">
<div style="background-color: antiquewhite">
<h2>ref属性放在组件上</h2>
<child ref="mychild"></child>
</div>
</div>
</body>
<script>
// 定义全局组件
Vue.component('child', {
template: `
<div>
<img :src="url" alt="">
<button @click="handleClick('子组件传入的')">点我弹窗</button>
</div>
`,
data() {
return {
url: './img/1.jpg'
}
},
methods: {
handleClick(name) {
alert(name)
}
},
})
var vm = new Vue({
el: '#app',
data: {
name: ''
},
methods: {
handleClick() {
// 操作组件对象
var i = this.$refs['mychild']
console.log(i.url)
// 改图片
i.url = './img/4.jpg'
// 改执行方法
i.handleClick('xiao')
// 子传父
this.name = i.url
}
}
})
</script>
</html>
四、动态组件
1、概念
动态组件就是允许你根据当前的数据来动态地切换显示不同的组件。
-
Vue内部提供的组件component组件作用是:实现动态的渲染组件,按需显示组件。
-
component 标签是 vue 内置的,作用:组件的占位符
-
其中is 属性的值,表示要渲染的组件的名字
-
is 属性的值,应该是组件在 components 节点下的注册名称
2、完整示例
- 比如我们这里有三个组件,需求:在app根组件中点击不同按钮可以按需显示组件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./vue/vue.js"></script>
<style>
.item {
width: 150px;
height: 50px;
background-color: pink;
font-size: 25px;
margin: 10px;
display: flex;
justify-content: center;
align-items: center;
}
.top {
display: flex;
justify-content: center;
}
</style>
</head>
<body>
<div id="app">
<h1>动态组件</h1>
<div class="top">
<div class="item" @click="current='goods'">
<span>商品</span>
</div>
<div class="item" @click="current='order'">
<span>订单</span>
</div>
<div class="item" @click="current='user'">
<span>用户</span>
</div>
</div>
<div>
<!-- 不使用动态组件-->
<!-- <goods v-if="current=='goods'"></goods>-->
<!-- <order v-else-if="current=='order'"></order>-->
<!-- <user v-else></user>-->
<!-- 使用动态组件-->
<component :is="current"></component>
</div>
</div>
</body>
<script>
// 1 定义出 商品,订单,用户 三个组件
Vue.component('goods', {
template: `<div>
<h3>商品页面</h3>
商品列表
<br>
商品列表
</div>`,
})
Vue.component('order', {
template: `<div>
<h3>订单页面</h3>
订单内容
</div>`,
})
Vue.component('user', {
template: `<div>
<h3>用户页面</h3>
用户信息
</div>`,
})
var vm = new Vue({
el: '#app',
data: {
current: 'goods'
},
})
</script>
</html>
3、内部组件keep-alive组件的使用
-
keep-alive 会把内部的组件进行缓存,而不是销毁组件;
-
在使用 keep-alive 的时候,可以通过 include 指定哪些组件需要被缓存;
-
或者,通过 exclude 属性指定哪些组件不需要被缓存;但是:不要同时使用 include 和 exclude 这两个属性
<keep-alive exclude="goods">
<component :is="current"></component>
</keep-alive>
五、插槽
1、介绍
slot的官方定义是用于组件内容分发,简单通俗的解释就是在组件化开发中,虽然组件是一样的,但是在不同的使用场景,组件的某一部分需要有不同的内容显示。slot就好比组件开发时定义的一个参数,如果不传入值就当默认值使用,如果传入了新值,在组件调用时就会替换定义时的slot默认值。
一般情况下,编写完1个组件之后,组件的内容都是写死的,需要加数据 只能去组件中修改,扩展性很差。然后就出现了插槽这个概念,只需在组件中添加<slot></slot>
,就可以在body的组件标签中添加内容。
2、匿名插槽
- 匿名插槽插入不同的内容类似for循环一样,使用插槽一次就要全部再来一遍,例如下面使用了两个不同内容但是匿名插槽一样,所以会有两次完整的组件形成。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./JS/vue.js"></script>
<script src="./JS/axios.js"></script>
</head>
<body>
<div id="app">
<h1>插槽使用</h1>
<div>
<Home style="background-color:greenyellow">
<div>
<img src="./img/1.jpg" alt="">
</div>
</Home>
</div>
<hr>
<div>
<Home style="background-color:orange">
<div>
<img src="./img/2.jpg" alt="">
</div>
</Home>
</div>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
who: 'Home'
},
components: {
Home: {
template: `<div>
<h3>我是首页</h3>
<slot></slot>
<h3>结束了</h3>
</div>`
},
}
})
</script>
</html>
2、具名插槽
- 在使用相同的具名插槽的时候,并没有再次形成完整的组件内容,而是将插槽里面的内容直接放到组件中对应插槽的位置
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./JS/vue.js"></script>
<script src="./JS/axios.js"></script>
</head>
<body>
<div id="app">
<h1>插槽使用</h1>
<div>
<Home style="background-color:greenyellow">
<div slot="middle">
<img src="./img/1.jpg" alt="">
</div>
<div slot="middle">
<img src="./img/1.jpg" alt="">
</div>
<div slot="bottom">
<a href="">点我看mm</a>
</div>
</Home>
</div>
<hr>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
who: 'Home'
},
components: {
Home: {
template: `<div>
<h3>我是首页</h3>
<slot name="middle"></slot>
<h3>结束了</h3>
<slot name="bottom"></slot>
</div>`
},
}
})
</script>
</html>
标签:Vue,入门,template,组件,全局,data,name
From: https://www.cnblogs.com/xiao01/p/18168771