Use vUE development process encountered problems or knowledge summary, continuous update…

Last updated: 2019-11-29

Internationalization of 1.

Internationalization plug-in: VUE-i18n

2. Force line breaks and forbid line breaks

Allow multiple lines of content to be displayed on one line. said

white-space : nowrap
overflow: hidden
text-overflow : ellipsis
Copy the code

Force line breaks when content exceeds width

overflow: hidden;
word-wrap:break-word;
overflow-wrap: break-word;
Copy the code

Note: CSS3 renamed <‘ word-wrap ‘> to <‘ overflow-wrap ‘>

3. Display pictures of the same width and height. The width is the width of the screen and the height is the same as the width

<div class="image-header">
  <img :src="food.image"/>
</div>

.image-header
    position: relative
    width:100%
    height: 0
    padding-top : 100%
    img
        position: absolute
        left: 0
        top: 0
        width: 100%
        height: 100%
Copy the code

The important thing is that the height of the parent element is set to 0 and the padding-top is set to 100%

4. Utility classes for converting time

/** * Created by solo on 2018/6/6. */

export function formatDatetime(date, fmt) {
  if(/(y+)/.test(fmt)){
    fmt = fmt.replace(RegExp. $1, (date.getFullYear()+"").substr(4-RegExp. $1.length))
  }

  let obj = {
    "M+": date.getMonth() + 1."d+": date.getDay(),
    "h+": date.getHours(),
    "m+": date.getMinutes(),
    "s+": date.getSeconds()
  }

  for(let key in obj){
    if(new RegExp(` (${key}) `).test(fmt)){
      let str = obj[key] + ' '
      fmt = fmt.replace(RegExp. $1.RegExp. $1.length === 1 ? str : padLeftZero(str))
    }
  }

  return fmt

}


function padLeftZero(str) {
  return ("00" + str).substr(str.length)
}
Copy the code

use

let date = new Date(timestamp)
let fmtDate =  formatDatetime(date, 'yyyy-MM-dd hh:mm')
Copy the code

You can also use third-party libraries: moment.js, dayjs

5. Bind native events to components

<custom @click.native='handleClick'></custom>
Copy the code

Just add. Native after @click to handle native click events directly

6. Transfer values between vUE components

6.1 Transferring Values between Parent and Child Components

  • Parent component passes value to child component, directly throughpropsThe value of
<custom content="hello world"></custom>
Copy the code
  • The child passes a value to the parent, passingemitSend the event
this.$emit('chooseType', type)
Copy the code

The parent component receives events:

<custom content="hello world" @chooseType="handleType"></custom>
Copy the code

6.2 Value transfer between Non-parent and Child Components

Values are mainly passed through the event bus

Mount an empty Vue object on the root node

Vue.prototype.bus = new Vue();
Copy the code

The component that needs to send the event

this.bus.$emit("change", params)
Copy the code

The component that receives events

this.bus.$on("change", (msg) => {
    //do yourself work
})
Copy the code

7. Dynamic components

Dynamically switch display components

<component :is='type'></component>

data(){
	components:{
        component-one,
        component-two
	}
    return{
        type: 'component-one'
    }
}
Copy the code

< Component > is an official vUE tag that dynamically switches components by changing the name of the child component pointed to by IS.

8. V – once the instructions

Render elements and components only once. In subsequent re-rendering, the element/component and all its child nodes are treated as static and skipped. This can be used to optimize update performance.

<! <span v-once>This will never change: {{MSG}}</span> <! - a child element -- -- > < div v - once > < h1 > comment < / h1 > < p > {{MSG}} < / p > < / div > <! <my-component v-once :comment=" MSG "></my-component> <! - ` v - for ` instructions - > < ul > < li v - for = "I in the list of" v - once > {{I}} < / li > < / ul >Copy the code

Transitions and animations

9.1 transition

.fade-enter-active, .fade-leave-active{
	transition: opacity 2s
}
.fade-enter, .fade-leave-to{
	opacity: 0
}
Copy the code

9.2 Animate with inanimate. CSS

CSS <link rel="stylesheet" type="text/ CSS "href="animate. CSS" enter-active-class="animated bounce" leave-active-class="animated shake"> <p v-if="show">hello world</p> </transition> <button @click='toggleShow'>toggle</button>Copy the code

To define the class names of enter-active-class and leave-active-class, which must be animated, what animation effect do you want in the second position

Fixed a bug where there was no animation in the first display

<transition 
	appear 
	enter-active-class="animated bounce" 
	leave-active-class="animated shake" 
	appear-active-class="animated bounce">
	<p v-if="show">hello world</p>
</transition>
Copy the code

Add “appear” and “appearance-active-class” to
.

9.3 Use transitions and animations simultaneously

<transition 
    name="fade"
    type='transition'
    appear 
    enter-active-class="animated bounce fade-enter-active" 
    leave-active-class="animated shake fade-leave-active" 
    appear-active-class="animated bounce">
    <p v-if="show">hello world</p>
</transition>
Copy the code

Add the corresponding class names fade-enter-active and fade-leave-active, and define the transition effect in the style.

.fade-enter-active..fade-leave-active{
	transition: opacity 2s
}
.fade-enter..fade-leave-to{
	opacity: 0
}
Copy the code

Does the total time of animation execution depend on animation or transition? You can specify manually:

// Specify the overall animation time as the transition animation timetype='transition'
Copy the code

You can also specify the total animation duration:

// Specify an animation duration of 10 seconds :duration="10000"// Specify entry duration 5 seconds and exit duration 10 seconds respectively :duration="{enter: 5000, leave: 10000}"
Copy the code

9.4 Transitions of multiple components and elements

  • Multiple element transition
<div id="app">
	<transition name="fade" mode="out-in">
		<div v-if="show" key="hello">Hello world</div>
		<div v-else key="bye">Bye world</div>
	</transition>
	<button @click="toggleShow">Add</button>
</div>
Copy the code

The element needs to be given a key to prevent vUE from reusing the element without animation.

You can specify the switching mode: mode=”out-in” : first out and then in, mode=”in-out” : First in and then out

  • Multi-component transitions are similar to multi-element transitions

9.5 List transition in VUE

Use the transition-group attribute

<div id="app">
	<transition-group name="fade">
		<div v-for="item in list" :key="item.id">
			{{item.title}}
		</div>
	</transition-group>
	<button @click="add2List">Add</button>
</div>


<style type="text/css" >
	.fade-enter-active, .fade-leave-active{
		transition: opacity 2s
	}
	.fade-enter, .fade-leave-to{
		opacity: 0
	}
</style>
Copy the code

10. Dynamic SRC binding of the IMG tag

1) Pictures with fixed paths

Require () before path

<img :src="bookingManageImg" slot="icon"/> bookingManageImg(){ return this.selectedTab === "bookingManage" ? require('.. /assets/manage_focus.png') : require('.. /assets/manage_normal.png') },Copy the code

2) The path of the image in the for loop is not fixed

If you use require() directly in the loop, webpack will use the image as a module, because it is dynamically loaded, so the URL-loader will not be able to resolve the image address, so the module will not be found.

The solution is to use a concatenation: require(‘.. /assets/ ICONS /’ + item.icon + ‘.

List data format:

const list = [
    {
      name: "Food",
      icon: "food"
    },
    {
      name: "Film",
      icon: "movie"},]Copy the code

Layout file:

<div class="item" v-for="item in list">
  <img :src="require('.. /assets/icons/' + item.icon + '.png')" class="icon">
  <div class="name">{{item.name}}</div>
</div>
Copy the code

11. Solution to vuex state loss after page refresh

After the page is refreshed, vuEX data is lost, which brings inconvenience to debugging. Put user login information in sessionStorage to avoid losing.

const USER_INFO = "userInfo";

export default new Vuex.Store({
  state: {
    userInfo: JSON.parse(sessionStorage.getItem(USER_INFO))
  },
  mutations: {
    setUserInfo(state, userInfo){
      // Store it in sessionStorage to prevent state loss after page refresh
      sessionStorage.setItem(USER_INFO, JSON.stringify(userInfo));
      state.userInfo = userInfo
    }
  }
}
Copy the code

12. Return to remember scrollbar position

See article: Vue returns to remember the scrollbar position

13. Modify page Title

In router.js, add the meta to each route and set the title

routes: [
  {
    path: '/login'.name: 'login'.component: Login,
    meta: {title:'login'}}, {path: '/home'.name: 'home'.component: Home,
    children: [].meta: {title:'home'}}]Copy the code

Then change the title dynamically in main.js via the front route

router.beforeEach((to, from, next) = > {
  /* Route change page title */
  if (to.meta.title) {
    document.title = to.meta.title;
  }
  next();
})
Copy the code

14. Enable Gzip compression during packaging

Start by installing the WebPack plug-in

npm install --save-dev compression-webpack-plugin
Copy the code

Add the following code to vue.config.js:

const CompressionPlugin = require("compression-webpack-plugin")

module.exports = {

  // Basic path
  baseUrl: '/'.// Output file directory
  outputDir: 'dist'.// Enable Gzip compression
	configureWebpack: (a)= > {
    module.exports = {
      configureWebpack:config= >{
        if(progress.env.NODE_ENV === 'production') {return{
            plugins: [

              new CompressionPlugin({
                test:/\.js$|\.html$|.\css/.// Match the file name
                threshold: 10240.// Compress data over 10K
                deleteOriginalAssets: false // Do not delete the source file}}},}},}Copy the code

Vue CLI 3 does not have vue.config.js by default. Create a new one in the root directory, the same location as package.json.

15. Vue communicates with android native apps

I have an article on two-way communication between Vue and Android:

Android WebView interacts with JS (Vue)

16. How to use SCSS declared global variables in styles

Sass declares variables like:

$color-primary: #409EFF;
$color-success: #67C23A;
$color-warning: #E6A23C;
$color-danger: #F56C6C;
$color-info: # 909399;
Copy the code

The common reference method is

<style scoped lang="scss"> @import ".. /.. /public/css/index"; .home { color: $color-primary; } </style>Copy the code

You need to import the declared file in the file you want to use before you can use it.

It’s cumbersome, it’s redundant. A more elegant approach can be used: sass-resources-loader

Using sass-resources-loader requires two steps:

  1. Install dependencies

    npm install sass-resources-loader
    Copy the code
  2. Vue. Config. js.

    3. Change the resources path in the code to your own path.

    // vue.config.js
    module.exports = {
      chainWebpack: config= > {
        const oneOfsMap = config.module.rule('scss').oneOfs.store
        oneOfsMap.forEach(item= > {
          item
            .use('sass-resources-loader')
            .loader('sass-resources-loader')
            .options({
              // Provide path to the file with resources
              resources: './path/to/resources.scss'.// Or array of paths
              resources: ['./path/to/vars.scss'.'./path/to/mixins.scss']
            })
            .end()
        })
      }
    }
    Copy the code

For details about the configuration of other environments, see the official website of Sas-Resources-Loader

Once configured, you can use the variables declared by sass in any file.

17. In the child component, change the properties passed by the parent component via props

It is not officially recommended that a child component change a property passed by its parent, and there will be a warning if you do.

But sometimes it is necessary to change the parent’s properties in the child because it is easier… For example, if there is Dialog in the child component, the display and hiding of Dialog should be controlled by the parent component, and the property value in the parent component should be updated synchronously when the child component closes Dialog.

Of course, there are many “correct” ways to do this, such as vuex, such as using parent-child communication, where the child changes its value and sends a notification to the parent to update the corresponding value.

However, both methods are troublesome. I want to pass a variable in the parent component to the child, and the child changes its value, and the variable in the parent component updates automatically.

This uses a “loophole” that encapsulates the value to be passed into an object. If you change the attribute value in the object, there will be no warning. Because the object is the same object, but the value inside has changed.

The parent component is as follows. Data visible: {value: false} is an object and cannot be written as visible: false.

<template>
  <child :visible="visible"/>
</template>

<script>
  export default {
    components: {
    	child
    },
    data(){
    	return{
    		visible: {value: false}
    	}
    }
  }
</script>
Copy the code

The sub-components are as follows:

<el-dialog :visible.sync="visible.value">
Copy the code

When the child component changes the value, it changes the value property in the Visible object. This allows you to change the value of the parent component directly from the child component.

18. The realization of the nine grids

Implement a similar sudoku code:

<template> <div class="view-home"> <div class="category-wrapper"> <div class="category-name"> Class a </div> <div class="icons"> <div class="item" v-for="item in list"> <img :src="require('.. /assets/icons/' + item.icon + '.png')" class="icon"> <div class="name">{{item.name}}</div> </div> </div> </div> </div> < / template > < script > const LIST = [{name: "movie," icon: "movie"}, {name: "food," icon: "the food"}, {name: "hair," icon: "Hair"}, {name: "swimming around," icon: "around"}, {name: "hotels," icon: "hotel"}, {name: 'behalf, con: "dg"}; export default { components: {}, data() { return { list: ICON_LIST, } }, } </script> <style scoped lang="scss"> .view-home { display: flex; flex-direction: column; width: 100%; padding: px2rem(10); box-sizing: border-box; .category-wrapper { width: 100%; display: flex; flex-direction: column; background-color: white; .category-name { font-size: $font-size-normal; color: $text-main; padding: px2rem(12); border-bottom: px2rem(1) solid $border-third; } .icons { display: flex; flex-direction: row; flex-wrap: wrap; .item { display: flex; flex-direction: column; justify-content: center; align-items: center; width: 25%; padding: px2rem(10) 0; .icon { width: px2rem(40); height: px2rem(40); } .name { font-size: $font-size-small; color: $text-normal; margin-top: px2rem(10); } } } } } </style>Copy the code

Key points:

  1. To wrap, use the following three lines of code:

    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    Copy the code
  2. Several ICONS per row, controlled by the width of the item. If there are four ICONS per row, the width of each item is 25%, and if there are five ICONS per row, the width of each item is 20%.

19. Slide sideways out of width

When the width of the child component exceeds that of the parent component, it slides horizontally. The parent component can be the root element of the entire screen or a specific element. Just set up the CSS. Set the parent element’s class=parent and the child element’s class=child

Parent {// other styles are omitted, listing only the code necessary to control horizontal sliding display: flex; overflow-x: auto; overflow-y: hidden; .child{// other styles are omitted, and only the code necessary to control horizontal sliding is listed // This clause means that the size of flex-shrink is not compressed: 0; }}Copy the code

Add these lines to your CSS code and you can swipe sideways.

20. Only N lines are displayed

There is often a need to display only two or three lines, with any extra indicated by ellipsis. Application scope: This method is applicable to WebKit browsers and mobile terminals because WebKit CSS extension attributes are used.

Note: – Webkit-line-clamp is used to limit the number of lines of text displayed in a block element. To achieve this effect, it needs to combine the other WebKit properties. Common combination properties: display: -webkit-box: must be combined to display an object as an elastic stretchy box model. -webkit-box-orient: Attribute that must be combined to set or retrieve the arrangement of child elements of a flex box object.

overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
Copy the code

21. In flex layout, single elements are aligned to the right

In the following image, the name, gender, comment icon line has three elements, which is the Flex layout, with the first two elements to the left and the comment icon to the right.

Given that the layout of the parent element is

display: flex;
flex-direction: row;
align-items: center;
Copy the code

This can be done in three ways:

  1. Add another div to the name and gender elements and set this divflex: 1. Disadvantage is more layer nesting, a little trouble.
  2. Set the comment icon element
    flex: 1;
    text-align: right;
    Copy the code
  3. Set the comment icon element
    margin-left: auto;
    Copy the code

The latter two methods are relatively simple and recommended.