Use scaffolding to create projects and use components to develop

Single file component

Single file component means that one file corresponds to one component. The name of single file component is usually xxx.vue (the naming convention is the same as that of component name). This file is only specified by the Vue framework. It can recognize that the browser cannot directly open and run

  • The Vue framework can compile xxx.vue files into html js css code that the browser can recognize

The content of xxx.vue file includes three categories: structural HTML code (template tag), interactive JS code (script tag), and style CSS code (style)

  • VSCode tool plug-in: vetur has a highlighted code when writing the xxx.vue file, and you can also generate code by entering , Auto Rename TagPlug-in facilitates modifying tag names at the same time

export and import

export is used to expose data (properties, methods and objects): Common exposure methods include respective exposure, unified exposure, and default exposure

// Use the m1.js file to expose properties and methods separately
export let school = 'Silicon Valley';

export function teach() {
    console.log("We can teach you development skills");
}

// The way objects are used in the m2.js file is uniformly exposed
let school = 'Silicon Valley';
function findJob(){
    console.log("We can help you find a job!!");
}
export {school, findJob};

// Use default exposure in m3.js file (can expose any type, usually an object)
export default {
    school: 'ATGUIGU',
    change: function(){
        console.log("We can change you!!");
    }
}

import is used to import data (properties, methods, objects) exposed in js files

<body>
    <script type="module">
        // Common import method, m1, m2, m3 store exposed data respectively
        import * as m1 from "./src/js/m1.js";
        import * as m2 from "./src/js/m2.js";
        import * as m3 from "./src/js/m3.js";
 
        // The destructuring assignment form uses exposed data in the form of objects. When the attribute method has the same name, use the as keyword.
        // import {a, b} from 'module identifier'
        import {<!-- -->school, teach} from "./src/js/m1.js";
        import {<!-- -->school as guigu, findJob} from "./src/js/m2.js";
        // default is a keyword and cannot be used directly, you need to use the alias mechanism
        import {<!-- -->default as m3} from "./src/js/m3.js";

        // A simple form of import but only for default exposure. m3 is an alias that stores exposed data and methods.
        // import any name from module identifier’
        import m3 from "./src/js/m3.js";
        // Accessing exposed properties and methods requires adding a default structure
        console.log(m3.default.school);
    </script>
</body>

Write the introduction of all modules into a separate js file, use the script tag in index, html, and the type is module directly Just import this js file

//Entry file introduced by the module
import * as m1 from "./m1.js";
import * as m2 from "./m2.js";
import * as m3 from "./m3.js";
 <body>
    <!--Introduce js files, the type is module-->
    <script src="./src/js/app.js" type="module"></script>
</body>

Single file component with nested components

Component development process: The browser does not recognize the .vue file and does not recognize the modular syntax of ES6, so it needs to install Vue scaffolding

Step 1: Create the xxx.vue file to create components that can be nested to use other components

<!--App.vue-->
<template>
    <div>
        <h1>App component</h1>
        <!-- Using components -->
        <X></X>
        <Y></Y>
    </div>
</template>
<script>
    import X from './X.vue'
    import Y from './Y.vue'
    // Expose the component
    export default {
        //Register component
        components : {X, Y}
    }
</script>

<!--X.vue-->
<template>
    <div>
        <h2>X component</h2>
        <!-- Using components -->
        <X1></X1>
    </div>
</template>
<script>
    import X1 from './X1.vue'
    export default {
        //Register component
        components : {X1}
    }
</script>
<!--X1.vue-->
<template>
    <div>
        <h3>X1 component</h3>
    </div>
</template>
<script>
    export default {
        // Expose X1 component
    }
</script>

<!--Y.vue-->
<template>
    <div>
        <h2>Y component</h2>
        <!-- Using components -->
        <Y1></Y1>
    </div>
</template>
<script>
    //Import component Y1 (Y1 can use other names)
    import Y1 from './Y1.vue'
    export default {
        //Register component
        components : {Y1}
    }
</script>

<!--Y1.vue-->
<template>
    <div>
        <h3>Y1 component</h3>
    </div>
</template>

<script>
    export default {
        //Expose Y1 component
    }
</script>

Step 2: Use js code to import the root component App.vue file, create a vm instance and register the App component, and finally write this code to a main.js entry file can be found

import App from './App.vue'
new Vue({<!-- -->
    el : '#root',
    // use components
    template : `<App></App>`,
    //Register App component
    components : {<!-- -->App}
})

Step 3: Introduce the vue.js file and the main.js file, and create a vm instance in the index.html file to mount elements to contain

Step 4: Open the index.html page. After the browser loads the vue.js and main.js files, it will create a Vue instance vm and complete the creation and registration of all components and their sub-components. Finally compile the template statement and render the page

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Single file component</title>
</head>
<body>
    <div id="root"></div>
    <script src="../js/vue.js"></script>
    <script src="./main.js"></script>
</body>
</html>

Develop using scaffolding components

Install Vue CLI (scaffolding)

Vue's scaffolding (Command Line Interface) is a standardized development platform officially provided by Vue to facilitate developers. Vue CLI 4.x requires Node.js v8.9 and above (v10 is recommended above)

Step 1: Execute the npm install -g @vue/cli command to install the scaffolding. -g means global installation, which means you only need to install it once. Use vue Command to test whether the installation is successful

Step 2: Execute the vue creat vue_pro command in the specified directory, which means creating a vue_pro project (built-in Hello Word case), with its own scaffolding environment and built-in webpack loader

Step 3: Execute the npm run serve command in the root directory of the vue_pro project to compile the Vue program. At this time, the xxx.vue file in the project will be automatically transferred. into html css jscode

Understand the scaffolding project structure

index.html file

There is only one container in the index.html file in the scaffolding project, and the vue.js file and the main.js file are not introduced, because the Vue scaffolding will automatically find the main.js file, prerequisite Is the file name and location fixed

<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8">
    <!--Let IE browser enable the highest rendering standard, IE8 does not support Vue-->
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <!-- Turn on the mobile virtual window (ideal viewport), you can set the width, height and initialization ratio of the virtual window to achieve the effect of zooming and moving when browsing the web on the mobile phone -->
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <!--Set the tab icon. BASE_URL is the absolute path set by Vue to imitate Jsp syntax. Absolute paths are more stable than relative paths-->
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <!--webpack will look for name in package.json as the title, or you can set it manually -->
    <title><%= htmlWebpackPlugin.options.title %></title>
    <title>Welcome to this system</title>
  </head>
  <body>
    <!--When the browser does not support JS language, the following prompt message is displayed-->
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <!-- Container -->
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

Configuration file vue.config.js

The vue.config.js file is the default configuration file of the scaffolding. For specific configuration items, please refer to the Vue CLI official website manual

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  //Whether to perform syntax checking when saving (for example, the name of the component should be composed of multiple words), the default value true means checking, false means not checking
  lintOnSave : false,
  //Configure the location and name of the entry file
  pages: {
    index: {
      entry: 'src/main.js',
    }
  },

Entry file main.js

Vue consists of two parts: one is the core of Vue, and the other is the template compiler (accounting for one-third of the entire vue.js file size)

  • Since the code must have been compiled when finally using webpack for packaging, the template compiler in Vue is no longer necessary at this time, so in order to reduce the size, a missing template compiler is directly introduced by default in the Vue scaffolding. The vue.js file is the runtime-only version of Vue

Since Vue introduces the vue.js file that lacks the template compiler, the template configuration item cannot be compiled in the main.js file when creating a Vue instance template statements, but the template statements in the template tag of the xxx.Vue file can be compiled normally because Vue is configured in the package.json file

  • The first way: introduce a complete vue.js, import Vue from 'vue/dist/vue.js'
  • The second way: Use the render function instead of the template configuration item. This function is automatically called by vue, and a function createElemen will be passed over to create elements (required after creation) return)
//The default introduction here is dist/vue.runtime.esm.js (esm version is the ES6 modular version)
import Vue from 'vue'
//Import App component (root component)
import App from './App.vue'

//Close production prompt information
Vue.config.productionTip = false

//Create Vue instance
newVue({
  el : '#app',
  // Complete writing method
  render(createElement){
    // Created a div element
    //return createElement('div', 'render function')
    return createElement(App)
  }
\t
  // The abbreviation of arrow function, the parameter has only one omitted parentheses, and the function body has only one statement to omit {} and return
  render : h => h(App)
  
})

App root component and other components

<!--App.vue-->
<template>
    <div>
        <h1>App component</h1>
        <!-- Using components -->
        <X></X>
        <Y></Y>
    </div>
</template>

<script>
    // Determine the path when the component is introduced
    import X from './components/X.vue'
    import Y from './components/Y.vue'
    export default {
        //Register component
        components : {X, Y}
    }
</script>
<!--The rest is the same as the nested content of the component-->

Data transfer between components

Sending component (parent component) passes data by assigning values to the sub-component tag attributes, receiving component (sub-component) uses props configuration items to declare properties to receive parent components Data passed in

  • Simple reception: props: [brand’, color’, price’]
  • Add type restrictions when receiving (not necessary): props : { brand : String, color : String, price : Number}
  • Add type restrictions (required) and default values when receiving: props: {name: {type: Number, required: true}, age: {type: Number, default: 10}}

Create a subcomponent Car to receive the data passed by the parent component. Whenever the parent component is re-rendered, the child component uses the value received by the properties in props Will be reassigned, and the default value is the default value

  • It is not recommended to modify the data received using props directly, because the next time the parent component is re-rendered, the properties received using prop configuration items in the child component will be reassigned.
  • Generally, indirect modification of the value of an intermediate variable is used to avoid the problem of the modified value of the child component being overwritten when the parent component is re-rendered.
<template>
    <div>
        <h3>Brand: {<!-- -->{brand}}</h3>
        
        <h3>Price: {<!-- -->{cprice}}</h3>
        <h3>Color: {<!-- -->{color}}</h3>
        <button @click="add">Price plus 1</button>
    </div>
</template>
<script>
export default {
    name: 'Car',
    data() {
        return {
            //Assign the value of the received price attribute to an intermediate variable
            cprice : this.price
        }
    },
    methods : {
        add(){
            // Modify the value of the intermediate variable. Even if the parent component is re-rendered, the modified value of the child component will not be overwritten.
            this.cprice++
        }
    },
    // Use the props configuration item in the Car subcomponent to dynamically receive data passed by other components, and no longer use the static data in its own configuration item data.
    data() {
        return {
            brand: 'BMW 520',
            price: 10,
            color: 'black'
        }
    },
    // The first one: simple receiving method, directly using array reception
    props: ['brand','color','price']
   
    // The second type: add type restrictions when receiving (an error will be reported if the type does not match)
    props : {
        brand: String,
        color: String,
        price :Number
    }
    
    // The third type: add necessary restrictions and default values of the type when receiving
    props : {
        brand : {
            type: String,
            required: true
        },
        color : {
            type: String,
            default: 'red'
        },
        price : {
            type: Number,
            required: true
        }
    }

}
</script>

Get the child component and its attributes from the parent component, and use the ref attribute on the child component tag or the Dom element to identify it

  • Get a certain subcomponent and its attributes: Use $refs in the current component to get all the subcomponents of the current component, and then get a specific component and its attributes through the component’s identifier.
  • Nested form is supported when obtaining subcomponents: this.$refs.Component identification.$refs.name indicates accessing the subcomponent properties of the subcomponent.
<template>
    <div>
        <!--Ordinary HTML tags can also be identified using HTML tags-->
        <h1 ref="hh">{<!-- -->{msg}}</h1>
        <!--price="10" means that the passed data is the string "10", :price="10" means that the passed data is the number 10 (attribute binding,"" 10 within is treated as a constant)-->
        <Car brand="BMW 520" color="black" :price="10" ref="car1"></Car>
        <Car brand="BYD Han" color="red" :price="20" ref="car2"></Car>
        <button @click="printCarInfo">Print car information</button>
    </div>
</template>

<script>
    import Car from './components/Car.vue'
    export default {
        name: 'App',
        data() {
            return {
                msg: 'Car information'
            }
        },
         methods : {
            printCarInfo(){
                // Use the $refs attribute to get child components
                console.log(this.$refs.car1)
                console.log(this.$refs.car2)
\t\t\t\t
                //Access the properties of the subcomponent
                console.log(this.$refs.car1.brand)
                console.log(this.$refs.car1.color)
                console.log(this.$refs.car1.price)

                // You can also use the $refs attribute to obtain the value of ordinary DOM elements, replacing the operation of native Dom.
                console.log(this.$refs.hh.innerText)
            }
        },
        components: {Car}
    }
</script>

mixins configuration items (mixing)

If the configuration item codes of multiple xxx.vue files are the same (the configuration items have no restrictions such as methods), you can use the mixins configuration item for reuse.

  • Step 1: Extract the same configuration items and define them separately into a mixin.js file, usually in the same directory as main.js
  • Step 2: Import the mixin.js file into the corresponding xxx.vue file, and then use the exposed configuration in the mixins configuration item

Configuration item conflicts during mixing

  • Adopt the proximity principle for common configuration items: that is, only the component’s own configuration will be executed and mixed configurations will not be executed, because mixing means not to destroy
  • Adopt the superposition method for the life cycle hook function: that is, execute the mixed one first and then execute your own

There are two ways of mixing: local mixing and global mixing

// Exposed separately
export const mix1 = {
    methods: {
        printInfo(){
           console.log(this.name, ',' , this.age)
        }
    }
}


// Ordinary configuration
export const mix2 = {
    methods: {
        a(){
            console.log('mixin.js a.....')
        }
    },
}
// life cycle function
export const mix3 = {
    mounted() {
        console.log('mixin.js mounted...')
    }
}

Adopt the proximity principle for common configuration items: that is, only the component’s own configuration will be executed and mixed configurations will not be executed, because mixing means not to destroy

<template>
    <div>
        <h1>{<!-- -->{msg}}</h1>
        <h3>Name: {<!-- -->{name}}</h3>
        <h3>Age: {<!-- -->{age}}</h3>
        <button @click="printInfo">Execute the printInfo method to print user information</button>
        <button @click="a">Execute method a</button>
    </div>
</template>

<script>
    //Import mixin configuration items
    import {mix1} from '../mixin.js'
    import {mix2} from '../mixin.js'
    export default {
        name: 'Vip',
        data() {
            return {
                msg: 'Member information',
                name: '李思2',
                age: 21
            }
        },
     // Partial mixing, array reception means multiple mixing can be done
        mixins : [mix1,mix2],
        // Only the own a method is called here, and the mixed a method will not be executed.
        methods: {
            a(){
                console.log('vip a....')
            }
        },
    }
</script>

Adopt the superposition method for life cycle hook functions: that is, execute the mixed hook function first and then execute your own hook function

<template>
    <div>
        <h1>{<!-- -->{msg}}</h1>
        <h3>Name: {<!-- -->{name}}</h3>
        <h3>Age: {<!-- -->{age}}</h3>
        <button @click="printInfo">Execute the printInfo method to print user information</button>
        <button @click="a">Execute method a</button>
    </div>
</template>

<script>
    //Import the mixin configuration items in the mixin.js file
    import {mix1} from '../mixin.js'
    import {mix2} from '../mixin.js'
    import {mix3} from '../mixin.js'
    export default {
        name: 'User',
        // Here the mixed mounted function is executed first, and then its own mounted function is executed.
        mounted() {
            console.log('User mounted...')
        },
        data() {
            return {
                msg: 'User information',
                name: 'Zhang San 2',
                age: 20
            }
        },
        // Partial mixing, array reception means multiple mixing can be done
        mixins : [mix1,mix2, mix3],
    }
</script>

The global mixin configuration items in the main.js file will be automatically imported into all components including the root component root, that is, vm configuration items and execute them according to the rules

// Equivalent to introducing the vue.js file
import Vue from 'vue'
//Import App component (root component)
import App from './App.vue'

//Import mixin configuration items
import {mix1} from './mixin.js'
import {mix2} from './mixin.js'
import {mix3} from './mixin.js'

//Global mix-in
Vue.mixin(mix1)
Vue.mixin(mix2)
Vue.mixin(mix3)

//Close production prompt information
Vue.config.productionTip = false

//Create Vue instance
newVue({
  el : '#app',
  render : h => h(App)
})

plugins configuration (plug-in)

Plug-in is an object: It is used to enhance functions of Vue (pluggable). A plug-in generally corresponds to an independent function, and plug-ins are generally placed in a plugins. js file (usually in the same directory as main.js)

The plug-in object must have an install method. This method has two parameters and will be automatically called

  • First parameter: Vue constructor
  • The second parameter: the data passed by the user when using this plug-in. There is no limit to the number of parameters.

Step one: Define the plug-in object and expose it. For example, we can define a plug-in here. The function is to extend a counter attribute to the prototype object of Vue (accessible through both vm and vc)

export const p1 = {<!-- -->
    install(Vue, a, b, c, d){<!-- -->
        console.log('This plug-in is displaying a cute cover')
        console.log(Vue)
        console.log(a,b,c,d)
        // Get the prototype object of Vue, extend a counter attribute to the prototype object of Vue, which can be accessed through vm and vc
        Vue.prototype.counter = 1000
    }
}

Step 2: Import the created plug-in object in the main.js file, and then use the imported plug-in

// Equivalent to introducing the vue.js file
import Vue from 'vue'
//Import App component (root component)
import App from './App.vue'

//Import plugin
import {p1} from './plugins.js'


// Plug in the plug-in (to delete it means to unplug the plug-in), usually before creating a Vue instance
Vue.use(p1, 1,2,3,4)

//Close production prompt information
Vue.config.productionTip = false

//Create Vue instance
newVue({
  el : '#app',
  render : h => h(App)
  
})

Step 3: Access a counter attribute extended by the plug-in object we defined to the Vue prototype object

<template>
    <div>
        <button @click="a">Execute method a</button>
    </div>
</template>

<script>
    export default {
        methods: {
            a(){
                console.log('vip a....')
                //Access the counter attribute extended by the plug-in object to the Vue prototype object
                console.log('A counter extended by a plug-in:', this.counter)
            }
        },
    }
</script>

Local style scoped

By default, the styles defined in the style tag in all components will eventually be summarized together. If the style names are consistent, conflicts will occur. At this time, the nearest principle will be adopted, that is, the component style to be loaded later will be adopted. Subject to

  • The styles in components support multiple style languages (such as css, less, sass). To use less syntax, you need to execute the npm i less-loader command to install less-loader.

After adding the scoped attribute to the style tag of the component, the bottom layer of Vue will add attributes to the tag, so that even if the styles are merged together, there will be no conflict

<template>
    <div class="s">
        <h1>{<!-- -->{msg}}</h1>
    </div>
</template>
<script>
    export default {
        data() {
            return {
                msg: 'User information',
            }
        }
    }
</script>
<!--After adding the scoped attribute to the style tag of the component, the bottom layer of Vue will add attributes to the tag, so that even if the styles are merged together, there will be no conflict-->
<style scoped>
   .s {
    background-color: aquamarine;
   }
</style>
<template>
    <div class="s">
        <h1>{<!-- -->{msg}}</h1>
    </div>
</template>
<script>
    export default {
        data() {
            return {
                msg: 'Member information',
            }
        }
    }
</script>
<!--After adding the scoped attribute to the style tag of the component, the bottom layer of Vue will add attributes to the tag, so that even if the styles are merged together, there will be no conflict-->
<style scoped>
   .s {
    background-color:bisque
   }
</style>

The style in App root component generally adopts the global method and it is not recommended to add the scoped attribute. The style of the sub-component generally adds the scoped attribute

<template>
    <div>
        <User></User>
        <Vip></Vip>
    </div>
</template>

<script>
    // Import Vip first. Due to style conflict, the style of the User component will overwrite the style of the Vip component.
    import Vip from './components/Vip.vue'
    import User from './components/User.vue'
    export default {
        name: 'App',
        components : {User, VIP}
    }
</script>

<style>
    /* Generally, the style in the App root component will not be scoped, because the style of the root component still wants to be processed in a global way*/
</style>
syntaxbug.com © 2021 All Rights Reserved.