Vue 高级-组件
参考:《Spring Boot + Vue 开发实战》第12章,12.1。
1 组件
组件是Vue的核心之一,它们可以扩展HTML元素,封装可重用代码,并能让开发者独立的、可复用的小组件来构建大应用。一个组件可以定义很多选项,最核心的如下:
- 模板: 反映了数据和最终实现给用户的DOM之间的映射关系。
- 初始数据:一个组件的数据初始化状态。对于可重复组件来说,通常私有状态。
- 接受的外部参数:组件之间通过参数进行数据的传递共享,参数默认是单向绑定,但也可以声明为双向绑定。
- 方法:对数据的改动操作一般都在组件内进行,可以通过v-on指令将用户输入的事件和组件方法进行绑定。
- 声明周期函数:一个组件会触发多个生命周期函数,在这些函数中可以封装一些自定义的逻辑。
Vue官网中的组件文档: cn.vuejs.org/guide/essen…
1.1 定义组件
一个简单的内容转换:点击button后将中文转换为英文语句。
<template>
<div id="container">
<div>
{{ message }}
</div>
<button @click="change">点击</button>
</div>
</template>
<script lang="ts">
export default {
name: 'A',
props: {},
data () {
return {
message: "你好,我是A组件",
}
},
methods: {
change: function () {
this.message = "Hello, this is A component"
}
},
}
</script>
<style scoped>
#container{
width: 800px;
margin: 10px auto;
}
</style>
在JavaScript中,使用了export default的方式到处定义的对象,而没有使用new Vue({})的方式。这是因为new Vue({})只是创建一个Vue示例,相当于创建一个跟组件,而export default是将组件加入组件树中,可以复用组件。
另外data()也不再是一个属性,而是一个方法,这是因为组件可以被复用。
有两种方式可以对此组件进行访问:一是通过配置路由的方式直接访问,二是在已经配置好的路由的组件中引入该组件,即复用组件。
1.2 复用组件
复用组件就像是在Vue项目的Home组件中引入HelloWorld组件。因为Home组件已经配置了路由,即可以通过路由地址在浏览器中访问Home组件。那如果在Home组件中引入A组件,则可以实现组件的复用,即在没有学习Vue路由之前,方便地访问A组件。
将Home组件略加改造,让它不再引入HelloWorld组件,而是引入A组件:
将A引入App.vue
<script setup lang="ts">
// 导入子组件
//import HelloWorld from './components/HelloWorld.vue'
import A from './components/A.vue'
</script>
中间插入Page.vue,将A.vue和B.vue引入Page.vue,最后将Page.vue引入App.vue。通过修comp的值可以在Vue页面A和B之间切换。
<template>
<div v-if="comp=='A'">
<A></A>
</div>
<div v-else-if="comp=='B'">
<B></B>
</div>
</template>
<script lang="ts">
// 导入子组件
import A from "./A.vue"
import B from "./B.vue"
export default {
name: 'Home',
data () {
return {
comp:''
}
},
components: {
A, B
},
created () {
this.comp="B"
},
}
</script>
<style scoped>
</style>
1.3 组件传参
在大多数情况下,组件都是父组件向子组件传参,但也有某些场景由于子组件处理完毕后会影响子组件,因此需要向父组件传参。
首先,先看一下父组件向子组件传参的情况。在子组件中通过props属性接收父组件的传参,props属性值是一个JavaScript对象。在该对象中指定接收的参数名和类型。如果不限制传参类型,则可以使用props:[name,gender,……]的方式,这样参数类型默认是字符串。
子组件中添加参数name
props:{
name: String
},
父组件中传参:
<component v-bind:is="comp" name="Ryam" ></component>
接下来,看一下子组件向父组件传参的情况。在父组件Home中,使用@符号指定一个子组件调用父组件的方法,赋值给父组件中已定义的方法,即当子组件使用$emit调用函数receiveMes()方法时,则会调用父组件的changeMes方法,代码如下:
<template>
<div class="home">
<div>{{ message }}</div>
<component v-bind:is="comp" name="Ryam" @receiveMes="changeMes"></component>
</div>
</template>
<script lang="ts">
// 导入子组件
import A from "./A.vue"
import B from "./B.vue"
export default {
name: 'Home',
data () {
return {
comp: "",
message: {}
}
},
components: {
A, B
},
computed: {
},
watch: {
},
methods: {
changeMes: function (mes:String){
this.message = mes;
},
},
created () {
this.comp="A"
},
mounted () {
},
}
</script>
<style scoped>
</style>
<template>
<div id="container">
<div>
<!-- {{ name + message }} -->
{{ name }}
{{ message }}
</div>
<button @click="change">点击</button>
<br>
<button @click="sendMes">发送消息到父组件</button>
</div>
</template>
<script lang="ts">
export default {
name:"A",
props:{
name: String
},
data () {
return {
message: "你好, 我是A组件",
}
},
methods: {
change: function () {
this.message = "Hello, this is A component"
},
sendMes: function(){
this.$emit("receiveMes", "这是A组件发送到父组件的信息")
}
}
}
</script>
<style scoped>
#container{
width: 800px;
margin: 10px auto;
}
</style>