Component Series: Element Plus Table part 3
Tags: javascript, vue, css, frontend
Published: 2023-03-07 11:55:12

## Table of Contents
- [Introduction](#introduction)
- [Global styling](#global-styling)
- [Local styling](#local-styling)
- [Importing to App.vue](#importing-to-appvue)
- [Start working on scoped styling](#start-working-on-scoped-styling)
- [Conclusion](#conclusion)

---
## Introduction
We will concentrate on implementing the table component from our previous article, Component Series: Element Plus Table part 2, in this article. We'll discuss styling in Vue in this article. The concepts we'll cover include global and local styling. We'll also learn how to use the class defined by Element Plus for our customized purposes.

## Global styling
Global styling refers to the strategy of building a styling outline for your application that allows for multiple base styles that can be updated later in the development stage. 
As if you are look closely we already used this strategy since the first article, since we installed Element Plus which in `src/main.js` 
```javascript
import { createApp } from 'vue';
import ElementPlus from 'element-plus';
import 'element-plus/dist/index.css';
import App from './App.vue';

createApp(App).use(ElementPlus).mount('#app');
```
However, there are 3 commons way to import style(s) class in Vue:
- Import in the root file `src/main.js`.
- Use `<style>` tag without using key word `scoped`.
- Use pseudo-class in `<style scoped>` by using `:global(.className)`

If you examine the `node_modules` directory, you will see a folder directory called `element-plus`, and if you look at the relative path in this project, `node moduleselement-plusdistindex.css` you will see a collection of CSS code that has been predefined by the developer who built the framework. And if you successfully open the file `index.css` you would see this 

![Index.css](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0s4hp12l1b3775gga141.png)
I understand that it appears to have a lot of code, but since this is a component-based framework, the styling will be added when you call the component, along with the component's import. It is advantageous to use a component-based framework in any frontend framework because it speeds up prototyping; however, you must adapt the component to fit your needs and preferences.

## Local styling
In contrast to global, this strategy only affects the current component that you imported. In other words, I'm going to create one more component to demonstrate this effect in your application since our component series currently only has one component (the table). Therefore, I'll add a new component to `components/NewTestTableComponent.vue`. First, let's copy the copy from `components/TableComponent.vue` to the new component which is `components/NewTestTableComponent.vue`.
```javascript
<template>
  <el-table :data="tableData" style="width: 100%">
    <template v-for="value in headerTable" ::key="value.name">
      <el-table-column :prop="value" :label="value" width="180" />
    </template>
  </el-table>
</template>

<script lang="ts" setup>
import { defineProps, onMounted, ref } from 'vue';

const props = defineProps<{
  tableData: any;
}>();

const headerTable = ref();

onMounted(() => {
  headerTable.value = Object.keys(props.tableData[0]);
});
</script>
``` 
After that we are going to add `style` tag in the new component
```javascript
<style scope>
</style>
```
Here is what the full code looked like in the `components/NewTestTableComponent.vue`
```javascript
<template>
  <el-table :data="tableData" style="width: 100%">
    <template v-for="value in headerTable" ::key="value.name">
      <el-table-column :prop="value" :label="value" width="180" />
    </template>
  </el-table>
</template>

<script lang="ts" setup>
import { defineProps, onMounted, ref } from 'vue';

const props = defineProps<{
  tableData: any;
}>();

const headerTable = ref();

onMounted(() => {
  headerTable.value = Object.keys(props.tableData[0]);
});
</script>
<style scope></style>
```
### Importing to App.vue
Full code of `src/App.vue` after import 
```javascript

<template>
  <TableComponent :table-data="tableData" />
  // as for pass props here we are using 
  // ':' because we wanted to be dynamic props when we are passing on 

  <NewTestTableComponent :table-data="tableData" />
</template>

<script lang="ts" setup>
import TableComponent from './components/TableComponent.vue';
import NewTestTableComponent from './components/NewTestTableComponent.vue';

const tableData = [
  {
    date: '2016-05-03',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
    age: 10,
  },
  {
    date: '2016-05-02',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
    age: 10,
  },
  {
    date: '2016-05-04',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
    age: 10,
  },
  {
    date: '2016-05-01',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
    age: 10,
  },
];
</script>
```

### Start working on scoped styling
Currently, it is difficult to distinguish between the two because of the table
![Table and NewTestTable](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ik70fp9u7mqvbnncmr65.png)
I am going to add on some styling in the `components/NewTestTableComponent.vue`,
```javascript
<template>
  <el-table :data="tableData" style="width: 100%" class="bg-table">
    <template v-for="value in headerTable" ::key="value.name">
      <el-table-column :prop="value" :label="value" width="180" />
    </template>
  </el-table>
</template>

<script lang="ts" setup>
import { defineProps, onMounted, ref } from 'vue';

const props = defineProps<{
  tableData: any;
}>();

const headerTable = ref();

onMounted(() => {
  headerTable.value = Object.keys(props.tableData[0]);
});
</script>
<style scope>
.bg-table {
  background-color: red;
}
</style>
```
After that, the outcome would appear as follows. (Despite the fact that I use the class in another component, it still has restrictions.)

![Apply Scoped](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6nvga4ehr9a2zoqzfgst.png)
But because our table has two displays that make them both look unfriendly, I'm going to achieve this by applying customized classes and also working with predefine classes that Element Plus provides.
I am going to inspect the html in my browser by going to chrome developer tool by clicking `F12` or right click go to inspect, if you still can't open you can have a quick look at this link that is from google itself [Open google developer tool](https://www.youtube.com/watch?v=X65TAP8a530).
After open it up

![Open tool](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ae1hyd06efvurkuajuci.png)
First you click this one for targeting the HTML element.

![Target HTML](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wzwzt5f7k5xfo1964jf6.png)
Then after hovering around you will start to see this get highlight

![Highlight](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o86ko1wyvekeyp7dmf0f.png)
And I wanted to customize this class.
```javascript
<template>
  <el-table :data="tableData" style="width: 100%">
    <template v-for="value in headerTable" ::key="value.name">
      <el-table-column :prop="value" :label="value" width="180" />
    </template>
  </el-table>
</template>

<script lang="ts" setup>
import { defineProps, onMounted, ref } from 'vue';

const props = defineProps<{
  tableData: any;
}>();

const headerTable = ref();

onMounted(() => {
  headerTable.value = Object.keys(props.tableData[0]);
});
</script>
<style scoped>
.el-table tr {
  background-color: red !important;
}
</style>
```
As you can see I have remove one class from this file `NewTestTableComponent.vue` , But, as you can see on the screen, nothing has changed and everything remains the same. Usually, I run into this issue when I first start working with Vue since I don't understand how the component's class renders to the screen. As for us, what we are currently doing is overriding the global class in a local class (component), which is not allowed and hence does not function. Because a child is the component you are overriding, this is. To solve this issue the common approach is using `:deep`
```javascript
<style scoped>
:deep(.el-table__row) {
  background-color: red;
}
</style>
``` 
We can see the changes taking place when we add this.
![Deep](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/329hmk8rplrnf39xid60.png)
As I am going add CSS in to this files.

`NewTestTableComponent.vue` (final)
```javascript
<template>
  <el-table :data="tableData" style="width: 100%">
    <template v-for="value in headerTable" ::key="value.name">
      <el-table-column :prop="value" :label="value" width="180" />
    </template>
  </el-table>
</template>

<script lang="ts" setup>
import { defineProps, onMounted, ref } from 'vue';

const props = defineProps<{
  tableData: any;
}>();

const headerTable = ref();

onMounted(() => {
  headerTable.value = Object.keys(props.tableData[0]);
});
</script>
<style scoped>
:deep(.el-table__row) {
  background-color: rgb(51, 134, 79);
  color: aliceblue;
}
:deep(.el-table__body :hover) {
  color: black;
}
</style>
```
`App.vue`
```javascript
<template>
  <div class="container">
    <TableComponent :table-data="tableData" />
    <!-- as for pass props here we are using ':' because we wanted to be dynamic
    props when we are passing on -->
    <el-divider />
    <NewTestTableComponent :table-data="tableData" />
  </div>
</template>

<script lang="ts" setup>
import TableComponent from './components/TableComponent.vue';
import NewTestTableComponent from './components/NewTestTableComponent.vue';

const tableData = [
  {
    date: '2016-05-03',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
    age: 10,
  },
  {
    date: '2016-05-02',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
    age: 10,
  },
  {
    date: '2016-05-04',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
    age: 10,
  },
  {
    date: '2016-05-01',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
    age: 10,
  },
];
</script>
<style>
.container {
  width: 756px;
  margin-right: auto;
  margin-left: auto;
  margin-top: auto;
}
</style>
```
Here is the output of the final polishing

(look cleaner then before)
![Clean](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wpo1m4fykayywnqzw94v.png)

## Conclusion
In conclusion, this article looked at the Vue style system and ways to apply it in daily development work. The best way for front-end developers is to utilize global styling to define a blueprint and local styling for customized use. Nevertheless, this technique has the drawback that front-end developers must submit prototypes to clients by a deadline. Keeping it balance is good thing. Yet, customizability demanded that our front-end developers also have a solid grasp of CSS. So I've added writing about CSS to my bookmarks. I'll speak in-depth about a new component that appears in element plus in the following part (I only selected a few component then I will move on to another framework component).
Here is my full code to this article [Git](https://github.com/TeLoardBruh/Blog-Componentseries/tree/component-series-part-3).


---
Happy coding~~~