[Crazy God Talks Java] Detailed Notes on Getting Started with Vue (Full)

Article directory

1 Overview

1.1. Vue overview

Vue (pronounced /vju/, similar to view) is a progressive framework for building user interfaces , released in February 2014. Unlike other large frameworks, Vue is designed to be applied layer by layer from the bottom up. Vue's core library only focuses on the view layer , which is not only easy to get started, but also easy to integrate with third-party libraries (such as: vue-router: jump, vue-resource: communication, vuex: management) or existing projects.
SOC principle: principle of separation of concerns

1.2. Front-end knowledge system

There is still a long way to go to become a true "Internet Java full-stack engineer", among which "My Big Front End" is a required course that cannot be avoided. The main purpose of this stage of the course is to lead my Java background programmers to know, understand and master the front-end, so as to take a step forward to become an "Internet Java full-stack engineer".

1.3. Three elements of front-end

  • HTML (structure): Hyper Text Markup Language (Hyper Text Markup Language), determines the structure and content of web pages
  • CSS (Presentation): Cascading Style sheets (Cascading Style sheets), set the presentation style of the web page
  • JavaScript (behavior): It is a weakly typed scripting language. Its source code does not need to be compiled, but is interpreted and run by the browser to control the behavior of web pages.

1.4. Presentation layer (CSS)

CSS cascading style sheet is a markup language , not a programming language, so it cannot customize variables, cannot quote, etc. In other words, it does not have any syntax support. Its main flaws are as follows:

  • The syntax is not powerful enough, for example, it cannot be nested, resulting in the need to write many repeated selectors in modular development;
  • Without variables and a reasonable style reuse mechanism, logically related attribute values ​​must be repeatedly output in the form of literals, making it difficult to maintain;

This resulted in an unreasonable increase in workload at work. In order to solve this problem, front-end developers will use a tool called [ CSS preprocessor ] to provide the missing style layer reuse mechanism of CSS, reduce redundant code, and improve the maintainability of style code. Greatly improves the efficiency of front-end style development. (For example, pages have different needs at different times, and Taobao’s styles will be different on Double 11 and 618)

1.5. CSS preprocessor

The CSS preprocessor defines a new language. The basic idea is to use a specialized programming language to add some programming features to CSS, use CSS as a target to generate files, and then developers only need to use this language. Carry out CSS coding work. Translated into easy-to-understand words, it means " using a special programming language to design the Web page style, and then convert it into a normal CSS file through a compiler for use in the project." What
are the commonly used CSS preprocessors?

  • SASS : Based on Ruby, processed through the server, and has powerful functions. High analysis efficiency. You need to learn the Ruby language, which is more difficult to get started than LESS.
  • LESS : Based on NodeJS, processed through the client, easy to use. The function is simpler than SASS, and the parsing efficiency is also lower than SASS, but it is sufficient in actual development, so our backend staff recommend using LESS if necessary.

1.6. Behavior layer (JavaScript)

JavaScript is a weakly typed scripting language. Its source code does not need to be compiled before being sent to the client for running. Instead, character codes in text format are sent to the browser for interpretation and execution by the browser.
Native JS development
Native JS development means that we follow the [ECMAScript] standard development method, which is called ES for short. The characteristic is that all browsers support it. As of the current blog publishing time, the ES standard has released the following versions:

  • ES3
  • ES4 (internal, unsolicited release)
  • ES5 (full browser support)
  • ES6 (commonly used, current mainstream version: webpack packaging becomes ES5 support! )
  • ES7
  • ES8
  • ES9 (draft stage)

The difference is that new features are gradually added.

1.7. TypeScript

TypeScript is a free and open source programming language developed by Microsoft. It is a superset of JavaScript and essentially adds optional static typing and class-based object-oriented programming to the language. Led by Anders Heilsberg (father of C#, Delphi, TypeScript; creator of .NET).
The characteristic of this language is that in addition to the features of ES, it also incorporates many new features that are not within the scope of the standard. Therefore, many browsers cannot directly support TypeScript syntax and need to be compiled (compiled into JS) before it can be correctly executed by the browser. .

1.8. JavaScript framework

  • jQuery : A well-known JavaScript framework. The advantage is that it simplifies DOM operations. The disadvantage is that DOM operations are too frequent , which affects front-end performance; in the eyes of the front-end, it is only used to be compatible with IE6, 7, and 8;
  • Angular : The front-end framework acquired by Google was developed by a group of Java programmers. It is characterized by moving the back-end MVC model to the front-end and adding the concept of modular development . It cooperates with Microsoft and uses TypeScript syntax to develop; it is friendly to back-end programmers. Not very friendly to front-end programmers; the biggest disadvantage is that the version iteration is unreasonable (for example: 1st generation -> 2nd generation, except for the name, it is basically two things; as of the time of publishing the blog, Angular6 has been launched)
  • React : Produced by Facebook, a high-performance JS front-end framework; its characteristic is that it proposes a new concept [virtual DOM] to reduce real DOM operations and simulate DOM operations in memory, effectively improving front-end rendering efficiency; its disadvantage is that it is complicated to use , because you need to learn an additional [JSX] language;
  • Vue : A progressive JavaScript framework. Progressive means gradually implementing new features, such as modular development, routing, state management and other new features. Its characteristic is that it combines the advantages of Angular (modularity) and React (virtual DOM) ;
  • Axios : front-end communication framework; because the boundaries of Vue are very clear, it is to process DOM, so it does not have communication capabilities. At this time, you need to use an additional communication framework to interact with the server; of course, you can also directly choose to use the AJAX communication function provided by jQuery ;

Three major front-end frameworks: Angular, React, Vue

1.9. UI framework

  • Ant-Design: Produced by Alibaba, a UI framework based on React
  • ElementUI, iview, ice: Produced by Ele.me, a Vue-based UI framework
  • Bootstrap: an open source toolkit for front-end development launched by Twitter
  • AmazeUI: Also called "Meizi UI", an HTML5 cross-screen front-end framework.

JavaScript build tools

  • Babel: JS compilation tool, mainly used for new ES features not supported by browsers, such as compiling TypeScript
  • WebPack: Module packager, its main function is packaging, compression, merging and sequential loading.
    Note: The above knowledge points have sorted out all the skills required for WebApp development.

1.10. Three ends in one

The main purpose of hybrid development (Hybid App)
is to unify a set of codes on three terminals (PC, Android: .apk, iOS: .ipa) and be able to call underlying components (such as sensors, GPS, cameras, etc.), packaging method There are mainly two types:

  • Cloud packaging: HBuild -> HBuildX, produced by DCloud; API Cloud
  • Local packaging: Cordova (formerly PhoneGap)

1.11. Back-end technology

Front-end personnel also need to master certain back-end technologies in order to facilitate development. However, we Java back-end personnel know that the back-end knowledge system is extremely large and complex. Therefore, in order to facilitate front-end personnel to develop back-end applications, technologies such as NodeJS have emerged.

The author of NodeJS has claimed to give up NodeJS (saying that the architecture is not well done and the bulky node_ modules may make the author unhappy) and began to develop Deno with a new architecture

Since it is a back-end technology, it definitely requires frameworks and project management tools. The NodeJS framework and project management tools are as follows:

  • Express: NodeJS framework
  • Koa: Express simplified version
  • NPM: comprehensive project management tool, similar to Maven
  • YARN: An alternative to NPM, similar to the relationship between Maven and Gradle

2. MVVM

2.1. What is MVVM

MVVM (Model-View-ViewModel) is a software architecture design pattern developed by Microsoft WPF (used to replace WinForm, which was used to develop desktop applications in the past) and Silverlight (similar to Java Applet, to put it simply, it is browsing Developed by Ken Cooper and Ted Peters, the architects of WPF (running on Windows Server), it is an event-driven programming method that simplifies the user interface . Published by John Gossman (also the architect of WPF and Silverlight) in 2005 on his blog.
MVVM is derived from the classic MVC (ModI-View-Controller) pattern. The core of MVVM is the ViewModel layer, which is responsible for converting data objects in the Model to make the data easier to manage and use. Its functions are as follows:

  • This layer performs two-way data binding upwards with the view layer.
  • Perform data interaction downwards with the Model layer through interface requests

image.png

2.2. Why use MVVM

The MVVM pattern is the same as the MVC pattern. The main purpose is to separate the view (View) and the model (Model). It has several advantages:

  • Low coupling : View (View) can change and modify independently of the Model. A ViewModel can be bound to different Views. When the View changes, the Model can remain unchanged, and when the Model changes, the View can also remain unchanged.
  • Reusable : You can put some view logic in a ViewModel and let many Views reuse this view logic.
  • Independent development : Developers can focus on business logic and data development (ViewModel), and designers can focus on page design.
  • Testable : Interfaces have always been difficult to test, but now tests can be written for ViewModel.

2.3. Vue is the implementer of MVVM pattern

image.png

  • Model: Model layer, where JavaScript objects are represented
  • View: View layer, here represents DOM (elements for HTML operations)
  • ViewModel: middleware that connects views and data. Vue.js is the implementer of the ViewModel layer in MVVM. In the MVVM architecture, data and views are not allowed to communicate directly. They can only communicate through ViewModel, and ViewModel defines a Observer

ViewModel can observe changes in data and update the content corresponding to the view.
ViewModel can monitor changes in views and notify data of changes.
Vue.js is an implementer of MVVM. Its core is to implement DOM monitoring and data binding

3. The first Vue program

  1. Create a new empty project and create a new package: chapter01

image.png

  1. Create a new HTML5 project and write
  2. open page
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Title</title>
  </head>
  <body>

    <!--View 层-->
    <div id="app">
      <!--4、元素获取 vue 中的数据-->
      {
   
   {message}}
    </div>

    <!--1、导入 vue.js -->
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
    <script>
      var vm = new Vue({
      
      
        // 2、绑定 app 元素
        el: "#app",
        // Model 层
        // 3、插入数据,键值对
        data: {
      
      
          message: "hello,vue"
        }
      });
    </script>
  </body>
</html>

image.png

  1. Open the developer tools, select Console input, and press Enter
vm.message="hehe"

It is found that the data on the page has also changed.
This is the ViewModel two-way binding
of the data in the view layer and the message variable. When the message changes, the data on the page also changes.

4. Instructions

4.1. Example

Write HTML pages

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Title</title>
  </head>
  <body>
    <!--View 层-->
    <div id="app">
      <!--4、元素获取 vue 中的数据-->
      <!--    {
    
    {message}}-->
      <span v-bind:title="message">
        鼠标悬停几秒可查看绑定的信息
      </span>
    </div>
    <!--1、导入 vue.js -->
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
    <script>
      var vm = new Vue({
      
      
        // 2、绑定 app 元素
        el: "#app",
        // Model 层
        // 3、插入数据,键值对
        data: {
      
      
          message: "hello,vue"
        }
      });
    </script>
  </body>
</html>

Open the page to view
image.png
and find that using v-bind: You can also bind variables to elements.

4.2. Overview

Directives are special attributes prefixed with v- . The value of a directive's attribute is expected to be a single JavaScript expression (the exception is v-for, which we'll discuss later). The responsibility of the directive is to reactively apply its associated effects to the DOM when the value of the expression changes.

4.3. v-if

Write HTML

<div id="app">
  <span v-if="ok===true">YES</span>
  <span v-else>No</span>
</div>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
  var vm = new Vue({
      
      
    el: "#app",
    data: {
      
      
      ok: true
    }
  });
</script>

Open the page
image.png
and modify the value of ok
image.png

4.4. v-else-if

<div id="app">
  <span v-if="str==='A'">AAA</span>
  <span v-else-if="str==='B'">BBB</span>
  <span v-else>Other</span>
</div>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
  var vm = new Vue({
      
      
    el: "#app",
    data: {
      
      
      str: 'A'
    }
  });
</script>

Open the page
image.png
and modify the value of str
image.png
image.png

4.5. for

<div id="app">
  <ul>
    <!--类似于java 的 foreach ,
    从 items 中遍历出的每一项命名为 item-->
    <li v-for="item in items">{
   
   {item.message}}</li>
  </ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
  var vm = new Vue({
      
      
    el: "#app",
    data: {
      
      
      items: [
        {
      
      message: "test-1"},
        {
      
      message: "test-2"},
        {
      
      message: "test-3"}
      ]
    }
  });
</script>

open page
image.png

5. Listen for events

You can use the v-on directive to listen to DOM events and run some JavaScript code when triggered.

<div id="app">
  <button v-on:click="sayHi()">click me</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
  var vm = new Vue({
      
      
    el: "#app",
    data: {
      
      
      message: "Hi!!!"
    },
    // 定义方法
    // 注意一定要加 S
    methods: {
      
      
      // 冒号前是方法名
      sayHi: function (){
      
      
        alert(this.message);
      }
    }
  });
</script>

open page
image.png

6. Two-way binding

6.1 What is two-way data binding?

Vue is an mvvm framework, which means two-way data binding. That is, when the data changes, the view also changes. When the view changes, the data will also change synchronously . This can be regarded as the essence of vue.
It is worth noting that the two-way data binding we are talking about must be for UI controls. Non-UI controls will not involve two-way data binding. One-way data binding is a prerequisite for using state management tools such as redux. If we use vuex, then the data flow is also single-item, which will conflict with two-way data binding. We can solve it like this

6.2 Why is it necessary to implement two-way binding of data?

In vue, if you use vuex, the data is actually one-way. The reason why it is called two-way data binding is because of the UI controls used. For us to process forms, vue's two-way data binding is particularly comfortable to use. .
That is to say, the two are not mutually exclusive. The global data flow uses a single item to facilitate tracking; the local data flow uses two directions, which is simple and easy to operate.

6.3 Using two-way data binding in forms

You can use the v-model directive to create two-way data binding on form <input>, <textarea>, and <select> elements. It automatically chooses the correct method to update the element based on the control type. Despite its magic, v-model is essentially syntactic sugar. It is responsible for listening to user input events to update data and perform some special processing for some extreme scenarios.

6.4 Use

1. Input box

<div id="app">
  <!--双向绑定:
  data 中的 message 既和输入框的 message 绑定
  又和 p 标签中的 message 绑定-->
  <span>输入文本:</span><input type="text" v-model="message">
  <p><span>输入的文本:</span><span>{
   
   {message}}</span></p>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
  var vm = new Vue({
      
      
    el: "#app",
    data: {
      
      
      message: ""
    }
  });
</script>

Modify the value of message on the page and
image.png
enter it directly in the input box
image.png

2. Radio button

<div id="app">
  性别:
  <input type="radio" name="sex" value="male" v-model="sex"><input type="radio" name="sex" value="female" v-model="sex"><p>选中了:{
   
   {sex}}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
  var vm = new Vue({
      
      
    el: "#app",
    data: {
      
      
      sex: ""
    }
  });
</script>

When you open the page , you can find that the Value
image.png
of the radio button is bound here.

3. Multiple selection box

<div id="app">
  <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
  <label for="jack">杰克</label>
  <input type="checkbox" id="john" value="John" v-model="checkedNames">
  <label for="john">约翰</label>
  <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
  <label for="mike">麦克</label>
  <br>
  <span>Checked names: {
   
   { checkedNames }}</span>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
  var vm = new Vue({
      
      
    el: "#app",
    data: {
      
      
      checkedNames: []
    }
  });
</script>

image.png

4. Drop-down box

<div id="app">
  下拉框:
  <select v-model="selected">
    <option value="" disabled>-请选择-</option>
    <option value="aaa">AA</option>
    <option value="bbb">BB</option>
    <option value="ccc">CC</option>
  </select>
  <p>选中 : {
   
   {selected}}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
  var vm = new Vue({
      
      
    el: "#app",
    data: {
      
      
      selected : ""
    }
  });
</script>

image.png

7. Components

7.1. Overview

  • Components are reusable Vue instances, which means that repeated parts can be encapsulated as components during the development process.
  • Organization of components
    image.png For example, you may have components such as header, sidebar, and content area, and each component contains other components such as navigation links and blog posts.

7.2. Demo of the first component

<div id="app">
  <my-component></my-component>
  <my-component></my-component>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
  // 定义组件
  Vue.component("my-component",{
      
      
    template: '<li>AA</li>'
  });

  var vm = new Vue({
      
      
    el: "#app"
  });
</script>

image.png

7.3. Passing data through Data

<div id="app">
  <!--  利用 v-for 把 items 的元素取出,
  再通过 v-bind 绑定数据: 把 item1 绑定在了 item2 上-->
  <my-component v-for="item1 in items" v-bind:item2="item1"></my-component>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
  // 定义组件
  Vue.component("my-component",{
      
      
    // 通过 item2 接收 item1 数据
    props: ['item2'],
    template: '<li>{
      
      {item2}}</li>'
  });

  var vm = new Vue({
      
      
    el: "#app",
    data: {
      
      
      items: ["AAA","BBB","CCC"]
    }
  });
</script>

image.png

8. Axios asynchronous communication

8.1. Overview

Axios is an open source asynchronous communication framework that can be used on the browser side and NodeJS. Its main function is to implement AJAX asynchronous communication. Its functional characteristics are as follows:

  • Create XMLHttpRequests from the browser
  • Create http request from node.js
  • Support Promise API
  • Intercept requests and responses
  • Convert request data and response data
  • Cancel request
  • Automatically convert JSON data
  • The client supports defense against XSRF (cross-site request forgery)

8.2. Why use Axios

Since Vue.js is a view layer framework and the author (You Yuxi) strictly adheres to the SoC (Separation of Concerns Principle), Vue.js does not include AJAX communication functions. Vue recommends using the Axios framework and try not to use JQuery. Because it frequently operates the DOM

8.3. Prerequisites

Confirm that IDEA's JavaScript supports ES6
image.png

8.4 The first Axios application

  1. Because in actual development, JSON format data is mostly used, so here is a new JSON format file.
  2. Write HTML - Get local Json data
  3. Open the page and open the developer tools. You can find that Axios is asynchronous communication like AJax. You
    image.png
    can also see that the data has been obtained.
    image.png
  4. Write HTML - render the obtained Json to the page
  5. page
    image.png
{
    
    
  "name": "呵呵",
  "url": "https://blog.csdn.net/weixin_44449838",
  "page": 123,
  "isNonProfit": true,
  "address": {
    
    
    "street": "塔克拉玛干沙漠",
    "city": "新疆",
    "country": "中国"
  },
  "links": [
    {
    
    
      "name": "Google",
      "url": "http://www.google.com"
    },
    {
    
    
      "name": "Baidu",
      "url": "http://www.baidu.com"
    }
  ]
}
<div id="vue">

</div>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<!-- axios 的包-->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
  var vm = new Vue({
      
      
    el: "#vue",
    data: {
      
      },
    // 钩子函数,在主流程执行过程中间执行的方法
    mounted(){
      
      
      axios.get('../data.json').then(response=>(console.log(response.data)));
    }
  });
</script>
<div id="vue">
  <!--    需要渲染的字段名 -->
  <div>{
   
   {info.name}}</div>
  <div>{
   
   {info.address}}</div>
  <div>{
   
   {info.address.city}}</div>
  <div v-for="link in info.links">
    <span>{
   
   {link.name}}</span> : 
    <a v-bind:href="link.url">{
   
   {link.url}}</a>
  </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<!-- axios 的包-->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
  var vm = new Vue({
      
      
    el: "#vue",
    // 有冒号、大括号的 data 是属性
    data: {
      
      },
    // 没有冒号的是方法
    // 这里使用的 data 方法,不要搞混
    data(){
      
      
      return{
      
      
        // 请求的返回参数,这里需要写上需要返回的字段名,不需要写值,所以都写 null
        // 这里的键可以比传入的 Json 中的少
        // 但是如果写了,就必须和获得的 Json 键的名字一样
        info: {
      
      
          name: null,
          address: {
      
      
            city: null,
            country: null
          },
          links: [
            {
      
      
              name: null,
              url: null
            }
          ]
        }
      }
    },
    // 钩子函数,在主流程执行过程中间执行的方法
    mounted(){
      
      
      // 这边把 上面 return 中的 info 值和返回的 data 数据绑定,以便返回给视图渲染
      axios.get('../data.json').then(response=>(this.info=response.data));
    }
  });
</script>

8.5 Solve the flickering problem

After the above demo is written, when you refresh the page, you will find that the template appears first, and the data comes out after a while.
image.png
This is not very user-friendly and is not safe for the data, so use the following method to solve it by
writing a above HTML < style >< /style >

<style>
  [v-cloak]{
      
      
    display: none;
  }
</style>

<div id="vue" v-clock>
  <!--    需要渲染的字段名 -->
  <div>{
   
   {info.name}}</div>
  <div>{
   
   {info.address}}</div>
  <div>{
   
   {info.address.city}}</div>
  <div v-for="link in info.links">
    <span>{
   
   {link.name}}</span> : 
    <a v-bind:href="link.url">{
   
   {link.url}}</a>
  </div>
</div>

In this way, although the data will still come out after a while, the template will no longer be visible.

9. Vue life cycle

A Vue instance has a complete life cycle, that is, a series of processes such as creation, initialization of data, compilation of templates, mounting of DOM, rendering -> update -> rendering, uninstallation, etc. This is called the life cycle of Vue.
Throughout the entire life cycle of Vue, it provides a series of events that allow us to register JS methods when events are triggered. We can use our own registered JS methods to control the entire situation. This in these event response methods is directly Points to an instance of Vue.
image.png

10. Computed properties

  • Calculated properties: Save the calculated results in properties.
  • Benefits: Runs in memory, virtual DOM
  • Write code
  • Experience the difference between opening a page, turning on developer mode, and using the console
<div id="vue">
  <!-- 调用方法 -->
  <p>currentTime1 : {
   
   {currentTime1()}}</p>
  <!-- 调用属性 -->
  <p>currentTime2 : {
   
   {currentTime2}}</p>
</div>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
  var vm = new Vue({
      
      
    el: "#vue",
    data: {
      
      
      message: "hello."
    },
    methods: {
      
      
      currentTime1: function (){
      
      
        // 返回当前时间戳
        return Date.now();
      }
    },
    // 计算属性
    computed: {
      
      
      // 方法名不能一样
      currentTime2: function (){
      
      
        // 返回当前时间戳
        return Date.now();
      }
    }
  });
</script>
  1. When calling a normal method, it is the calling method name; when calling a calculated property, it is the property name.
    image.png
  2. Ordinary function calls are executed once; calculated properties treat the calculated results as attributes and store them in memory.
    image.png
  • When does a computed property change? Methods in modifying computed properties
// 计算属性
computed: {
    
    
  // 方法名不能一样
  currentTime2: function (){
    
    
    // 返回当前时间戳
    return Date.now() +"  | "+this.message;
  }
}

Open the page, open developer mode, and use the console.
image.png
So as long as the data in the calculated property method body changes, the calculated property will change.

11. Content distribution—slot

  • Slot: dynamically pluggable component
  • Simple case
<div>
  <p>数据列表(原本的)</p>
  <ul>
    <li>AAA</li>
    <li>BBB</li>
    <li>CCC</li>
  </ul>
</div>
————————————————————————————————
<div id="vue">
  <list>
    <!--绑定插槽 : 使用 slot 属性绑定,引号里的值,必须和下面的 name 属性一样-->
    <!--绑定数据 : 冒号后面是组件中定义的值
    引号里面是 data 数据的字段值
    不能混淆-->
    <list-title slot="list-title" :title="l_title"></list-title>
    <list-items slot="list-items" v-for="item in l_items" :item="item"></list-items>
  </list>
</div>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script>
  Vue.component("list",{
      
      
    template:
      '<div>\
      <slot name="list-title"></slot>\
      <ul>\
      <slot name="list-items"></slot>\
      </ul>\
      </div>'
  });
  // 定义数据,插入插槽
  Vue.component("list-title",{
      
      
    props: ['title'],
    template: '<div>{
      
      {title}}</div>'
  });

  Vue.component("list-items",{
      
      
    props: ['item'],
    template: '<li>{
      
      {item}}</li>'
  });

  var vm = new Vue({
      
      
    el: "#vue",
    data: {
      
      
      l_title: "标题————",
      l_items:["AA","BBB","CCCC"]
    }
  });
</script>

Page effect
image.png

12. Custom event content distribution

  • Based on the above case, I hope to add a delete button after each line, and click delete to delete and change the line.
  1. Make slight modifications first, add a delete button, bind the click event, and print the subscript after clicking.
  2. Add delete method in vue object
  3. Test the two methods written above. Click the delete button image.pngto call the removeItem method on the console image.png
    . These two methods are successful respectively. How to make the connection between these two methods?
  4. Let the component call the event through this.$emit("custom event name", parameter)
  5. test
    image.png
  6. Simple diagram of the process
    image.png
<list-items slot="list-items" v-for="(item,index) in l_items" :item="item" :index="index"></list-items>
 
var vm = new Vue({
  el: "#vue",
  data: {
  l_title: "标题————",
  l_items:["AA","BBB","CCCC"]
  },
  methods: {
  removeItem: function (index){
  // 打印信息
  console.log("删除了"+this.l_items[index]);
  // 表示从 index 开始,删除 n 个元素
  this.l_items.splice(index,1);
  }
  }
  });
<!--数据绑定 :把 items 中的每一项元素遍历出来命名为 item 再和下面的 item 绑定-->
<!--事件绑定 :自定义一个名为 diyremove 的事件,先和vue对象中的 removeItem 方法绑定
再去到组件中的 remove 和 diyremove 事件绑定-->
<!--注意 : 属性值都要小写,大写不生效,也不会报错 ; 在自定义事件绑定方法的时候 v-on 不能缩写-->
<list-items slot="list-items" v-for="(item,index) in l_items" :item="item" :index="index" v-on:diyremove="removeItem(index)"></list-items>

13. View-cli

13.1 What is vue-cli

A scaffolding officially provided by vue-cli is used to quickly generate a vue project template; the
predefined directory structure and basic code are just like when we create a Maven project, we can choose to create a skeleton project. This skeleton project is the scaffolding. Our development is faster;
main functions:

  • Unified directory structure
  • local debugging
  • Hot deployment
  • unit test
  • Integrated packaging goes online

13.2 Required environment

  1. Download Node.js, select windows 64-bit
  2. Install NodeJs and continue to the next step
  3. To check whether the installation is successful, enter node -v under cmd and check whether the version number can be printed correctly!
  • Install Node.js Taobao Image Accelerator (cnpm)
  • Install vue-cli
CMD 命令)
-g 就是全局安装
npm install cnpm -g --registry=https://registry.npm.taobao.org

# 或使用如下语句解决 npm 速度慢的问题
npm install --registry=https://registry.npm.taobao.org

The installation process is a bit slow.
The installation location is: C:\Users\Administered\AppData\Roaming\npm

(CMD 命令)
 cnpm install vue-cli -g	

vue list

image.png

13.3 Vue-cli program

  1. Use cmd in the folder to create a vue project named myvue and package it with the webpack packaging tool
  2. Initialize and run the myvue project
(CMD 命令)
 # 先找到要创建该文件的目录
 # 这里的 myvue 是项目名称,可以根据自己的需求起名
 vue init webpack myvue

image.png
Description:
1. Project name : Project name, just press Enter by default
2. Project description : Project description, just press Enter by default
3. Author : Project author, just press Enter by default
4. Vue build : Compile, choose first 5. Install vue-router
: Whether to install vue-router, select n not to install ( you will need to add it manually later) 6. Use ESLint to lint your code : Whether to use ESLint for code checking, select n not to install (you will need to add it manually later) Add) 7. Set up unit tests : related to unit testing, select n not to install (you need to add it manually later) 8. Setup e2e tests with Nightwatch : related to unit testing, select n not to install (you need to add it manually later) 9. Should we run npm install for you after the project has been created : Initialize directly after the creation is completed, select n, we execute it manually; run the result! The generated file





image.png

(CMD 命令)
# 进入文件夹
cd myvue
# 安装环境
npm install --registry=https://registry.npm.taobao.org
# 启动项目
npm run dev
# 停止 ctrl + c

After running successfully
image.png

14. Webpack

14.1 What is webpack

Webpack can be seen as a static module packager : what it does is to analyze your project structure, find JavaScript modules and other extension languages ​​​​that browsers cannot run directly (Scss, TypeScript, etc.), and package them into appropriate format for use by browsers.

14.2 Why use webpack

Many web pages today can actually be regarded as feature-rich applications, with complex JavaScript code and a large number of dependency packages. In order to simplify the complexity of development, many good practices have emerged in the front-end community

  1. Modularization allows us to refine complex programs into small files;
  2. Similar to TypeScript, a development language based on JavaScript: it allows us to implement features that cannot be used directly in the current version of JavaScript, and can later be converted into JavaScript files so that the browser can recognize them;
  3. CSS preprocessors such as scss, less...
    These improvements have indeed greatly improved our development efficiency, but the files developed using them often require additional processing to be recognized by the browser, and manual processing is very cumbersome. This provides the need for the emergence of tools like WebPack.

14.3 Install Webpack

WebPack is a module loader and packaging tool that can process and use various resources, such as JS, JSX, ES 6, SASS, LESS, images, etc., as modules.
Installation command

(CMD 命令)
 npm install webpack -g --registry=https://registry.npm.taobao.org
 npm install webpack-cli -g --registry=https://registry.npm.taobao.org

Test whether the installation is successful

webpack -v
webpack-cli -v

14.4 Configuration

Create webpack.config.js configuration file

  • entry: entry file, specify which file Web Pack uses as the entry point of the project
  • output: output, specifies WebPack to place the processed files to the specified path
  • module: module, used to process various types of files
  • plugins: plug-ins, such as: hot update, code reuse, etc.
  • resolve: Set the path to point to
  • watch: monitoring, used to package directly after setting file changes
module.exports = {
  entry:"",
    output:{
    path:"",
      filename:""
  },
  module:{
    loaders:[
      {test:/\.js$/,;\loade:""}
    ]
  },
  plugins:{},
  resolve:{},
  watch:true
}

Directly run the webpack command to package

14.5 Using webpack

  1. Create project: webpack-study
  2. Create a directory named modules to place resource files such as JS modules
  3. Create a module file under modules: hello.js is used to write JS module related code
// 暴露一个方法
exports.sayHi = function(){
    
    
  document.write("<h1>Hello World</h1>");
}
  1. Create an entry file named main.js under modules to set the entry attribute when packaging.
// 引入 hello.js,相当于java的对象 
var hello = require("./hello");
// 调用 hello.js 中的方法
hello.sayHi();
  1. Create the webpack.config.js (note: dot) configuration file in the webpack-study directory and use the webpack command to package it
// 把 module 导出
module.exports = {
    
    
  // 目标文件
  entry: './modules/main.js',
  // 输出地址
  output: {
    
    
    filename: "./js/bundle.js"
  }
}
  1. Pack the file you just wrote into the webpack-study directory

image.png

  1. Introduced in HTML page
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<script src="dist/js/bundle.js"></script>


</body>
</html>
  1. open page
    image.png

15. vue-router

15.1 Description

Vue Router is the official routing manager (path jump) of Vue.js. It is deeply integrated with the core of Vue.js, making it easy to build single-page applications. Features included are:

  1. Nested route/view tables
  2. Modular, component-based routing configuration
  3. Routing parameters, queries, wildcards
  4. View transition effect based on Vue.js transition system
  5. Fine-grained navigation control
  6. Links with automatically activated CSS classes
  7. HTML5 history mode or hash mode, automatically downgraded in IE9
  8. Custom scroll bar behavior

15.2 Installation

Test and learn
cmd based on the first vue-cli. Enter the myvue directory and execute

可以用
cnpm install vue-router --save-dev
没成功
npm install vue-router --save-dev --registry=https://registry.npm.taobao.org

15.3 Use

  1. Clean the code, delete the images in the src directory, and the components in the components directory. Modify App.vue.
  2. Startup project
  3. Modify App.vue
  4. Create a new Vue component in components: Content.vue
  5. Create a new Vue component in components: Main.vue
  6. Create a new package (router) under src and create a new file in the package: index.js
  7. Modify main.js
  8. Modify the template part in App.vue
  9. open page
    image.png
    image.png
    image.png
<template>
  <div id="app">
  </div>
</template>
<script>
  export default {
    name: "App"
  }
</script>
<style>
  #app {
    font-family: 'Avenir', Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
    margin-top: 60px;
  }
</style>
<template>
  <div id="app">
    <h1>呵呵</h1>
  </div>
</template>

The discovered project is automatically Bulid, and the page is automatically refreshed.
This is Vue’s hot deployment.

<template>
  <h1>Content</h1>
</template>
<script>
  export default {
    name: "Content"
  }
</script>
<!-- 加上 scoped 表示只会在当前组件生效 -->
<style scoped>
</style>
<template>
  <h1>首页</h1>
</template>
<script>
  export default {
      
      
    name: "main"
  }
</script>
<style scoped>
</style>
// 导入文件
import Vue from "vue";
import VueRouter from "vue-router";
// 导入组件
import Content from "../components/Content";
import Main from "../components/Main";

// 安装路由
Vue.use(VueRouter);

// 配置导出路由
export default new VueRouter({
    
    
  routes: [
    {
    
    
      // 类似于 @RequestMapping 接收一个请求,返回一个页面
      // 路由的路径
      path: '/content',
      // 配置名称
      name: 'content',
      // 跳转的组件
      component: Content
    },
    {
    
    
      // 路由的路径
      path: '/main',
      // 配置名称
      name: 'Main',
      // 跳转的组件
      component: Main
    }
  ]
});
import Vue from 'vue'
import App from './App'
// 导入 vue-router 的路由配置
// 这里是写在 index.js 文件中的所以导入该文件
// 因为文件名是 index 会自动扫描该文件,所以index可省
// 注意!! 这里必须写 router ,写错前端页面就报错
import router from "./router/index";

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
    
    
  el: '#app',
  // 配置路由,上面的组件名
  router,
  components: {
    
     App },
  template: '<App/>'
})
<template>
  <div id="app">
    <h1>呵呵</h1>
    <!--跳转链接,点击链接显示对应内容-->
    <!--类似于原来的 <a></a> ;
    to 类似于原来的 href,后面的值就是配置的路由-->
    <router-link to="/main">首页</router-link>
    <router-link to="/content">内容页</router-link>
    <!--展示视图,理解为用于展示上面两个链接对应内容的区域-->
    <router-view></router-view>
  </div>
</template>

16. Vue+ElementUI

  1. Create a project named vue-elementuivue init webpack vue-elementui
  2. Install four plug-ins: vue-router, element-ui, sass-loader, node-sass
# 进入工程
cd vue-elementui
# 安装 vue-router
cnpm install vue-router --save-dev 
# 安装 element-ui
cnpm i element-ui -S 
# 安装依赖
cnpm install 
# 安装 SASS 加载器
cnpm install sass-loader node-sass --save-dev
# 启动测试
npm run dev


测试报错:
cnpm install --save vue-hot-reload-api
  1. Restore the project to an empty project, delete logo.png and HelloWorld.vue under src, and modify App.vue as follows:
<template>
 </template>
 <script>
 export default {
      
      
   name: 'App'
 }
 </script>
 <style>
 #app {
      
      
   font-family: 'Avenir', Helvetica, Arial, sans-serif;
   -webkit-font-smoothing: antialiased;
   -moz-osx-font-smoothing: grayscale;
   text-align: center;
   color: #2c3e50;
   margin-top: 60px;
 }
 </style>
  1. Create a new folder router: store routing information
    views: store view components
    components: store functional components
    image.png
  2. Create a new view component under the views package: Main.vue
<template>
  <h1>首页</h1>
</template>
<script>
  export default {
    name: "Main"
  }
</script>
<style scoped>
</style>
  1. Create a new view component under the views package: Login.vue
<template>
  <div>
    <el-form ref="loginForm" :model="form" :rules="rules" label-width="80px" class="login-box">
      <h3 class="login-title">欢迎登录</h3>
      <el-form-item label="账号" prop="username">
        <el-input type="text" placeholder="请输入账号" v-model="form.username"/>
      </el-form-item>
      <el-form-item label="密码" prop="password">
        <el-input type="password" placeholder="请输入密码" v-model="form.password"/>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" v-on:click="onSubmit('loginForm')">登录</el-button>
      </el-form-item>
    </el-form>

    <el-dialog
      title="温馨提示"
      :visible.sync="dialogVisible"
      width="30%"
      :before-close="handleClose">
      <span>请输入账号和密码</span>
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
  export default {
    name: "Login",
    data() {
      return {
        form: {
          username: '',
          password: ''
        },

        // 表单验证,需要在 el-form-item 元素中增加 prop 属性
        rules: {
          username: [
            {required: true, message: '账号不可为空', trigger: 'blur'}
          ],
          password: [
            {required: true, message: '密码不可为空', trigger: 'blur'}
          ]
        },

        // 对话框显示和隐藏
        dialogVisible: false
      }
    },
    methods: {
      onSubmit(formName) {
        // 为表单绑定验证功能
        this.$refs[formName].validate((valid) => {
          if (valid) {
            // 使用 vue-router 路由到指定页面,该方式称之为编程式导航
            this.$router.push("/main");
          } else {
            this.dialogVisible = true;
            return false;
          }
        });
      }
    }
  }
</script>

<style lang="scss" scoped>
  .login-box {
    border: 1px solid #DCDFE6;
    width: 350px;
    margin: 180px auto;
    padding: 35px 35px 15px 35px;
    border-radius: 5px;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
    box-shadow: 0 0 25px #909399;
  }

  .login-title {
    text-align: center;
    margin: 0 auto 40px auto;
    color: #303133;
  }
</style>
  1. Write routing configuration information under the router file: index.js
import Vue from 'vue';
import VueRouter from "vue-router";

import Main from "../views/Main";
import Login from "../views/Login";

// 显式的使用导入的组件
Vue.use(VueRouter);

export default new VueRouter({
    
    
  routes: [
    {
    
    
      path: "/login",
      name: "login",
      component: Login
    },{
    
    
      path: "/main",
      name: "main",
      component: Main
    }
  ]
});
  1. Modify main.js
import Vue from 'vue'
import App from './App'
import router from './router'
// 导入 elementUI
import ElementUI from 'element-ui'
// 导入 elementUI 对应的 CSS
import 'element-ui/lib/theme-chalk/index.css'

Vue.use(router)
Vue.use(ElementUI)

new Vue({
    
    
  el: '#app',
  // 配置 elementUI
  render: h => h(App),
  router
})
  1. Modify App.vue
<template>
  <div id="app">
    <!-- 因为 main.js 中配置了,element-ui 自动渲染,所以这里只需要有一个这个标签就好了 -->
    <router-view></router-view>
  </div>
</template>x
  1. If an error is reported when starting the project , try downgrading the sass-loader version. Find the package.json file,
    image.png
    find the sass-loader attribute,
    image.png
    change the subsequent version number to ^7.3.1,
    and reinstall the environment dependencies.npm install
  2. Just enter your username and password, log in and find that you go to the home page to view the Login.vue code , which is in <script>< /script>
    image.png

The installation steps are the same as before

Restart the project and visit http://localhost:8080/#/login
image.png

17. Route nesting

  • Nested routing is also called sub-routing. In practical applications, it is usually composed of multiple layers of nested components, such as:
    image.png
  1. Create a new user package in views
  2. Under the user package, create a new List.vue
<template>
  <h1>用户列表</h1>
</template>
<script>
  export default {
    name: "List"
  }
</script>
<style scoped>
</style>
  1. Under the user package, create a new Profile.vue
<template>
  <h1>个人信息</h1>
</template>
<script>
  export default {
    name: "Profile"
  }
</script>
<style scoped>
</style>
  1. Modify Main.vue and add a sidebar
<template>
  <div>
  <el-container>
  <el-aside width="200px">
  <el-menu :default-openeds="['1']">
  <el-submenu index="1">
  <template slot="title"><i class="el-icon-caret-right"></i>用户管理</template>
  <el-menu-item-group>
  <el-menu-item index="1-1">
  <!--插入的地方-->
  <router-link to="/user/profile">个人信息</router-link>
  </el-menu-item>
  <el-menu-item index="1-2">
  <!--插入的地方-->
  <router-link to="/user/list">用户列表</router-link>
  </el-menu-item>
  </el-menu-item-group>
  </el-submenu>
  <el-submenu index="2">
  <template slot="title"><i class="el-icon-caret-right"></i>内容管理</template>
  <el-menu-item-group>
  <el-menu-item index="2-1">分类管理</el-menu-item>
  <el-menu-item index="2-2">内容列表</el-menu-item>
  </el-menu-item-group>
  </el-submenu>
  </el-menu>
  </el-aside>

  <el-container>
  <el-header style="text-align: right; font-size: 12px">
  <el-dropdown>
  <i class="el-icon-setting" style="margin-right: 15px"></i>
  <el-dropdown-menu slot="dropdown">
  <el-dropdown-item>个人信息</el-dropdown-item>
  <el-dropdown-item>退出登录</el-dropdown-item>
  </el-dropdown-menu>
  </el-dropdown>
  </el-header>
  <el-main>
  <!--在这里展示视图-->
  <router-view />
  </el-main>
  </el-container>
  </el-container>
  </div>
  </template>
  <script>
  export default {
    
    
  name: "Main"
}
  </script>
  <style scoped lang="scss">
  .el-header {
    
    
  background-color: #B3C0D1;
  color: #333;
  line-height: 60px;
}
.el-aside {
    
    
  color: #333;
}
</style>
  1. Modify index.js, routing information
import Vue from 'vue';
import VueRouter from "vue-router";

import Main from "../views/Main";
import Login from "../views/Login";

import List from "../views/user/List";
import Profile from "../views/user/Profile";

// 显式的使用导入的组件
Vue.use(VueRouter);

export default new VueRouter({
    
    
  routes: [
    {
    
    
      path: "/login",
      name: "login",
      component: Login
    },{
    
    
      path: "/main",
      name: "main",
      component: Main,
      // 嵌套路由
      children: [
        {
    
    
          path: "/user/profile",
          component: Profile
        },{
    
    
          path: "/user/list",
          component: List
        }
      ]
    }
  ]
});
  1. Insert routing link in Main.vue to display the view
    image.png
    image.png
  • There are two modes for modifying routing : 1. hash: # in the path; 2. history: modify the file index.js without # in the path
    image.png
  1. open page
    image.png

18. Parameter passing and redirection

18.1 Passing parameters through route

  1. Modify the front-end <router-link> tag
    image.png
  2. Modify routing information in index.js
    image.png
  3. Take out the parameters on the front-end page and modify: Profile.vue. Note that it is route, not router.
    image.png
  4. open page
    image.png

18.2 Passing parameters through props

  • Display username after login is complete
  1. Modified Login.vueimage.png
  2. Modify index.js
    image.png
  3. Home page acquisition: Main.vue
    image.png

18.3 Redirects

  1. Modify index.js and add redirect information
    image.png
  2. Modified Main.vue
    image.png
  3. open page

image.png

19. 404 and routing hooks

19.1 404

  1. Create a new view component: 404.vue
  2. Configure the 404 component into routing information: index.js
    image.png
  3. Start the page and access a non-existent path at will
<template>
  <div>
    <h1>404,页面走丢了!</h1>
  </div>
</template>
<script>
  export default {
    name: "404"
  }
</script>
<style scoped>
</style>

image.png

19.2 Routing hooks

1. Basic use

  • beforeRouteEnter: hook executed before entering the route
  • beforeRouteLeave: hook executed before leaving the route
  1. Modify Profile.vue
    image.png
  2. open page
  • Parameter description :
    • to: The path information that the route will jump to
    • from: path information before path jump
    • next: control parameters of routing
      • next() jumps to the next page
      • next('/path') changes the jump direction of the route so that it jumps to another route
      • next(false) returns to the original page
      • next((vm)=>{}) is only available in beforeRouteEnter, vm is the component instance

2. Use asynchronous requests in hook functions

  1. Install Axios
  2. main.js references Axios
  3. To prepare data, only the files in our static directory can be accessed, so we put the static files in this directory. Create a new folder mock (test data) under static and create a new data.json
  4. Make an asynchronous request in beforeRouteEnter and modify Profile.vue
  5. Access the /user/profile page console and output the obtained data.
cnpm install --save vue-axios
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)
{
    
    
  "name": "呵呵",
  "url": "https://blog.csdn.net/weixin_44449838",
  "page": 123,
  "isNonProfit": true,
  "address": {
    
    
    "street": "塔克拉玛干沙漠",
    "city": "新疆",
    "country": "中国"
  },
  "links": [
    {
    
    
      "name": "Google",
      "url": "http://www.google.com"
    },
    {
    
    
      "name": "Baidu",
      "url": "http://www.baidu.com"
    }
  ]
}
export default {
    
    
  //第二种取值方式
  // props:['id'],
  name: "UserProfile",
  //钩子函数 过滤器
  beforeRouteEnter: (to, from, next) => {
    
    
    //加载数据
    console.log("进入路由之前")
    next(vm => {
    
    
      //进入路由之前执行getData方法
      vm.getData()
    });
  },
  beforeRouteLeave: (to, from, next) => {
    
    
    console.log("离开路由之前")
    next();
  },
  //axios
  methods: {
    
    
    getData: function () {
    
    
      this.axios({
    
    
        method: 'get',
        url: 'http://localhost:8080/static/mock/data.json'
      }).then(function (response) {
    
    
        console.log(response)
      })
    }
  }
}

Guess you like

Origin blog.csdn.net/qq_53517370/article/details/128875793