elementui组件系列--布局组件row和col

420 阅读2分钟

参考elementui组件库,实现简单的row和col布局组件。

利用flex进行布局,涉及到主要知识点如下:vue语法包括(slot,provide,inject),vue中封装组件,vite中设置别名,flex布局

1.使用vite+vue3创建项目。

首先,确保在你的开发环境中已经安装了Node.js。然后,可以按照以下步骤使用Vite搭建一个Vite + Vue3 的入门示例。

a. 创建一个新的项目文件夹,并在该文件夹下打开终端。

  mkdir vite-demo
    cd vite-demo

b. 使用npm init命令初始化一个新的NPM项目,并按照提示进行填写。

```
npm init
```

c. 安装Vite作为项目的脚手架工具,并创建一个新的Vue项目。

```
npm install -g create-vite   # 安装Vite脚手架工具
create-vite . --template vue-ts   # 创建一个Vue + TypeScript项目
```

d. 安装项目依赖。 npm install

e. 启动项目。

npm run dev

2.创建布局组件

1)先配置别名@代表src目录

在Vite + Vue3中设置路径别名@,需要在Vite的配置文件中进行相应的设置。

a. 打开项目根目录下的vite.config.js文件。

b. 在文件中添加以下内容:

```
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src')  // 设置别名@指向src目录
    },
  }
})
```

c. 确保你的项目中已经安装了@vitejs/plugin-vuepath这两个依赖包,如果没有安装,可以使用以下命令进行安装:

```
npm install @vitejs/plugin-vue path --save-dev
```

d. 将项目中的文件和路径按照别名@进行修改 实现布局组件row和col可以通过使用Vue的组件开发实现。

2)在项目中创建一个名为Row.vue的文件。

gutter属性利用provide传入,在col中使用inject注入使用。


<template>
  <div class="row" :class="justifyContentClass">
    <slot></slot>
  </div>
</template>

<script>
export default {
   provide: function() {
    return {
      gutter: this.gutter
    }
   },
  name: "RowCol",
  props: {
    gutter:{
      type:Number,
      default:0
    },
    justifyContent: {
      type: String,
      default: "flex-start",
      validator: (value) =>
        ["flex-start", "flex-end", "center", "space-between", "space-around"].includes(value),
    },
  },
  computed: {
    justifyContentClass() {
      return `justify-content-${this.justifyContent}`;
    },
  },
};
</script>

<style scoped>
.row {
     
    width:100%;
  display: flex;
  flex-wrap: wrap;
}
.row .col{
  padding-left:
}
.justify-content-flex-start {
  justify-content: flex-start;
}

.justify-content-flex-end {
  justify-content: flex-end;
}

.justify-content-center {
  justify-content: center;
}

.justify-content-space-between {
  justify-content: space-between;
}

.justify-content-space-around {
  justify-content: space-around;
}
</style>

3)然后,在同级目录中创建一个名为Col.vue的文件。

根据传入的span和offset,来设置占据比例和便宜位置。span=24宽度占据100%,如果span=12占据50%,其他类似。

<template>
  <div class="col" :class="colClass" :style="style">
    <slot></slot>
  </div>
</template>

<script>
export default {
  name: "Col",
    inject: ['gutter'],
  props: {
    span: {
      type: Number,
      default: 24,
      validator: (value) => value >= 1 && value <= 24,
    },
    offset: {
      type: Number,
      default: 0,
      validator: (value) => value >= 0 && value <= 24,
    },
  },
  computed: {
    colClass() {
      return `col-${this.span} offset-${this.offset} col-border`;
    },
    style(){
         const styles = {}
        if (this.gutter) {
    styles.paddingLeft = styles.paddingRight = `${this.gutter / 2}px`
  }
  return styles 
    }
  },
};
</script>

<style scoped>
.col-border{
   border:solid 1px;

}
.col {
    box-sizing: border-box;
  flex-basis: 0;
  flex-grow: 1;
  max-width: 100%;
}

.col-24 {
  flex-basis: 100%;
  max-width: 100%;
}
.col-12 {
  flex-basis: 50%;
  max-width: 50%;
}
.col-6 {
  flex-basis: 25%;
  max-width: 25%;
}

.offset-0 {
  margin-left: 0;
}

.offset-1 {
  margin-left: 4.16667%;
}

.offset-2 {
  margin-left: 8.33333%;
}

/* 省略其他 offset 样式 */

.offset-23 {
  margin-left: 95.83333%;
}

/* 自定义 span 样式 */
.col-1 {
  flex-basis: 4.16667%;
  max-width: 4.16667%;
}

.col-2 {
  flex-basis: 8.33333%;
  max-width: 8.33333%;
}

/* 省略其他 span 样式 */

.col-23 {
  flex-basis: 95.83333%;
  max-width: 95.83333%;
}

.col-24 {
  flex-basis: 100%;
  max-width: 100%;
}
</style>

4)在需要使用这些布局组件的页面中引入并使用。

<template>
  <div>
    <Row justifyContent="space-between" :gutter='20'>
      <Col span="12">
        <div class='col-content'>Column 11</div>
      </Col>
      <Col  span="6">
        <div class='col-content'>Column 2</div>
      </Col>
      <Col span="6">
        <div class='col-content'>Column 3</div>
      </Col>
    </Row>
  </div>
</template>

<script>
import Row from "@/components/row-col/Row.vue";
import Col from "@/components/row-col/Col.vue";

export default {
  components: {
    Row,
    Col,
  },
};
</script>
<style scoped>
.col-content{
  background:pink;
}
</style>

5.App.vue修改

<script setup lang="ts">
import HelloWorld from './components/HelloWorld.vue'
</script>

<template>
<div :style="{width}">
  <HelloWorld msg="Vite + Vue" />
</div>

</template>

<style scoped>
.logo {
  height: 6em;
  padding: 1.5em;
  will-change: filter;
  transition: filter 300ms;
}
.logo:hover {
  filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.vue:hover {
  filter: drop-shadow(0 0 2em #42b883aa);
}
</style>

使用以上代码可实现自定义的RowCol布局组件。其中,Row组件是一个行容器,可以设置justifyContent属性来控制行内元素的对齐方式,default值为flex-start gutter属性用于设置左右padding,传入数字,例如传入20,那么左右内边距分别是10pxCol组件是列容器,可以设置span属性来控制元素所占的列数,默认为24offset属性来控制左侧的空白列数,默认为0。 结果如下:

image.png