Vue 异步通信、计算属性、slot插槽和自定义事件

Vue 异步通信、计算属性、slot插槽和自定义事件

      • 1. Axios 异步通信
      • 2. Vue 计算属性
      • 3. slot 插槽
      • 4. Vue 自定义事件

参考【狂神说Java】Vue最新快速上手教程通俗易懂 视频学习内容

1. Axios 异步通信

Axios 是一个开源的可以用在浏览器和 NodeJS 的异步通信框架,它的主要作用就是实现 Ajax 异步请求通信

CDN 安装方法:

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

为什么要使用 Axios?

由于 Vue.js 是一个视图层框架且作者严格遵守 SoC(关注度分离原则),所以 Vue.js 并不包含 Ajax 的通信功能。为了解决通信问题,作者单独开发了一个名为 vue-resources 的插件,不过在进入 2.0 版本之后停止了对该插件的维护,并推荐使用 Axios 框架,减少使用 JQuery 下的 Ajax 请求,因为它操作 DOM 元素过于频繁。

使用方法:

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

数据准备 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/"
    }
  ]
}

测试内容:给按钮绑定一个点击事件 v-on:click="getInfo()",当用户点击按钮时会通过 axios 触发异步请求,请求的内容是本地的一个 JSON 数据。


<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>Titletitle>
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>

Vue 异步通信、计算属性、slot插槽和自定义事件_第1张图片Vue 异步通信、计算属性、slot插槽和自定义事件_第2张图片


2. Vue 计算属性

计算属性的重点突出在属性两个字上(属性是名词),首先它是个属性,其次这个属性有计算的能力(计算是动词),这里的计算就是个函数。简单地说,它就是一个能够将计算结果缓存起来的属性(将行为转化成立静态的属性)。


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
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>

我们可以使用 methods 来替代 computed,效果上两个都是一样的,但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行。

Vue 异步通信、计算属性、slot插槽和自定义事件_第3张图片

结论:调用方法时,每次都需要进行计算,既然有计算过程则必然产生系统开销,那如果这个结果是不经常变化的呢?此时就可以考虑将这个结果缓存起来,采用计算属性可以很方便的做到这一点,计算属性的主要特性就是为了将不经常变化的计算结果进行缓存,以节约我们的系统开销。


3. slot 插槽

在了解 slot 插槽之前,需要对 vue 组件基础以及传值过程有所理解。

Vue 实现了一套内容分发的 API,将 元素作为承载分发内容的出口,被称作插槽。**插槽实质是对子组件的扩展,通过插槽向组件内部指定位置传递内容。**可以应用在组合组件的场景中。


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

    在自定义组件 todo 中声明两个 slot 插槽,然后定义两个子组件 todo-titletodo-items,将这两个组件插入到这两个槽位。组件与子组件之间如果需要传递数据,就会用到 v-bindprops

    Vue 异步通信、计算属性、slot插槽和自定义事件_第4张图片


    4. Vue 自定义事件

    我们现在如果想在 slot 插槽(子组件) 上绑定事件,比如在每个

  • Item
  • 项后增加一个删除按钮,用户点击该按钮则删除该项。由于数据项在 Vue 的实例中,但删除操作要在组件中完成,那么组件如何才能删除 Vue 实例中的数据呢?

    
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Titletitle>
    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: '
    \ \
      \ \
    \
    '
    }); Vue.component('todo-title',{ //属性 props: ["name"], template: '
    {{name}}
    '
    }); Vue.component('todo-items',{ //属性 props: ["item", "index"], template: '
  • {{item}} 
  • '
    , 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>

    测试效果:
    Vue 异步通信、计算属性、slot插槽和自定义事件_第5张图片

    下面我们分析一下上面的执行过程:

    首先,我们给每个列表项增加一个按钮并绑定点击事件 '

  • {{item}} 
  • ,在该子组件 todo-items 的 methods 方法中进行事件分发 this.$emit('自定义事件名', 参数)

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

    将该事件分发到上层处理 v-on:removes="removeItem(index)",最后调用 Vue 实例 methods 属性中定义的方法完成。

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

    注:this.todoItems.splice(index, len) 是 JavaScript 的数组内置方法,表示从数组某一个索引开始,向后删除 len 个元素。

    Vue 异步通信、计算属性、slot插槽和自定义事件_第6张图片

    你可能感兴趣的:(技术笔记,vue)