DEV Community

Rax
Rax

Posted on

Component Series: Element Plus Table part 3

Table of Contents


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

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');
Enter fullscreen mode Exit fullscreen mode

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
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.

<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>
Enter fullscreen mode Exit fullscreen mode

After that we are going to add style tag in the new component

<style scope>
</style>
Enter fullscreen mode Exit fullscreen mode

Here is what the full code looked like in the components/NewTestTableComponent.vue

<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>
Enter fullscreen mode Exit fullscreen mode

Importing to App.vue

Full code of src/App.vue after import


<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>
Enter fullscreen mode Exit fullscreen mode

Start working on scoped styling

Currently, it is difficult to distinguish between the two because of the table
Table and NewTestTable
I am going to add on some styling in the components/NewTestTableComponent.vue,

<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>
Enter fullscreen mode Exit fullscreen mode

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
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.
After open it up

Open tool
First you click this one for targeting the HTML element.

Target HTML
Then after hovering around you will start to see this get highlight

Highlight
And I wanted to customize this class.

<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>
Enter fullscreen mode Exit fullscreen mode

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

<style scoped>
:deep(.el-table__row) {
  background-color: red;
}
</style>
Enter fullscreen mode Exit fullscreen mode

We can see the changes taking place when we add this.
Deep
As I am going add CSS in to this files.

NewTestTableComponent.vue (final)

<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>
Enter fullscreen mode Exit fullscreen mode

App.vue

<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>
Enter fullscreen mode Exit fullscreen mode

Here is the output of the final polishing

(look cleaner then before)
Clean

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.


Happy coding~~~

Oldest comments (0)