axios在vue用的使用,$ref基本使用,$nextTick(回调函数),动态组件,组件缓存,插槽(匿名,具名,作用域)使用,自定义指令的使用(局部,全局)

1,107 阅读4分钟

axios 使用

基本用法

axios在vue的用法,先下载第三方依赖包,然后用法如下

import axios from 'axios'
export default {
  methods: {
    getBooks() {
      // axios 发请求只需要带上一个配置对象
      axios({
        // url 地址
        url: 'http://123.57.109.30:3006/api/getbooks',
        // method 请求方法
        method: 'get'
      }).then(res=>{
        // 这个库有个特点, 会将你发请求的配置放在返回中一起交给你, 最终的数据, 其实是放在 res.data
        console.log(res.data);
      })
    }
  }
}

get请求带参方式

        params: {
          // get 请求的传输只能用参数方式
          // query 查询字符串的传参方式 => 这个参数会在 url 后面用 ?a=1 的形式拼接
          bookname: this.bookName
        }

post 请求带参方式

        data: {
          // post 请求一般用这个方式带参数, 实际的作用是将数据放入到请求载荷(请求体)中
          appkey: "7250d3eb-18e1-41bc-8bb2-11483665535a",   //这个就是自己密码的意思
          ...this.bookData
        }

其实 params 和 data 的传参方式一个用在 get 一个用在 post 这种说法只是一般约定, 但是技术上其实可以有例外, 比较确定的区别是, params 会将数据待在 url? 后面查询字符串, data 将数据放在请求载荷(请求体)

中午拓展延展运算符

也叫展开运算符(简单来说就是把数据剥去一层外壳,当然它还有其他很多用法)

// ... 展开运算符/延展运算符
// ...[1,2,3] => 1,2,3
// ...{name: 'tom', age: 13} => name: 'tom', age: 13
// const arr = [1,2,3]
// const arr2 = arr
// arr2[1] = 666
// const arr2 = [...arr]
// console.log(...[1,2,3]) => console.log(1,2,3);
// console.log(...{name: 'tom', age: 13}) => console.log(name: 'tom', age: 13)

封装全局axios

改造全局配置(就是配置一个基地址)

// /src/utils/request.js
// 改造 axios 添加基地址后重新导出
import axios from 'axios'
axios.defaults.baseURL = 'http://123.57.109.30:3006/api'

export default axios

封装api函数管理层(封装一个axios请求)

// /src/api/book.js
// 这里是统一管理关于书籍的请求接口函数
// 获取书籍的a
import request from '@/utils/request'pi
export function getBooks(params) {
  return request({
    // url 地址
    url: '/getbooks',
    // method 请求方法
    method: 'get',
    params: params,
    data: {
      a:666
    }
  })
}
// App.vue 最终使用
import {getBooks} from '@/api/book'
const params = {
  bookname: this.bookName
}
getBooks(params).then(res=>{
  // 这个库有个特点, 会将你发请求的配置放在返回中一起交给你, 最终的数据, 其实是放在 res.data
  console.log('成功');
  console.log(res.data);
}).catch(err=>{
  console.log(err);
})

$refs

基本使用

就是使用$ref或缺dom元素,代码用法如下

<template>
  <div>
    <!-- vue 获取元素的方法第一步设置一个 ref 属性 -->
    <div id="myBox" ref="myBoxRef">盒子</div>
  </div>
</template>

<script>
export default {
  mounted() {
    // console.log(document.getElementById('myBox'));
    // vue 当中获取元素方法第二部 this.$refs.名字
    console.log(this.$refs.myBoxRef);
  }
}
</script>

<style>

</style>

获取子组件内的属性和方法

用$ref或缺子组件里面的属性和方法,代码用法如下

  components: {MyBox},
  mounted() {
    // console.log(document.getElementById('myBox'));
    // vue 当中获取元素方法第二部 this.$refs.名字
    // console.log(this.$refs.myBoxRef);
    // 用id获取组件
    console.log(document.getElementById('zjBox'));
    // 用ref获取组件
    console.log(this.$refs.zjBoxRef);
    setTimeout(() => {
      this.$refs.zjBoxRef.msg = '789'
      this.$refs.zjBoxRef.dajiao()
    }, 1000);
  
  }

$nextTick(回调函数)

基本使用

等待当前所有代码执行完毕, 页面更新结束之后执行传入的回调函数(类似onload数据加载完成才执行,它这个是dom元素)

ta是vue的一个方法,相当于会自动执行异步的所有方法,一个个的试,如果都不行最终会执行延时器

    toggleShow() {
      this.isShow = !this.isShow
      // 希望每次显示的时候都将这个 dom 打印在控制台
      // console.log(this.$refs.myBox);
      // this.$nextTick(回调函数) 作用是等待页面更新完毕执行回调函数
      this.$nextTick(()=>{
        console.log(this.$refs.myBox);
      })
    }
<template>
  <div>
    <!-- 有个按钮叫做开始搜索
    点击后自身隐藏, 显示一个输入框
    输入框自动聚焦 -->
    <input v-if="isShowSearch" type="text" ref="search" />
    <button v-else @click="showSearch">开始搜索</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isShowSearch: false,
    };
  },
  methods: {
    showSearch() {
      this.isShowSearch = !this.isShowSearch;
      // 这里我想要聚焦输入框, 只要获取输入框 dom 执行其中 focus 函数即可
      // 设置显示取反没有马上渲染
      // this.$refs.search.focus()
      // 如果想要等待渲染完毕有了input再执行,使用 this.$nextTick
      this.$nextTick(() => {
        this.$refs.search.focus();
      });
    },
  },
};
</script>

<style>
input {
  margin-top: 300px;
}
</style>

动态组件

<template>
  <div>
    <button @click="componentName = 'UserInfo'">个人信息</button>
    <button @click="componentName = 'UserName'">账号登录</button>
    <!-- vue内置标签 component 是动态组件挂载点, 会根据绑定的 is 属性显示名字对应的组件 -->
    <component :is="componentName" />
  </div>
</template><script>
import UserInfo from '@/components/UserInfo.vue'
import UserName from '@/components/UserName.vue'
export default {
  data() {
    return { 
      componentName: 'UserInfo'
    }
  },
  components: {
    UserInfo,
    UserName
  }
}
</script><style></style>

组件缓存

初步使用

双标签里面包裹着要缓存的动态组件

    <keep-alive>
      <component :is="componentName" />
    </keep-alive>

拓展生命周期

组件缓存会触发以下的两个钩子函数,不写东西都是存在的,如果要添加什么就是跟写生命周期一样就行

    activated() { //激活
      console.log('缓存的组件被激活(显示)');
    },
    deactivated() {//失效
      console.log('缓存的组件被隐藏');
    }

插槽使用

基本操作

用于实现组件的内容分发, 通过 slot 标签, 可以接收到写在组件标签内的内容

vue提供组件插槽能力, 允许开发者在封装组件时,把不确定的部分定义为插槽

语法口诀:

  1. 组件内用占位

  2. 使用组件时子组件的名字 夹着的地方, 传入标签替换slot

    组件
<template>
  <div class="topBar">
    <div class="left"></div>
    <div class="right">
      <!-- 插槽占位标签 -->
      <slot/>
    </div>
  </div>
</template><script>
export default {
​
}
</script><style lang="less" scoped>
.topBar {
  display: flex;
  justify-content: space-between;
  border: 2px solid salmon;
}
</style>
根组件
<template>
  <div>
    <!-- 员工页使用, 就要带导入员工新建员工按钮 -->
    <TopBar>
      <button>新增员工</button>
      <button>导入员工</button>
    </TopBar>
    <!-- 工资页面使用需要一个报表按钮 -->
    <TopBar>
      <button>报表</button>
    </TopBar>
  </div>
</template><script>
import TopBar from '@/components/TopBar.vue'
export default {
  components: {
    TopBar
  }
}
</script><style></style>

默认显示内容设定

夹着内容默认显示内容, 如果不给插槽slot传东西, 则使用夹着的内容在原地显示

组件
<template>
  <div class="topBar">
    <div class="left"></div>
    <div class="right">
      <!-- 插槽占位标签 -->
      <slot>
        <!-- 如果外面没有传入, 默认显示的内容 -->
        欢迎来到我的页面
      </slot>
    </div>
  </div>
</template>

具名插槽

目标: 当一个组件内有2处以上需要外部传入标签的地方

传入的标签可以分别派发给不同的slot位置

要求: v-slot一般用跟template标签使用 (template是html5新出标签内容模板元素, 不会渲染到页面上, 一般被vue解析内部标签)

components/04/Pannel.vue - 留下具名slot

组件
    <div class="left">
      <slot name="left"/>
    </div>
    <div class="right">
      <!-- 插槽占位标签 -->
      <slot name="right">
        <!-- 如果外面没有传入, 默认显示的内容 -->
        欢迎来到我的页面
      </slot>
    </div>
根组件
    <TopBar>
      <!-- v-slot: 可以被简化成# -->
      <template #left>
        一共 666 位员工
      </template>
      <template #right>
        <button>新增员工</button>
        <button>导入员工</button>
      </template>
    </TopBar>
    <!-- 工资页面使用需要一个报表按钮 -->
    <TopBar>
      <template v-slot:left>
        5月工资报表
      </template>
      <template v-slot:right>
        <button>报表</button>
      </template>
    </TopBar>

作用域插槽

例子: 默认内容在子组件中, 但是父亲在给插槽传值, 想要改变插槽显示的默认内容

口诀:

  1. 子组件, 在slot上绑定属性和子组件内的值

  2. 使用组件, 传入自定义标签, 用template和v-slot="自定义变量名"

  3. scope变量名自动绑定slot上所有属性和值

子组件

      <slot :row="monthList" name="left">
        {{monthList.first}} 工资报表
      </slot>

父组件

      <template v-slot:left="scope">
       {{scope.row.second}} 工资报表
      </template>

作用域插槽具体使用场景

封装一个灵活的表格组件

自定义指令的使用方式

注意:

inserted方法 - 指令所在标签, 被插入到网页上触发(一次)

update方法 - 指令对应数据/标签更新时, 此方法执行

<template>
  <div>
    <!-- 使用自定义指令, 跟普通vue指令一样, 请千万注意,要加上 v- 前缀 -->
    <input type="text">
    <br>
    <input type="text">
    <br>
    <input v-autofocus type="text">
  </div>
</template><script>
export default {
  // 局部指令注册
  // directives: {
    // 指令名字符串: {
        // 配置对象
        // 可以指定使用这个指令的元素, 在不同生命周期执行的函数
        // 在这些钩子函数的形参中, 默认第一个可以获取元素本身, 第二个可以用来传参
        // inserted,
        // update
    // }
  // }
  directives: {
    autofocus: {
      inserted(el) {
        console.log(el, '自动聚焦');
        el.focus()
      }
    }
  }
}
</script><style></style>
全局自定义指令
​
// 全局指令注册 - 到处"直接"使用
//语法:directives:{
//  指令名:{
// 函数加要指定的指令内容
// }
// }
// 例子:
// Vue.directive("gfocus", {
//   inserted(el) {
//     el.focus() // 触发标签的事件方法
//   }
// })
​