vue+element learning record

1, Vue introduction

Author: You Yuxi

Official website: https://cn.vuejs.org/

       Vue The author is from China. His name is you Yuxi. His major is not computer science. During his college years, he majored in interior art and art history
    He had a master's degree in art design and technology. It was during his master's degree that he came into contact with him by chance JavaScript ,Since then, I have been deeply attracted by this programming language,
    Started his front-end career. In February 2014, a front-end development library was developed Vue.js. ((quoted from Baidu Encyclopedia)
  • Question 1: what is Vue:

    Vue is a progressive framework for building user interfaces (free combination and flexible reuse). Vue's core library only focuses on view layers, which is not only easy to start, but also easy to integrate with third-party libraries (Vue Router: jump, axios: communication, vuex: state management).

  • Question 2: what are the advantages over other frameworks:

    https://cn.vuejs.org/v2/guide/comparison.html

    Angular: the front-end framework acquired by Google is characterized by moving the background MVC mode to the front-end and adding the concept of modular development

    React: produced by Facebook, a high-performance JS front-end framework; The feature is that a new concept [virtual DOM] is proposed for
    Reduce real DOM operations, simulate DOM operations in memory, and effectively improve the front-end rendering efficiency

    Vue: it combines the advantages of Angular (Modular) and React (virtual DOM), and is easy to use, flexible and efficient

  • Question 3: Vue's core features:

    • Responsive data binding

    • Composable view components

    • Virtual DOM

    • MVVM mode

      MVVM is a design idea
      DOM Listeners and Data Bindings are regarded as two tools, which are the key to realizing two-way binding.
      From the View side, the DOM Listeners tool in the ViewModel will help us monitor the changes of DOM elements on the page. If there are changes, change the data in the Model; From the Model side, when we update the data in the Model, the Data Bindings tool will help us update the DOM elements in the page.

2, Element introduction

vue2.0-https://element.eleme.io/#/zh-CN

vue3.0-https://element-plus.gitee.io/zh-CN/

Website rapid prototyping tool, a set of desktop component library based on Vue 2.0 for developers, designers and product managers

3, Development environment

brew,node.js, npm and Vue cli;

  • brew: it is a software package management tool, similar to yum under centos or apt get under ubuntu. It is very convenient and avoids the inconvenience of manual compilation and installation
  • node.js: JavaScript running on the server side
  • npm: Yes, along with node JS is a package management tool in the JavaScript world. Through npm, you can install, share and distribute code, and manage project dependencies (npm has been integrated into the new version of nodejs)
  • vue cli: a scaffold officially provided to quickly generate a vue project template; The pre-defined directory structure and basic code are just like when we create Maven project, we can choose to create a skeleton project, which is the scaffold, and our development is faster;

1. Install node js

Installation tutorial: https://www.runoob.com/nodejs/nodejs-install-setup.html

Download from the official website: http://nodejs.cn/download/

Brew Download: brew install -g node

Set Taobao image accelerator

npm install cnpm -g
npm install --registry=https://registry.npm.taobao.org
 When the back npm When the installation fails, you can use cnpm Try replacing it

2. Installing VUE-CLI

vue-cli:

At the command console, enter, - g for global installation

💡 npm install vue-cli -g

Check whether the installation is successful

💡 vue list

3. Create a vue project

To create a project from Vue cli scaffolding:

vue init webpack vue_test


Run project:

4. Engineering structure

5. Editor environment preparation

Recommendation: vsCode, webStorm, idea (the degree of recommendation decreases in order)

idea: install Vue JS plug-in (the genuine version needs to be cracked, but the community version can't find the plug-in) https://blog.csdn.net/m0_47333020/article/details/108182429

webStorm: no need to install plug-ins (genuine version needs to be cracked)

vsCode: install corresponding plug-ins (relatively convenient) https://blog.csdn.net/yujing1314/article/details/90340647

4, Adding, deleting, modifying and querying based on Vue

design sketch

1. Install routing, element UI and axios communication tools

npm install vue-router

npm i element-ui -S

npm install axios

[external chain picture transfer failed. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-fvrrzpxg-164078161641)( https://s3-us-west-2.amazonaws.com/secure.notion-static.com/f0f72c1b-7bf7-48fc-ba14-15481a80631e/Untitled.png )]

2. In main JS: root directory - > main js

import router from './router'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

import Vue from 'vue'
import App from './App'
import router from './router'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.config.productionTip = false

Vue.use(ElementUI);

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

Configure agent (solve cross domain problems): root directory - > config - > index js

proxyTable: {
  '/': {
		// The request address of the back-end interface is used for local access
    target: 'http://114.116.255.239:8081',
    // secure: false, / / this parameter needs to be configured if it is an https interface
    changeOrigin: true, // If the interface is cross domain, you need to configure this parameter
    pathRewrite: {
      '^/': ''
    }
  }
}

Universal request tool encapsulation: src -- utils -- API js

import axios from 'axios';

//Request encapsulation
let base = "";

//post request encapsulation, in the form of Key and Value
export const postKeyValueRequest=(url,params)=>{
  return axios({
    method: 'post',
    url: `${base}${url}`,
    data: params,
    transformRequest: [function (data) {
      let ret = '';
      for(let i in data) {
        ret += encodeURIComponent(i)+'='+encodeURIComponent(data[i])+'&';
      }
      console.log(ret);
      return ret;
    }],
    headers: {
      'Content-Type':'application/x-www-form-urlencoded'
    }
  })
};

//post request encapsulation, json form
export const postRequest = (url, params) => {
  return axios({
    method: 'post',
    url: `${base}${url}`,
    data: params
  })
}

//put request encapsulation
export const putRequest = (url, params) => {
  return axios({
    method: 'put',
    url: `${base}${url}`,
    data: params
  })
}

//get request encapsulation
export const getRequest = (url, params) => {
  return axios({
    method: 'get',
    url: `${base}${url}`,
    params: params
  })
}

//delete request encapsulation
export const deleteRequest = (url, params) => {
  return axios({
    method: 'delete',
    url: `${base}${url}`,
    params: params
  })
}

Routing configuration (page access and jump): src - router - index js

import Vue from 'vue'
import Router from 'vue-router'

import {postRequest} from "../utils/api";
import {getRequest} from "../utils/api";
import {postKeyValueRequest} from "../utils/api";
import {putRequest} from "../utils/api";
import {deleteRequest} from "../utils/api";

import Emp from "../views/Emp"

//The global variable set as vue is convenient to be referenced in the component
Vue.prototype.postRequest = postRequest;
Vue.prototype.getRequest = getRequest;
Vue.prototype.postKeyValueRequest = postKeyValueRequest;
Vue.prototype.putRequest = putRequest;
Vue.prototype.deleteRequest = deleteRequest;
Vue.use(Router)
Vue.config.productionTip = false;

//Define routing rules
export default new Router({
  routes: [
    {
      path: '/',
      name: 'Employee list',
      component: Emp,
      hidden : true
    }
  ]
})

Emp.vue content:

<template>
  <div style="margin: 50px">
     <!--increase-->
     <el-button size="small" type="success" style="margin-bottom:10px" @click="dialogVisible = true">add to</el-button>
     
     <el-input size="small" v-model="employee.name" placeholder="Please enter your name" 
     style="width:200px; margin-left:30px">
     </el-input>

     <el-select v-model="employee.gender" placeholder="Gender" size="small">
      <el-option label="All" value=""></el-option>
      <el-option label="male" value="1"></el-option>
      <el-option label="female" value="0"></el-option>
    </el-select>

		<!--search-->
    <el-button size="small" type="primary" style="margin-bottom:10px" @click="initData()">search</el-button>
     
     <!-- List data -->
     <el-table
      :data="empList"
      stripe
      style="width: 100%">
      <el-table-column
        type="selection"
        width="50">
      </el-table-column>
      <el-table-column
        prop="id"
        label="id"
        width="180">
      </el-table-column>
      <el-table-column
        prop="name"
        label="full name"
        width="180">
      </el-table-column>
      <el-table-column
        label="Sex "
        width="180">
        <template #default="scope">
          <el-tag v-if="scope.row.gender === '1'">male</el-tag>
          <el-tag v-else type="warning">female</el-tag>
        </template>
      </el-table-column>
      <el-table-column
        prop="address"
        label="address"
        width="180">
      </el-table-column>
      <el-table-column
        prop="email"
        label="mailbox"
        width="180">
      </el-table-column>
      <el-table-column
        prop="phone"
        label="Telephone"
        width="180">
      </el-table-column>
      <el-table-column
        prop="department" 
        label="department"
        width="180">
      </el-table-column>
      <el-table-column
        label="operation">
        <template #default="scope">
           <el-link type="warning" @click="update(scope.row)">modify</el-link>
           <el-link type="danger" @click="del(scope.row.id)">delete</el-link>
        </template>
      </el-table-column>
     </el-table>

    <!-- Add bullet frame -->
    <el-dialog
      title="add to"
      :visible.sync="dialogVisible"
      width="30%">
      <el-form label-position="left" label-width="50px" :model="employee">
        <el-form-item label="id">
          <el-input v-model="employee.id"></el-input>
        </el-form-item>
        <el-form-item label="full name">
          <el-input v-model="employee.name"></el-input>
        </el-form-item>
        <el-form-item label="address">
          <el-input v-model="employee.address"></el-input>
        </el-form-item>
        <el-form-item label="Gender">
          <el-radio v-model="employee.gender" label="1">male</el-radio>
          <el-radio v-model="employee.gender" label="0">female</el-radio>
        </el-form-item>
        <el-form-item label="department">
          <el-select v-model="employee.department" placeholder="Please select">
            <el-option label="ABC" value="ABC"></el-option>
            <el-option label="AIDC" value="AIDC"></el-option>
        </el-select>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">Cancel</el-button>
        <el-button type="primary" @click="add()">determine</el-button>
      </span>
    </el-dialog>

    <!-- Modify bullet frame -->
    <el-dialog
      title="modify"
      :visible.sync="updateDialogVisible"
      width="30%">
      <el-form label-position="left" label-width="50px" :model="employee">
        <el-form-item label="id">
          <el-input v-model="employee.id"></el-input>
        </el-form-item>
        <el-form-item label="full name">
          <el-input v-model="employee.name"></el-input>
        </el-form-item>
        <el-form-item label="address">
          <el-input v-model="employee.address"></el-input>
        </el-form-item>
        <el-form-item label="Gender">
          <el-radio v-model="employee.gender" label="1">male</el-radio>
          <el-radio v-model="employee.gender" label="0">female</el-radio>
        </el-form-item>
        <el-form-item label="department">
          <el-select v-model="employee.department" placeholder="Please select">
            <el-option label="ABC" value="ABC"></el-option>
            <el-option label="AIDC" value="AIDC"></el-option>
        </el-select>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="updateDialogVisible = false">Cancel</el-button>
        <el-button type="primary" @click="updateData()">determine</el-button>
      </span>
    </el-dialog>

  </div>
</template>

<script type="text/javascript">
export default {
  name: "Task",
  data() {
    return {
      employee: {
        id: "",
        name: "",
        gender: "",
        address: "",
        email: "",
        phone: "",
        department: ""
      },
      empList:[],
      dialogVisible: false,
      updateDialogVisible: false
    }
  },
  mounted() {
    this.initData();
  },
  methods: {
    clearDara() {
      this.employee = {
        id: "",
        name: "",
        gender: "",
        address: "",
        email: "",
        phone: "",
        department: ""
      }
    },
    // initialization
    initData() {
      this.getRequest("employee/query", this.employee).then(res=>{
        if(res.data.code == 0) {
          this.empList = res.data.info;
        }
      })
    },
    // increase
    add() {
      this.postRequest("employee/add", this.employee).then(res=>{
        if(res.data.code == 0) {
          this.$message.success("Successfully added!");
          this.initData();
        } else {
          this.$message.error("Failed to add!" + res.data.msg);
        }
      })
      this.dialogVisible = false;
      this.clearDara();
    },
    // to update
    update(emp) {
      this.employee = emp;
      this.updateDialogVisible = true;
    },
    updateData() {
      this.putRequest("employee/update", this.employee).then(res=>{
        if(res.data.code == 0) {
          this.$message.success("Update succeeded!");
          this.initData();
        }else {
          this.$message.error("Update failed!" + res.data.msg);
        }
      })
      this.updateDialogVisible = false;
      this.clearDara();
    },
    //delete
    del(id) {
      this.$alert('Delete this record', 'Tips', {
          confirmButtonText: 'determine',
          callback: action => {
            this.deleteRequest("employee/delete/" + id).then(res=>{
            if(res.data.code == 0) {
              this.$message.success("Delete succeeded!");
              this.initData();
            }else {
              this.$message.error("Deletion failed!" + res.data.msg);
            }
          })
          }
        });
    }
  }
}
</script>

<style scoped>
</style>

Back end main logic:

package com.controller;

import com.pojo.BaseResponse;
import com.pojo.Employee;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author 10018318
 * Provide interface
 */
@RestController
@RequestMapping("/employee")
public class EmployeeController {
  private static final Map<Integer, Employee> employeeData = new LinkedHashMap<>();

  static {
    for (int num = 1001; num <= 1010; num++) {
      employeeData.put(num, new Employee(num, "Li Jiegui", "1", "lijiegui1@shein.com", "15874423919", "Nanjing", "ABC"));
    }
  }

  /**
   * Query employee information
   */
  @GetMapping("/query")
  public BaseResponse getEmployeeList(Employee employee) {
    List<Employee> employeeList = employeeData.entrySet().stream()
        .filter(employeeEntry -> (StringUtils.isEmpty(employee.getName()) ? true : employeeEntry.getValue().getName().contains(employee.getName())) &&
            (StringUtils.isEmpty(employee.getGender()) ? true : employeeEntry.getValue().getGender().equals(employee.getGender())))
        .map(Map.Entry::getValue).collect(Collectors.toList());
    return BaseResponse.ok(employeeList);
  }

  /**
   * Add employee
   * @param employee
   * @return
   */
  @PostMapping("/add")
  public BaseResponse addEmployee(@RequestBody Employee employee) {
    if (!employeeData.containsKey(employee.getId())) {
      employeeData.put(employee.getId(), employee);
      return BaseResponse.ok("Successfully added!");
    }
    return BaseResponse.fail("Failed to add, id Repeated!");
  }

  /**
   * Delete employee
   * @param id
   * @return
   */
  @DeleteMapping("/delete/{id}")
  public BaseResponse delEmployeeById(@PathVariable Integer id) {
    employeeData.remove(id);
    if(!employeeData.containsKey(id)) {
      return BaseResponse.ok("Delete succeeded!");
    }
    return BaseResponse.fail("Deletion failed!");
  }

  /**
   * Update employees
   * @param employee
   * @return
   */
  @PutMapping("/update")
  public BaseResponse updateEmployee(@RequestBody Employee employee) {
    employeeData.put(employee.getId(), employee);
    return BaseResponse.ok("Update succeeded!");
  }
}

Entity:

@Data
@AllArgsConstructor
public class Employee {
  private Integer id;

  private String name;

  private String gender;

  private String email;

  private String phone;

  private String address;

  private String department;
}

5, How to deploy

npm run build

[external chain picture transfer failed. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-pc7olzsj-164078161641)( https://s3-us-west-2.amazonaws.com/secure.notion-static.com/eefefaa1-bbbf-4d20-908a-da9ad27980c1/Untitled.png )]

  • Deployment method:

    1. Copy the contents under the dist file to the static file under the resource under the springboot project

    [external chain picture transfer failed. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-kc4m2pj0-164078161642)( https://s3-us-west-2.amazonaws.com/secure.notion-static.com/9dff1a66-fb61-464c-9b41-f4004aa14528/Untitled.png )]

    2. Through nginx proxy,

    #user  nobody;
    worker_processes  1;
    
    events {
        worker_connections  1024;
    }
    
    http {
        include       mime.types;
        default_type  application/octet-stream;
        sendfile        on;
        keepalive_timeout  65;
    
        server {
        listen 80;
        server_name duxing.online;
    
        root  /home/duxing/front/dist/;
        index   index.html;
        try_files $uri $uri/ /index.html last;
    
            # gzip config
            gzip on;
            gzip_min_length 1k;
            gzip_comp_level 9;
            gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
            gzip_vary on;
            gzip_disable "MSIE [1-6]\.";
    
            location ^~ /prod-api/ {
                add_header 'Access-Control-Allow-Origin' *;
                add_header 'Access-Control-Allow-Credentials' 'true';
                add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS';
                proxy_pass http://127.0.0.1:8888/;
                proxy_set_header   X-Real-IP         $remote_addr;
                 proxy_set_header   Host              $http_host;
                 proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
            }
    	}
    	
    	server {
        listen 8085;
        server_name www.duxing.online;
    
        root  /home/duxing/back/dist/;
        index   index.html;
        try_files $uri $uri/ /index.html last;
    
            # gzip config
            gzip on;
            gzip_min_length 1k;
            gzip_comp_level 9;
            gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
            gzip_vary on;
            gzip_disable "MSIE [1-6]\.";
    
            location ^~ /prod-api/ {
                add_header 'Access-Control-Allow-Origin' *;
                add_header 'Access-Control-Allow-Credentials' 'true';
                add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS';
                proxy_pass http://127.0.0.1:8888/;
                proxy_set_header   X-Real-IP         $remote_addr;
                 proxy_set_header   Host              $http_host;
                 proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
            }
    	}
    }
    

reference resources:

https://cn.vuejs.org

https://juejin.cn/post/6844903709055401991

https://cn.vuejs.org/v2/guide/comparison.html

Keywords: Front-end Vue.js

Added by fogofogo on Mon, 03 Jan 2022 06:25:53 +0200