三、vue页面开发进阶版-组件开发
注:本文皆为本人自己实际开发中的了解所得经验,如有不对之处欢迎诸位批评指点
vue页面开发进阶版-组件开发
Vue 是一套用于构建用户界面的渐进式框架。
本教程均基于vue2.x的版本进行编写,搭建的脚手架是使用的@vue/cli 4,编译工具使用的是webStorm
1、vue组件开发
vue的组件开发其实就是将一个或多个大页面拆分出可以复用的部分,独立写成一个多适用性的vue页面,他和普通vue页面在项目中看起来基本一样,但是他有以下优点:
- 会使项目代码简洁性提高;
- 提高代码复用率避免大量的冗杂代码;
- 可维护性在组件分离后大大提高。
上面也说了组件其实和vue普通页面一样,在生成vue实例的时候都有data、computed、watch、methods 以及生命周期钩子等,他比组件多的主要是props,可以用来接收父组件传递的参数;
组件的名称通常就是组件vue文件名称,所以你可以将组件文件名使用全小写加‘-’链接或者是驼峰式方式命名,而驼峰式命名的话再父组件那里是可以直接使用全小写加‘-’调用,例如
<template>
<div id="app">
<HelloWorld msg="Welcome to Your Vue.js App"/>
<hello-world msg="Welcome to Your Vue.js App"/>
</div>
</template>
<script>
import HelloWorld from "./components/HelloWorld";
export default {
name: 'App',
components: {
HelloWorld
}
}
</script>
但是如果组件名称是全小写加‘-’则不可以使用驼峰是调用
注意的一点,因为组件会在多个地方被不同的页面引用,可能一个页面中出现多个一样的组件,这样的话,如果你习惯使用document.getElementById()这种方法获取DOM进行修改页面,可能会导致这个功能只有在第一个组件生效,最好是是用vue的this.$refs.[指定标签上
ref
中的值]来获取DOM进行修改页面,但是如果出现一些元素是vue方式的无法获取比如:scrollHeight
,而且刚好其他组件同时执行这个方法没有影响的话可以这样实现:
var div_ls = document.getElementsByTagName(‘div’)
for(var i=0;i<div_ls.length;i++){
if(div_ls[i].getAttribute(‘id’) === ‘chat_box’){
//进行修改操作
}
}
组件在使用时主要有三个功能来实现组件功能:通过 Props 接收父组件传递数据、使用$emit提供父组件监听子组件方法、父组件通过插槽分发内容到子组件以及父子组件互调方法.
1. 通过 Props 接收父组件传递数据
通常我们会在子组件中vue实例中定义props来指定参数名称、类型,并且可以设定默认值,当父组件没有传值时子组件会直接使用默认值,并且父组件传递过来的值不能在当前组件中修改,只能由父组件修改,并且想要监听传递过来的值需要在计算器中创建深拷贝的计算值,完后监听计算值的变化。
```javascript
export default {
name: 'HelloWorld1',
props: {
msg: String,
name:{
type:Number,
default: 0
}
},
}
```
不过如果值的类型是Array或者是Object就不能再default后直接加[]和{},而是要这样
```javascript
name:{
type:Array,
default: function () {
return []
}
},
name2:{
type:Object,
default: function () {
return {}
}
}
```
当子组件设定好值后父组件调用子组件传值就像html语言中设置标签属性一样,例如要在父组件中给子组件的msg传固定值和动态值的方法:
```html
<HelloWorld msg="Welcome to Your Vue.js App"/>
<HelloWorld :msg="fmsg"/>
```
2. 使用$emit提供父组件监听子组件方法
在实际使用中子组件中进行一些事件操作或者数据变动后都需要通知父组件进行相应的变动或者是通知父组件将props中的参数进行变更。
子组件中:
```javascript
<button v-on:click="test">
<button v-on:click="test2('测试')">
methods: {
test(){
this.$emit('notext')
},
test2(text){
this.$emit('hastext',text)
}
}
```
父组件:
```javascript
<HelloWorld @notext="test0" @hastext="test1"/>
methods: {
test0(){
console.log("子组件点击按钮后会使这个方法生效")
},
test1(text){
console.log("子组件点击按钮后会使这个方法生效,并且获取到值:text",text)
}
}
```
3. 父组件通过插槽分发内容到子组件
组件的作用就是高复用性,所以高变化性时必须的,有时候我们会在子组件中预留一些元素位置用来预留不同父组件的调用多样性。所以在组件中有一个插槽的定义:slot元素
子组件:
```html
<div>
<slot name="title"/>
<br/>
-----分割线---------
<br/>
<slot name="content"/>
</div>
```
父组件:
```html
<HelloWorld>
<div slot="title">
标题
<div>
<div slot="content">
内容
<div>
</HelloWorld>
```
效果:
![在这里插入图片描述](https://img-blog.csdnimg.cn/2020062601215029.png)
4. 父子组件互调方法
在编写组件的时候有时候为了方便或者一些特殊的需求我们需要在子组件直接调用父组件的方法,或者父组件直接调用子组件的方法
子组件直接调用父组件的方法:
```javascript
this.$parent.方法()
```
父组件直接调用子组件的方法:
```javascript
<Button @click="handleClick">点击调用子组件方法</Button>
<HelloWorld ref="testRef"/>
methods: {
handleClick() {
this.$refs.testRef.方法();
//或者是通过$children,可以获取到所有子组件的集合
this.$children[0].方法()
},
},
```