一. 组件化
Vue可以组件化某些会重复使用的代码块,比如pagination、table等,将这些代码单独拎出来,放入一个vue中,可以在需要的时候直接import进入主页面,避免每次都需要重新编写。这就是Vue的组件化。
项目中需要在某个页面展示脚本列表,比如python、Java脚本。最开始的时候只有python脚本,后来需要兼容Java脚本,考虑使用tab进行切换。由于展示内容基本一致,所以这里不再重复写一套列表的代码,而是将这个展示列表 <el-table> 抽离出来进行组件化。
二. 子组件及其使用
1.子组件化
首先说明一下抽出来的子组件的格式,与一个完整的vue页面完全一样,一般需要填写的是下面几个部分:
<template>
</template>
<script>
export default {
name: "ScriptListTable",
data() {
return {
}
},
methods: {
},
watch: {
}
}
</script>
<style scoped>
</style>
2.父页面调用
(1)引入子组件
在父页面的 <script> 中通过 import 引入子组件,再通过 components 进行注册:
<script>
import ScriptListTable from './components/ScriptListTable'
export default {
name: "XXXX",
components: { ScriptListTable },
}
</script>
(2)使用子组件
父页面直接在 <template> 中通过子组件的名字进行标签使用(可以使用一样的驼峰形式,也可以使用短线连接形式):
<script-list-table>
......
</script-list-table>
三. 父子组件传值
组件化后最重要的内容就是进行父子组件间的传值。父组件一般用来操作方法,从后台获取结果,子组件则负责将父组件传来的结果展示出来,因此这里就牵扯到父传子;子组件也需要给父组件传值,比如子组件中某个按钮被点击,需要告诉父组件进行事件响应,这就牵扯到子传父。下面将介绍如何在父子组件间传值。
1.父组件向子组件传值
父组件通过 :XXX 将值传给子组件,这里给了个例子 :table-list-prop,它的值 tableList 就是从后端获取到的数组列表,现在传给子组件显示;
注意,这里很多帖子都说通过 v-bind:table-list-prop=“tableList” 进行动态绑定,但是我试了好久没用,不知道哪里有问题,因此这里没有使用 v-bind,而是通过子组件的 watch 进行变量监听。
<script-list-table
ref = "pythonTable"
:table-list-prop="tableList"
</script-list-table>
<script>
export default {
name: "python-script",
components: { ScriptListTable },
data() {
return {
tableList: []
}
}
}
</script>
2.子组件获取值
(1)子组件首先需要将父组件中的 :XXX 在 props 中进行声明,表明它的期望接收类型;
(2)由于传递的值是动态变量,所以需要在 watch 中进行变量监听,保证父组件的值改变后会立即传递给子组件;
(3)之后,在 data() 的 return 中重新定义一个变量 YYY,并将父组件的 XXX 变量赋值给该 YYY 变量;
(4)子组件即可使用 YYY 变量。
<template>
<el-table :data="tableList" ... > ... </el-table>
</template>
<script>
export default {
name: "ScriptListTable",
props: {
tableListProp: {
type: Array,
required: true
},
},
data() {
return {
tableList: this.tableListProp,
}
},
watch: {
tableListProp: {
handler(val) {
this.tableList = val
},
deep: true
}
}
}
</script>
3.子组件向父组件传值
当子组件的某个按钮被点击了,需要通知父组件进行事件响应。子组件通过 this.$emit 将参数传递给父组件,有参和无参的形式分别如下所示:
<template>
...
<el-button type="primary" @click="scriptEditY(scope.row)">编辑入参
</el-button>
<el-button type="primary" @click="searchScriptY">查询脚本
</el-button>
...
</template>
<script>
export default {
methods: {
scriptEditY(row) {
this.$emit("scriptEditX", row);
},
searchScriptY() {
this.$emit("searchScriptX");
},
},
}
</script>
4.父组件接收值
父组件通过 v-on(@是v-on的简写) 监听子组件事件,@后面的方法名需要与 this.$emit 第一个参数相同。= 右边的值是在父页面中定义的方法,用于处理子组件的事件:
<template>
<script-list-table
ref = "pythonTable"
:table-list-prop="tableList"
@scriptEditX = "scriptEdit"
@searchScriptX = "searchScript">
</script-list-table>
</template>
<script>
export default {
methods: {
scriptEdit(row) {
console.log(row.id); //参数即被传递过来
},
searchScript() {
console.log("这是个无参方法");
}
}
}
</script>
5.父组件获取子组件的属性值
this.$refs[‘pythonTable’] 就可获取到子组件,再通过它调用某个值。
this.$refs['pythonTable'].XXX