Vue asynchronous communication, computed properties, slot slots and custom events

Vue asynchronous communication, computed properties, slot slots and custom events

Refer to [Crazy God Says Java] Vue's latest quick start tutorial is easy to understand . Video learning content

1. Axios asynchronous communication

Axios is an open source asynchronous communication framework that can be used in browsers and NodeJS. Its main function is to implement Ajax asynchronous request communication .

CDN installation method:

<script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>

Why use Axios?

Since Vue.js is a view layer framework and the author strictly adheres to SoC (the principle of separation of concerns), Vue.js does not include the communication function of Ajax. In order to solve the communication problem, the author developed vue-resourcesa , but after entering the 2.0 version, the maintenance of the plug-in is stopped, and the Axios framework is recommended to reduce the use of Ajax requests under JQuery, because it manipulates DOM elements too frequently .

Instructions:

Vue.axios.get(api).then((response) => {
  console.log(response.data)
})

Data preparation JSON:

{
    
    
  "name": "trainingl",
  "age": "22",
  "sex": "男",
  "url":"https://www.suda.edu.cn/",
  "address": {
    
    
    "street": "干将东路",
    "city": "江苏省苏州市",
    "country": "中国"
  },
  "links": [
    {
    
    
      "name": "Web of suda",
      "url": "https://www.suda.edu.cn/"
    },
    {
    
    
      "name": "baidu",
      "url": "https://www.baidu.com"
    },
    {
    
    
      "name": "Graduate of SUDA",
      "url": "http://yjs.suda.edu.cn/"
    }
  ]
}

Test content : Bind a click event to the button v-on:click="getInfo()". When the user clicks the button, an asynchronous request will be triggered through axios. The content of the request is a local JSON data.

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <h3>{
   
   {message}}</h3>
    <button v-on:click="getInfo()">获取用户信息</button>
    <div>{
   
   {info.name}}</div>
    <div>{
   
   {info.age}}</div>
    <div>{
   
   {info.address.country}}{
   
   {info.address.city}}{
   
   {info.address.street}}</div>
    <div><a v-bind:href="info.url">点我跳转</a></div>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>
<script>
    var vm = new Vue({
     
     
        el:"#app",
        data(){
     
     
            return{
     
     
                message: 'Hello World',
                //请求调用的返回参数格式,必须和json字符串一样
                info:{
     
     
                    name: null,
                    age: null,
                    sex: null,
                    url: null,
                    address: {
     
     
                        street: null,
                        city: null,
                         country: null
                    }
                }
            }
        },
        methods:{
     
     
            getInfo: function () {
     
     
                axios
                    .get("./data.json")
                    .then(response => (this.info=response.data))
                    .catch(function (error) {
     
      //请求失败处理
                        console.log(error);
                    })
            }
        },
        //钩子函数,链式编程,ES6新特性
        mounted(){
     
     
            //如果希望加载页面时触发异步请求,则将axios写在这里
        }
    })
</script>
</body>
</html>

insert image description here


2. Vue Computed Properties

The focus of the calculation attribute is on the word attribute (attribute is a noun). First, it is an attribute, and secondly, this attribute has the ability to calculate (calculation is a verb). The calculation here is a function. Simply put, it is a property that can cache the result of a calculation (turn the behavior into a static property).

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="app">
    <div>currentTime1:{
   
   {currentTime1()}}</div>
    <div>currentTime2:{
   
   {currentTime2}}</div>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
    var vm = new Vue({
     
     
        el: '#app',
        data: {
     
     
            message: 'Hello, World!'
        },
        methods:{
     
     
            currentTime1: function () {
     
     
                return new Date().toLocaleString(); //返回一个时间
            }
        },
        computed: {
     
     
            //计算属性:method,computed 方法名不能重名
            currentTime2: function () {
     
     
                this.message;
                return new Date().toLocaleString();
            }
        }
    })
</script>
</body>
</html>

We can use methods to replace computed, both of which are the same in effect, but computed is based on its dependency cache, which will only be re-valued when the relevant dependencies change. With methods, when re-rendering, the function will always be called again.

Conclusion: When calling a method, it needs to be calculated every time. Since there is a calculation process, it will inevitably generate system overhead. What if the result does not change frequently? At this point, you can consider caching the result, which can be easily done by using computed properties. The main feature of computed properties is to cache the calculation results that change infrequently to save our system overhead.


3. slot slot

Before understanding slot slots, you need to understand the basics of vue components and the process of passing values.

Vue implements a set of APIs for content distribution, using the <slot>element as an outlet to carry distributed content, called a slot. **Slots are essentially an extension of subcomponents, <slot>passing content to a specified location inside the component through the slot. **Can be used in scenes where components are composed.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="app">
    <todo>
        <todo-title slot="todo-title" v-bind:name="title"></todo-title>
        <todo-items slot="todo-items" v-for="item in todoItems" v-bind:item="item"></todo-items>
    </todo>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
    //slot 插槽。这个组件要定义在前面
    Vue.component("todo", {
     
     
        template: '<div>\
                <slot name="todo-title"></slot>\
                <ol>\
                <slot name="todo-items"></slot>\
                </ol>\
                </div>'
    });

    //子组件,子组件的传值方式与组件是一样的
    Vue.component('todo-title',{
     
     
       //属性
       props: ["name"],
       template: '<div>{
     
     {name}}</div>'
    });
    Vue.component('todo-items',{
     
     
        //属性
        props: ["item"],
        template: '<li>{
     
     {item}}</li>'
    });
    
    var vm = new Vue({
     
     
        el:"#app",
        data:{
     
     
            //标题
            title: "中国华东五大名校",
            //列表
            todoItems: ['浙江大学', '上海交通大学', '复旦大学', '南京大学', '中国科学技术大学']
        }
    })
</script>
</body>
</html>

todoDeclare two slot slots in the custom component , and then define two subcomponents todo-titleand todo-itemsinsert the two components into the two slots. and are used when data needs to be passed between components v-bindand props.


4. Vue custom events

Now if we want to bind events on the slot slot (child component), such as adding a delete button after each <li>Item</li>item , the user clicks the button to delete the item. Since the data item is in the Vue instance, but the delete operation needs to be done in the component, how can the component delete the data in the Vue instance?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="app">
    <todo>
        <todo-title slot="todo-title" v-bind:name="title"></todo-title>
        <todo-items slot="todo-items" v-for="(item, index) in todoItems" v-bind:item="item" v-bind:index="index" v-on:removes="removeItem(index)"></todo-items>
    </todo>
</div>


<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
    //slot 插槽。这个组件要定义在前面
    Vue.component("todo", {
     
     
        template: '<div>\
                <slot name="todo-title"></slot>\
                <ol>\
                <slot name="todo-items"></slot>\
                </ol>\
                </div>'
    });
    Vue.component('todo-title',{
     
     
       //属性
       props: ["name"],
       template: '<div>{
     
     {name}}</div>'
    });
    Vue.component('todo-items',{
     
     
        //属性
        props: ["item", "index"],
        template: '<li>{
     
     {item}}&emsp;<button @click="remove">删除</button></li>',
        methods: {
     
     
            remove: function (index) {
     
     
                //this.$emit 自定义事件分发
                this.$emit('removes', index)
            }
        }
    });

    var vm = new Vue({
     
     
        el:"#app",
        data:{
     
     
            //标题
            title: "中国华东五大名校",
            //列表
            todoItems: ['浙江大学', '上海交通大学', '复旦大学', '南京大学', '中国科学技术大学']
        },
        methods: {
     
     
            removeItem: function (index) {
     
     
                console.log("删除了"+this.todoItems[index]+"OK");
                this.todoItems.splice(index,1);
            }
        }
    })
</script>
</body>
</html>

Test effect:

Let's analyze the above execution process:

First, we add a button to each list item and bind the click event '<li>{ {item}}&emsp;<button @click="remove">删除</button></li>, and dispatch the event in the methods method of the subcomponent todo-items this.$emit('自定义事件名', 参数).

methods: {
    remove: function (index) {
        //this.$emit 自定义事件分发
        this.$emit('removes', index)
    }
}

Distribute the event to the upper layer for processing v-on:removes="removeItem(index)", and finally call the method defined in the Vue instance methodsproperty to complete.

methods: {
    removeItem: function (index) {
        console.log("删除了"+this.todoItems[index]+"OK");
        this.todoItems.splice(index,1);
    }
}

Note: this.todoItems.splice(index, len)It is a built-in method of array in JavaScript, which means to delete len elements backward from an index of the array.

Guess you like

Origin blog.csdn.net/qq_41775769/article/details/123226822