Vue.js from entry to mastery day 4

Posted by moselkady on Wed, 09 Mar 2022 15:29:38 +0100

Vue.js - Day4

Parent component passes value to child component

  1. For the component instance definition method, note: the props attribute must be used to define the data passed by the parent component
<script>
    // Create Vue instance and get ViewModel
    var vm = new Vue({
      el: '#app',
      data: {
        msg: 'This is the message in the parent component'
      },
      components: {
        son: {
          template: '<h1>This is a subcomponent --- {{finfo}}</h1>',
          props: ['finfo']
        }
      }
    });
  </script>
  1. Use v-bind or simplified instructions to transfer data to subcomponents:
<div id="app">
    <son :finfo="msg"></son>
  </div>

The child component passes values to the parent component

  1. Principle: the parent component passes the reference of the method to the child component. The child component calls the method passed by the parent component internally, and passes the data to be sent to the parent component as a parameter when calling the method;
  2. The parent component passes the method reference to the child component, where getMsg is the method name defined in the methods in the parent component and func is the method name when the child component calls the passed method
<son @func="getMsg"></son>
  1. Inside the sub component, through this$ Emit ('method name ', data to be transferred) mode to call the method in the parent component and transfer the data to the parent component for use
<div id="app">
    <!-- Reference parent component -->
    <son @func="getMsg"></son>

    <!-- Component template definition -->
    <script type="x-template" id="son">
      <div>
        <input type="button" value="Pass value to parent component" @click="sendMsg" />
      </div>
    </script>
  </div>

  <script>
    // How subcomponents are defined
    Vue.component('son', {
      template: '#son ', / / component template Id
      methods: {
        sendMsg() { // Button click event
          this.$emit('func', 'OK'); // Call the method passed by the parent component and pass the data out at the same time
        }
      }
    });

    // Create Vue instance and get ViewModel
    var vm = new Vue({
      el: '#app',
      data: {},
      methods: {
        getMsg(val){ // In the sub component, through this$ The method actually called by emit() is defined here
          alert(val);
        }
      }
    });
  </script>

Differences between data and props in components

Comment list case

Objective: to mainly practice value transfer between parent and child components

Use this$ Refs to get elements and components

  <div id="app">
    <div>
      <input type="button" value="Get element content" @click="getElement" />
      <!-- use ref Get element -->
      <h1 ref="myh1">This is a big problem H1</h1>

      <hr>
      <!-- use ref Get subcomponents -->
      <my-com ref="mycom"></my-com>
    </div>
  </div>

  <script>
    Vue.component('my-com', {
      template: '<h5>This is a sub component</h5>',
      data() {
        return {
          name: 'Subcomponents'
        }
      }
    });

    // Create Vue instance and get ViewModel
    var vm = new Vue({
      el: '#app',
      data: {},
      methods: {
        getElement() {
          // Through this$ Refs to get the element
          console.log(this.$refs.myh1.innerText);
          // Through this$ Refs to get the component
          console.log(this.$refs.mycom.name);
        }
      }
    });
  </script>

What is routing

  1. **Back end Routing: * * for ordinary websites, all hyperlinks are URL addresses, and all URL addresses correspond to the corresponding resources on the server;

  2. **Front end Routing: * * for single page applications, the hash(# number) in the URL is mainly used to switch between different pages. At the same time, hash has one feature: the HTTP request will not contain hash related content; Therefore, the page Jump in single page program is mainly realized by hash;

  3. In a single page application, this way of switching pages through hash change is called front-end routing (different from back-end routing);

Using vue router in vue

  1. Import Vue router component class library:
<!-- 1. Import vue-router Component class library -->
  <script src="./lib/vue-router-2.7.0.js"></script>
  1. Use the router link component to navigate
<!-- 2. use router-link Components to navigate -->
<router-link to="/login">Sign in</router-link>
<router-link to="/register">register</router-link>
  1. Use the router view component to display the matched components
<!-- 3. use router-view Component to display the matched components -->
<router-view></router-view>
  1. Create and use Vue Extend create component
    // 4.1 using Vue Extend to create the login component
    var login = Vue.extend({
      template: '<h1>Login component</h1>'
    });

    // 4.2 using Vue Extend to create a registered component
    var register = Vue.extend({
      template: '<h1>Register components</h1>'
    });
  1. Create a routing router instance and define routing matching rules through the routers attribute
// 5. Create a routing instance and define routing matching rules through the routes attribute
    var router = new VueRouter({
      routes: [
        { path: '/login', component: login },
        { path: '/register', component: register }
      ]
    });
  1. Use the router property to use routing rules
// 6. Create Vue instance and get ViewModel
    var vm = new Vue({
      el: '#app',
      router: router // Use the router property to use routing rules
    });

Use the tag attribute to specify the label type of router link rendering

Set route redirection

Set route highlight

Set route switching dynamics

Define parameters in routing rules

  1. Define parameters in the rule:
{ path: '/register/:id', component: register }
  1. Through this$ route. Params to get the parameters in the route:
var register = Vue.extend({
      template: '<h1>Register components --- {{this.$route.params.id}}</h1>'
    });

Route nesting using children attribute

  <div id="app">
    <router-link to="/account">Account</router-link>

    <router-view></router-view>
  </div>

  <script>
    // Components in parent route
    const account = Vue.extend({
      template: `<div>
        This is account assembly
        <router-link to="/account/login">login</router-link> | 
        <router-link to="/account/register">register</router-link>
        <router-view></router-view>
      </div>`
    });

    // login component in sub route
    const login = Vue.extend({
      template: '<div>Login component</div>'
    });

    // register component in sub route
    const register = Vue.extend({
      template: '<div>Register components</div>'
    });

    // Routing instance
    var router = new VueRouter({
      routes: [
        { path: '/', redirect: '/account/login' }, // Route redirection using redirect
        {
          path: '/account',
          component: account,
          children: [ // The nesting of routes is realized through the children array attribute
            { path: 'login', component: login }, // Note that the / path character should not be added at the beginning of the sub route
            { path: 'register', component: register }
          ]
        }
      ]
    });

    // Create Vue instance and get ViewModel
    var vm = new Vue({
      el: '#app',
      data: {},
      methods: {},
      components: {
        account
      },
      router: router
    });
  </script>

Named views implement classic layouts

  1. Label code structure:
<div id="app">
    <router-view></router-view>
    <div class="content">
      <router-view name="a"></router-view>
      <router-view name="b"></router-view>
    </div>
  </div>
  1. JS code:
<script>
    var header = Vue.component('header', {
      template: '<div class="header">header</div>'
    });

    var sidebar = Vue.component('sidebar', {
      template: '<div class="sidebar">sidebar</div>'
    });

    var mainbox = Vue.component('mainbox', {
      template: '<div class="mainbox">mainbox</div>'
    });

    // Create routing object
    var router = new VueRouter({
      routes: [
        {
          path: '/', components: {
            default: header,
            a: sidebar,
            b: mainbox
          }
        }
      ]
    });

    // Create Vue instance and get ViewModel
    var vm = new Vue({
      el: '#app',
      data: {},
      methods: {},
      router
    });
  </script>
  1. CSS Style:
  <style>
    .header {
      border: 1px solid red;
    }

    .content{
      display: flex;
    }
    .sidebar {
      flex: 2;
      border: 1px solid green;
      height: 500px;
    }
    .mainbox{
      flex: 8;
      border: 1px solid blue;
      height: 500px;
    }
  </style>

Use of the watch property

Consider a problem: if you want to change the contents of the first name and last name text boxes, the value in the full name text box will also change; (how to realize it with previous knowledge???)

  1. Listen for attribute changes in data:
<div id="app">
    <input type="text" v-model="firstName"> +
    <input type="text" v-model="lastName"> =
    <span>{{fullName}}</span>
  </div>

  <script>
    // Create Vue instance and get ViewModel
    var vm = new Vue({
      el: '#app',
      data: {
        firstName: 'jack',
        lastName: 'chen',
        fullName: 'jack - chen'
      },
      methods: {},
      watch: {
        'firstName': function (newVal, oldVal) { // The first parameter is new data, and the second parameter is old data
          this.fullName = newVal + ' - ' + this.lastName;
        },
        'lastName': function (newVal, oldVal) {
          this.fullName = this.firstName + ' - ' + newVal;
        }
      }
    });
  </script>
  1. Listen for changes in routing objects:
<div id="app">
    <router-link to="/login">Sign in</router-link>
    <router-link to="/register">register</router-link>

    <router-view></router-view>
  </div>

  <script>
    var login = Vue.extend({
      template: '<h1>Login component</h1>'
    });

    var register = Vue.extend({
      template: '<h1>Register components</h1>'
    });

    var router = new VueRouter({
      routes: [
        { path: "/login", component: login },
        { path: "/register", component: register }
      ]
    });

    // Create Vue instance and get ViewModel
    var vm = new Vue({
      el: '#app',
      data: {},
      methods: {},
      router: router,
      watch: {
        '$route': function (newVal, oldVal) {
          if (newVal.path === '/login') {
            console.log('This is the login component');
          }
        }
      }
    });
  </script>

Use of computed properties

  1. By default, there is only the calculation attribute of getter:
<div id="app">
    <input type="text" v-model="firstName"> +
    <input type="text" v-model="lastName"> =
    <span>{{fullName}}</span>
  </div>

  <script>
    // Create Vue instance and get ViewModel
    var vm = new Vue({
      el: '#app',
      data: {
        firstName: 'jack',
        lastName: 'chen'
      },
      methods: {},
      computed: { // Calculate attributes; Features: when any data attribute in the calculation attribute is changed, the recalculation of the calculation attribute will be triggered again, so as to update the value of fullName
        fullName() {
          return this.firstName + ' - ' + this.lastName;
        }
      }
    });
  </script>
  1. Calculation properties with getter and setter defined:
<div id="app">
    <input type="text" v-model="firstName">
    <input type="text" v-model="lastName">
    <!-- Click the button to recalculate the attribute fullName assignment -->
    <input type="button" value="modify fullName" @click="changeName">

    <span>{{fullName}}</span>
  </div>

  <script>
    // Create Vue instance and get ViewModel
    var vm = new Vue({
      el: '#app',
      data: {
        firstName: 'jack',
        lastName: 'chen'
      },
      methods: {
        changeName() {
          this.fullName = 'TOM - chen2';
        }
      },
      computed: {
        fullName: {
          get: function () {
            return this.firstName + ' - ' + this.lastName;
          },
          set: function (newVal) {
            var parts = newVal.split(' - ');
            this.firstName = parts[0];
            this.lastName = parts[1];
          }
        }
      }
    });
  </script>

Comparison between watch, computed and methods

  1. The results of the computed attribute are cached and will not be recalculated unless the dependent responsive attribute changes. It is mainly used as an attribute;
  2. The methods method represents a specific operation, mainly writing business logic;
  3. watch is an object. The key is the expression to be observed, and the value is the corresponding callback function. It is mainly used to monitor the changes of some specific data, so as to carry out some specific business logic operations; It can be regarded as a combination of computed and methods;

Installation and use of nrm

Function: it provides some of the most commonly used image addresses of NPM packages, enabling us to quickly switch the server address when installing packages;
What is mirroring: originally, the package only existed in foreign NPM servers at the beginning, but it is often inaccessible due to network reasons. At this time, we can create an NPM server exactly the same as the official website in China, but the data is taken from others. In addition, the use method is exactly the same;

  1. Run npm i nrm -g global installation nrm package;
  2. Use nrm ls to view all available image source addresses and the currently used image source addresses;
  3. Use nrm use npm or nrm use taobao to switch different image source addresses;

Relevant documents

  1. hash in URL

Topics: Vue