Introduction to the

Hello everyone, I am Wangly19. This article is mainly to summarize some routines I have summarized using vue.js, and I can do some missing points. If there are any interesting tips, please leave me a comment so I can learn them. This article is pure text, no pictures, I suggest you to read on the subway, most of you may know, but also have not seen. Check carefully to fill the following gaps.

Using these tips will improve the quality and reading of your code as you work on your project. Even better with my previous post:

  • To summarize some basic optimizations I made for the launch of the Vue project: click to read

The body of the

In the beginning, not all knowledge points are in Vue, but in Vue use of some tricks, which also contains some JavaScript tips. Then you can use it in other places.

Package management tool

First of all, I use YARN as the main package management tool. When using NPM, I encountered some problems such as packet loss, card package and rigid installation process, so I use YARN without hesitation instead of NPM as the main package management tool. In addition to the above issues, YARN has also actively exposed a yarn-erro.log error stack file to developers. Although it looks a little chicken ribs, it also shows that it is very thoughtful in some ways.

package.json

We have all used different scaffolding, such as: vue-cli create-React-app nest-cli umi-cli, taro-cli and so on out of the box some customized scaffolding, we just need to use the official demo and quick start to install and use. But also in so many scaffolds it’s not really script shell friendly, maybe some of them are run serve to start the project, some run start, and so on and so forth, so if you use this kind of scaffolding, It’s better to give yourself a unified Script shell. So we don’t get out of the mess. My personal use is to run: dev and package: build. (for reference only).

"scripts": {
    "dev": "vue-cli-service serve"."build": "vue-cli-service build"
  }
Copy the code

Path alias @…

In a real project, for better logical layering, or for monorepo, the project’s large and small directories are very noisy, resulting in a lot of unfriendly path references due to the consumption of reference resources. There are a lot of risks… References to/and other paths are very bad, so proxy paths to certain resources can be very readable to developers and collaborators, rather than repeating useless symbols. In my project, the code directory has the following. Specific can undertake a few appropriate configuration according to oneself hobby.

module.exports = {
  resolve: {
    alias: {
      // Set the path proxy
      The '@': resolve('src'),
      'components': resolve('src/components'),
      'api': resolve('src/api'), 
      'icons': resolve('src/icons'),
      The '#': resolve('src/assets'),
      'utils': resolve('src/utils')}}}Copy the code

Global SASS file management

If you use sass/ SCSS, you will define your own custom global style, such as @function, @extends CKass interface, @mixins, global variables, etc. But a lot of people use @import for each component, which means you need to add @import for every component you need to use… /file path, which is very troublesome. So we need to do once reference, lifetime benefit, in Vuecli can be very convenient for global introduction

css: {
  sourceMap: false.loaderOptions: {
    scss: {
      additionalData: ` @import "~@/assets/styles/norm.scss"; @import "~@/assets/styles/mixins.scss"; `
    },
    sass: {
      additionalData: ` @import "~@/assets/styles/norm.scss" @import "~@/assets/styles/mixins.scss" `}}}Copy the code

File summary after packaging

After we package the Vue project, often the directory in dist file is very messy, there are many js files exposed outside, very ugly, so we need to set assetsDir: ‘static’ to store the package file to define. In this way, all the resource files will be stored in the directory you define after packaging. We just need to put the index. HTML and static in our nginx service deployment.

module.exports = {
    publicPath: '/',
    outputDir: 'dist',
    lintOnSave: true,
    assetsDir: 'static'
}
Copy the code

The Proxy cross-domain

We are all familiar with cross-domain Proxy. In Vue, it is very convenient to carry out domain name Proxy by configuring Proxy. Of course, this needs some cooperation from the background. You can also set up multiple proxies if your project involves multiple domains. Just add the following configuration to devServe.

proxy: {
  "/api": {
    target: 'http://....... '.changeOrigin: true.// Whether to change the domain name
    ws: true.// socket
    pathRewrite: {
      // Overwrite the path
      "/api": ' ' // Rewrite the concatenation content}},... }Copy the code

Configure the developer and Build packages differently

Most developers like to write the Vue config in a file, which seems to be fine, but as the environment changes, project optimization, WebPack plug-ins, and other specific configurations come in, it will become a little messy, this time you can consider doing a separate configuration. I introduced a config for each environment using process.dev, and posted my configuration below. I created a new config directory in the project root directory, which unpackages the public methods into a public.js and compiles the rest separately for production and offline environments.

-- config -- dev.js -- build.js -- public.jsconst devConfig = require('./config/dev')
const buildConfig = require('./config/build')
module.exports = process.env.NODE_ENV === 'development' ? devConfig : buildConfig
Copy the code

Global methods to use or not to use

There is nothing wrong with mounting some common methods in Vue’s Prototype. It is recommended to use carefully, and there are still only a few localstorage methods hanging on it. So, it’s kind of a personal thing, but the reason I don’t like to use typeScript is because I like to write typeScript, and if you mount too many things on a Vue prototype, you also need to put in some type declaration, some kind of credential to declare the mount method.

vue.prototype.local = localStorageUtils
Copy the code

Avoid component style conflicts

To avoid conflicts during development, there are two ways to create a separate style for the Vue Component when writing it: cssModule and scoped. Most of the time, we use scoped to avoid conflicts between component styles, which is as simple as binding scoped to the style. When you create a CSS file, just add.module to it and it automatically identifies as a cssModule module, such as global.module.scss.

<style scoped>
</style>
Copy the code

Keep the routing page name and component name at all times

When we declare a Vue-router, I personally recommend that we keep the name attribute and the name of the component to be mounted, because we may need to cache the page data and exclude the page data, so it is very convenient to cache some routing components and data on keepalive. Without having to fix the problem later.

// component
export default {
	name: 'Home'.data: () = >({})... }// router
{
	path: '/home'.name: 'Home'.component: () = > import('... ')}Copy the code

Computational attribute utility

Computational properties are very powerful. During development, I strongly disapprove of doing complex logical operations, which not only break the readability of the template, but also make it very difficult to extend the code. Try to write some logical operations into the computed properties. Here’s a common example:

DEMO: data filtering

This is a very common computing attribute for filtering data. Its main function is to filter out the attributes that need to make vIf judgment in vFor first, so as to achieve the correct DOM elements that we need to render, optimize the performance and have good management and scalability for data.

// Calculate the properties
computed: {
  filterList: function () {
  return this.showData.filter(function (data) {
  	// Return the data to be displayed
    return data.isShow
  })
}
  
// DOM
  
<ul>
  <li v-for="item in filterList" :key="item.id">
  {{ item.name }}
  </li>
</ul>
Copy the code

Collection method

The following is what happens to the Option API when it comes to adding or deleting tables, which in my opinion is a little bit of reading fatigue, because there aren’t many of them, and the possibility of change isn’t very great. Then we can carry out a factory-style packaging for unified management, in the occurrence of a leak can quickly locate the problem place.

getData() {}
createRow() {}
updateRow() {}
deleteRow() {}
Copy the code

Use a common method to manage the addition and deletion of tabular data. Of course, if the complexity of the operation itself is high, then still consider splitting out the code of the operation to prevent the current factory from reading obstruction.

tableFactory(action) { switch (action) { case 'update': ... break; case 'create': ... break; case 'delete': ... break; default: // ... Get the list break by default; }}Copy the code

Mixins with

I made it clear a long time ago that I personally don’t like mixins, but I have to use them. So a middle ground is to have a fixed format for the variables that mix into the mixin definition. My naming rules are as follows. All declarations are marked with a capital M, and the Methods are also mixed in.

Mip: 'xxxx'.Mmsg: 'xxxxxxxxxxxxxxx'
Copy the code

Maintain the data validation specification for Props

I personally strongly recommend using some basic constraints on Props, such as data type, mandatory, default value, validation rule, etc., rather than registering a Porps namespace directly through an array.

props: {
	test: {
    	type: String.default: ' '
    },
    test2: {
    	type: [Number.String].default: 1
    },
    test3: {
    	required: false.type: Object}}Copy the code

V-model and sync modifiers

Most of the time, there are many props in the component. It is known that it is illegal to change the props value directly in Vue, even though it seems to work. Of course, the process would still be to throw the event and parameter through the $emit, and then the parent component would receive the parameter assigned to the value passed to the component, so the process of passing the value from the parent component to the parent component would be finished, but this step is very noisy, so with some simple data format, I chose to use the V-Model and sync modifier for data transfer management.

Custom component V-Model

Registered the value attribute, paid attention to in the first through the props have to value, is actually use the $emit to throw out a name for the input (must), will need to modify the value passed in, can be in the negative components through the v – model instructions for data binding.

Porps: {value: {type: [String, Number]}} $emit('input', 'emit')Copy the code

Sync modifier

This modifier is very interesting. When thrown from $emit, use the props name for the update: binding.

this.$emit('update:title', 'newTitle')
Copy the code

Component name use

Most of the time, we define the name in the component as the name we would use in the template. We recommend using the hump name here because the hump name is resolved well in vue.

/ / GanMessage. Vue components
export default {
	name: 'GanMessage'. }// Use after introduction
components: {
	[GanMessage.name]: GanMessage
}

// Template
<template>
	<gan-message/>
</template>
Copy the code

Slot Indicates the default slot content

When you add a content element to a slot, it will be treated as a default content element. When you use a slot, it will be overwritten and treated as a default content element.

<slot>
	<p>The default content</p>
</slot>
Copy the code

Template engine debugging

Most of the time, writing logic on a template is very difficult to debug. It’s very straightforward, and for some values, it becomes unmanageable, so in a development environment, I always hang a global console.log method on the prototype for debugging.

vue.prototype.$logs = window.console.log;

/ / use
<template>
	{{$logs('1111')}}
</template>
Copy the code

Filter use

For filter, actually has been a very small thing, in many cases are not many people to use it, I was on the global symbol and time formats used to filter and discipline, such as the need to format the flower time, symbols for Numbers to add money, money for micrometer comma filters can be used to solve the problem. So it is very convenient to use it reasonably in the right scenario.

filters: {
    $time (timeText) {
      return. }}Copy the code

Get the lifecycle of the data

Data acquisition has always been controversial. Most students get data from created, but I personally obtain background data in beforeMount

async beforeMount(){
	const data = await getUserInfo();
}

Copy the code

Use async and await

Most of the time, promises are handled by.then,.catch,.finally. But in fact, I prefer to use async asynchronous function for Pormise processing, we only need to get the data, and catch the try exception can quickly conduct a good troubleshooting and throw the error. See the lifecycle of getting the data above

async beforeMount(){
	try {
      const data = await getUserInfo()
    } catch (error) {
      console.log(error)
    } finally{}}Copy the code

Manage request loading status

In most data requests will add a loading state display, friendly to the user or user some good hints, most of the novice front end is a Promise for success and failure of a state change. This is no doubt adding unnecessary expense. You only need to make one change in the finally. No more useless code, and no unnecessary interference with the processing of data.

async beforeMount(){
	// Start loading
	this.loading = true
	try {
      const data = await getUserInfo()
    } catch (error) {
      console.log(error)
    } finally {
    	// Stop loading
    	this.loading = false}}Copy the code

Try to avoid frequent watches

For listener within a component if possible don’t use it frequently, if you are in a component frequently watch will be used to monitor the change of the multiple data sources to the business development, then illustrate the component or whether this demand itself exists very unreasonable place, most demand are active trigger, Rather than relying on one condition as necessary for the task. So, keep listeners to a minimum, but it’s a great experience to use them if you really need them. It’s all up to the developer to try and figure out if they need to use listeners as the best solution.

Turn on performance tracking

One of the most interesting things about Vue is the vue.config. performance API, which is officially described as follows:

Set to true to enable performance tracking for component initialization, compilation, rendering, and patching in the performance/timeline panel of the browser development tools. Only available in development mode and on browsers that support the Performance. Mark API. @ vue. Js official

The suggestion is to open it in a development environment, not online. Just modify the state in main.js.

vue.config.performance = process.env.NODE_ENV ! = ="production";
Copy the code

Env configuration

Env files are known to exist in scaffolding projects, but what exactly are they? In fact, they are just places to store static constants. When we use WebPack, we are in a process that is actually inside Node.js, so most of the variables stored are configuration information. Are personal private information, so for the sake of project security, remember to delete when uploading the repository, to avoid illegal personnel through the account information caused some trouble to you. (To use in Vue, add VUE_APP to follow its specification)

NDOE_ENV=development
APP_KEY=***********
HOST_URL=**********
Copy the code

Attributes emissions

The issue of Vue’s Option API emission has always surprised people. One thousand people have different styles, and it is difficult to achieve unity. It is suggested to summarize a template that is convenient for you and make it into a template format, and then automatically generate this architecture through shortcut keys next time. When you write components, it’s easy. Attached is a copy of my basic template

export default {
	name: 'name'.components: { // Mount a},
    created(){} // Data acquisition
    beforeMount() {}, // Data acquisition
    data: () = > ({}), // Response data
    computed: {} // Calculate the set of attributes
    methods: {} // Set of methods.// Destroy unwanted resources on the page
}
Copy the code

conclusion

Most of the time, I now find it easy to touch the bottleneck when using Vue. When I want to go deeper, I find the road ahead is very narrow. Most of the time I’m making things that make perfect with practice. Although the skills are good, ultimately cannot leave the growth, pay attention to practice can make perfect, do not be obsessed with some of the technical things, for growth has no effect, even let their own mentality feel very strong, have a lot of confidence, in fact, is only a P0 programmer. I’ve seen too many two-year programmers using vUE with a shuttle that doesn’t have any logic at all. It’s like doing tasks for the sake of completing tasks, ignoring your own growth.

This article is a previous article, which involves very simple routines and techniques, and does not involve vueRouter and Vuex, this will be updated in the next set oh. First-hand information can catch me to get the article push.

The author is now looking for a job, college degree. I worked for more than a year. Prepare to change the environment to study, update the article is slow, if the article is useful, learn something, then readily click like it. There is an internal push opportunity can also didi me oh.