Vue 组件化开发

动态组件

动态组件指 动态切换组件的显示与隐藏

vue 提供内置 <component> 组件,专门用于实现动态组件渲染。<component :is="comName">

:<component> 切换时,组件会重新创建。可用<keep-alive> 缓存组件

<keep-alive> 生命周期函数

  • 缓存时。自动触发 deactivated 生命周期函数
  • 激活时。自动触发 activated 生命周期函数  (第一次创建也会被激活)

<keep-alive> include,exculde属性

  • include 属性指定:只有名称匹配的组件才会被缓存,多个组件由  ',' 分割
  • exculde 属性指定:排除项不会被缓存
<template>
  <div class="app-container">
    <h1>App 根组件</h1> 
    <hr />
    <button @click="comName = 'Left'">Left</button>
    <button @click="comName = 'Right'">Right</button>
    <div class="box">
       <!--keep-alive  可以把内部组件进行缓存,而不是销毁-->
      <keep-alive include="Left">
         <!-- component 组件占位符  :is 表示渲染组件名称 -->
        <component :is="comName"></component>
      </keep-alive>
    </div>
  </div>
</template>

<script>
import Left from '@/components/Left.vue'
import Right from '@/components/Right.vue'

export default {
  data(){
    return{
      comName:'Left'
    }
  },
  components:{
    Left,
    Right
  }
}
</script>

<style lang="less">
.app-container {
  padding: 1px 20px 20px;
  background-color: #efefef;
}
.box {
  display: flex;
}
</style>

插槽

插槽(slot) 时vue为组件封装着提供的功能。允许开发这在封装组件时,把不确定,希望由用户指定的部分定义为插槽。

############### Left.vue ################# 
<template>
  <div class="left-container">
    <h3>Left 组件</h3>
    <hr />
    <!--声明插槽区域-->
    <!--官方规定solt需要有name 名称,默认为defalut-->
    <!--后备内容,无定义内容时使用-->
    <!--具名插槽:为<slot> 提供名称-->
    <!--作用域插槽:为<slot> 提供属性对应的值-->
    <slot name="myslot" msg="message" :user="user">default text</slot>  
  </div>
</template>

############### App.vue ###########
<template>
  <div class="app-container">
    <h1>App 根组件</h1> 
    <hr /> 
    <div class="box">
      <!--插槽使用-->
      <left>
         <!--v-slot:  简写 #--> 
         <!--scope 解构赋值成  {msg,user}-->
        <template #myslot="{msg,user}"> <!--<template #myslot="scope">-->
          <p>Left插槽调用</p>
          <p>{{msg}}</p>
          <p>{{user.name}}</p>
        </template>
      </left>
    </div>
  </div>
</template>

自定义指令

私有自定义指令

在每个vue组件中,可以在 directives 节点下声明 私有自定义指令。

  • bind(el,binding)       只在绑定第一次才触发
  • update(el,binding)   在DOM 更新时触发
  • color(el,binding)     自定义指令 简写
  •  <!--<h5 v-color>自定义指令</h5>-->
    <h5 v-color="'red'">自定义指令</h5>
    
    directives:{
        /*color:{
          //为绑定到 html 元素设置红色文字
          bind(el){   
            //形参中的 el 是绑定了次指令的,原生的DOM 对象
            el.style.color='red';
          },
           //bind(el)  固定写法,只在绑定第一次才触发
          bind(el,binding){  
            el.style.color=binding.value;
          },
          //bind(el)  固定写法,在DOM 更新时触发
          update(el,binding){   
            el.style.color=binding.value;
          }
        }*/
        //自定义指令 简写
        color(el,binding){
          el.style.color=binding.value;
        }
    }

    全局自定义指令

    main.js 通过 Vue.directive('color',function(el,binding)  方式声明。

  • ######## main.js   ##########
    
    import Vue from 'vue'
    import App from './App.vue'
    
    Vue.config.productionTip = false
    
    //全局自定义指令
    Vue.directive('color',function(el,binding){
      el.style.color=binding.value;
    })
    
    
    new Vue({
      render: h => h(App),
    }).$mount('#app')
    

    axios 优化

         全局axios

        ①定义全局axios,避免组件多次创建

        ②定义全局根路径,避免重复书写更路径

        缺点:API接口无法在组件间复用

######## main.js  ##########

import Vue from 'vue'
import App from './App.vue'
import axios from 'axios'

Vue.config.productionTip = false

// 全局配置 axios 的请求根路径
axios.defaults.baseURL = 'http://www.myAxios.top:3006'

// 把axios挂载到 vue.prototype 上,供每个.vue组件实例直接调用
Vue.prototype.$http = axios

new Vue({
  render: h => h(App)
}).$mount('#app')
######## .vue  ##########

methods: {
    async postInffo () {
      const { data: res } = await this.$http.post('/api/post', { name: zs, age: 22 })
      console.log(res)
    }
  }

③ 解决全局axios 无法重用问题

封装 request.js 模块

// request.js //
import axios from 'axios'

const request = axios.create({
  // 指定请求的根路径
  baseURL: 'https://www.escook.cn'
})

export default request

④ API接口封装

// 文章相关接口 返回Promise实例对象  提供代码复用性
import request from '@/utils/request.js'

// 按需导出
export const getArticleList = function (page, limit) {
  return request.get('/articles', {
    // 请求参数
    params: { _page: page, _limit: limit }
  })
}
// 按需导入API接口
import { getArticleList } from '@/api/articleAPI.js'

export default {
  methods: {
    // 封装获取文章数据
    async initArticleList (refreshFlag) {
      const { data: res } = await getArticleList(this.page, this.limit)
      console.log(res)
    },
  },
  created () {
    this.initArticleList()
  },
}

axios 拦截器

概念:每次发起 ajax 请求响应 时候自动被触发。

作用:Token 身份认证,Loading效果

// main.js //
import axios from 'axios'

//Loading 效果
import {Loading} from 'element-ui'
let loadingInstance = null

//请求拦截器
axios.interceptors.request.use(config=>{
  //获取Token
  config.headers.Authorzation = 'Barer xxxx'
  //Loading 开启
   loadingInstance = Loading.servive({fullscreen:true})

  // config 必须返回
  return config;
})

//响应拦截器
axios.interceptors.response.use(function(response){
    //成功
    //Loading 关闭
    loadingInstance.close();
    return response;
},function(error){
    //失败
    loadingInstance.close();
    return Promise.reject(error);
})

proxy 跨域代理

 

vue-cli 项目通过代理解决接口跨域问题

① 把 axios 的请求根路径 设置为 vue 项目的运行地址(接口请求不再跨域)

② vue项目 发现请求接口不存在,把请求转交给proxy代理

③ 代理把请求根路径替换为 devServer.proxy 属性的值,发起真正的数据请求

④ 代理把请求到的数据,转交到axios

// request.js //
import axios from 'axios'

const request = axios.create({
  // 指定请求的根路径(项目运行地址)
  //baseURL: 'https://www.escook.cn'
  baseURL: 'https://localhost:8080'
})

export default request
/vue.config.js

module.exports = {
   devServer:{
        //当项目在调试阶段
        //会将任何未知请求(未匹配到静态文件的请求)代理到 'https://www.escook.cn'
        proxy: 'https://www.escook.cn'
    }
}

注意:

① devServer.proxy 提供的代理功能,仅在开发阶段生效

② 项目上线发布时,仍然需要API接口服务器开启CORS跨域资源共享

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BC菜鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值