项目重温 _ 查漏补缺

目录

动态路由传参

query 方式传参

params 方式传参

组件间传值

Vue 中如何动态的绑定图片

Vue 动态绑定背景图片

Vue 中 v-on 如何绑定多个事件 ?

将块元素旋转 90 °

vue-router 如何判断是从哪个路径跳转过来的 ?

处理后端返回的列表数据

导出数据结果

模板下载


路由跳转之编程式导航

编程式导航 就是 通过 js 来实现 路由跳转

使用了 vue-router 中提供的一个 属性 对象  router

push / replace  可以传入的参数    { string  ||  object }

捕获 重复跳转的异常处理   this.$router.push( url ).catch( ( ) => { } )

 


动态路由传参

路由配置:

{
  path: '/update/:uid/:name',    // uid 参数、name 参数
  name: 'Update',
  component: () => import('@/views/update.vue'),
  children : []
};

路由跳转:

this.$router.push('/update/123/zhangsan');    
// 如果没有添加对应参数,页面出现 404,不会到达对应页面

在对应页面中拿到路由参数进行网络请求: 

mounted(){
    let id = this.$route.params.uid;
    let name = this.$route.params.name;
 
    // 进行网络请求...
}

query 方式传参

路由配置:

{
  path: '/update',    
  name: 'Update',
  component: () => import('@/views/update.vue'),
  children : []
};

路由跳转(两种方式):

this.$router.push({
    path : '/update',        // 方式1:通过 path 跳转
    query : {
        uid : 123,
        name : 'zhangsan'
    }
})
 
 
this.$router.push({
    name : 'Update',        // 方式2:通过 name 跳转
    query : {
        uid : 456,
        name : 'lisi'
    }
})

在对应页面中拿到路由参数进行网络请求:

mounted(){
    let id = this.$route.query.uid;
    let name = this.$route.query.name;
 
    // 进行网络请求...
}

params 方式传参

路由配置:

{
  path: '/update',    
  name: 'Update',
  component: () => import('@/views/update.vue'),
  children : []
};

路由跳转(只有一种方式):

this.$router.push({
    name : 'Update',        // 只能通过 name 跳转
    params : {
        uid : 1313,
        name : 'love'
    }
})

在对应页面中拿到路由参数进行网络请求:

mounted(){
    let id = this.$route.params.uid;
    let name = this.$route.params.name;
 
    // 进行网络请求...
}

Vue 路由传参 ----- params 和 query 的区别
背景:项目中需要跨页面传值,如试题 id , 遇到了刷新后,传的值消失,所以研究了以下两者的区别

1. params 只能用 name 来引入路由 ,query 用 path / name 来引入

2. params 类似于 post ,query 更加类似于我们 ajax 中 get 传参,说的再简单一点,前者在浏览器 地址栏中不显示参数,后者显示,所以 params 传值相对 安全 一些。

3. 取值用法类似分别是 this.$route.params.name 和 this.$route.query.name。

4. params 传值一刷新就没了,query 传值刷新还存在


src / router / routes / edit.js

export default {
  path: '/edit',
  name: 'Edit',
  component: () => import(/* webpackChunkName: "edit" */ '@/views/edit')
}

src / views / list / component / allMattersTab.vue  ( 子 组件

// 项目中所用
// elementUI 中的 MessageBox 弹框
// . . . 省略 . . .
.then(({ value }) => {
  this.$message({
    type: 'success',
    message: `${value}创建成功`
  })
  // 动态路由传参
  // this.$router.push(`/edit/${value}`)
  
  // 跳转页面时 ( 通过 query 属性传值 )
  this.$router.push({
    path: 'edit',
    query: {
      title: value
    }
  })

  // 跳转页面时 ( 通过 params 方式隐士传参 )
  /* this.$router.push({
    name: 'Edit',
    params: {
      title: value
    }
  }) */
})
.catch(() => {
  this.$message({
    type: 'info',
    message: '取消新建'
  })
})

 src / views / edit / index.vue

<template>
  <div>
    <el-input
      class="input_title"
      v-model="edit_title"
      placeholder="请输入问卷标题"
  </div>
</template>

<script>
export default {
  data() {
    return {
      edit_title: '问卷标题',   // 绑定输入编辑框初始内容
    }
  },
  created() {
    this.edit_title = this.$route.query.title
    // this.edit_title = this.$route.params.title
  }
}
</script>

组件间传值

事件总线 

非父子组件 或 更多层级间组件间 传值 ,在 Vue 中通过单独的 事件中心 来管理组件间的传值。

  • 建立统一的事件中心

const bus = new Vue( ) 

  • 传递数据方,通过一个事件触发  bus.$emit( 方法名,传递的数据 )
  • 接收数据方,在生命周期函数中,通过  bus.$on( 方法名,[params] )来监听
  • 销毁事件,在接受数据方,通过  bus.$off( 方法名 )  销毁之后无法监听数据


 Vue 兄弟组件之间的传值,使得兄弟组件之间可以联动,相互操作

方法:eventBus 事件总线 传值

思路:在 Vue 的 原型 ( prototype ) 上创建一个属性 eventBus ,该属性的值为 new Vue(),即 eventBus 也是一个 Vue 实例

第一步:在 src / main.js 中创建 eventBus 事件总线

// 创建 eventBus 事件总线
Vue.prototype.eventBus = new Vue()

第二步:在 子组件 A 中 ,通过 eventBus 事件总线 抛出 信息 和 值。this.eventBus 就是 Vue 实例 ,$emit 也是上面的方法

src / views / edit / components / parameter.vue  ( 关于 参数 的 子组件 )

<template>
  <!-- 右侧参数配置项 -->
  <div>
    <!-- 是否为必答项 -->
    <el-form-item
      v-if="Object.keys(data).indexOf('validate') >= 0"
      label="必答"
    >
      <div v-for="(item, idx) in data.validate" :key="idx">
        <el-switch
          v-model="item.required"
          active-color="#13ce66"
          inactive-color="#ff4949"
          @change="isRequired(data)"
        />
      </div>
    </el-form-item>
  </div>
</template>

<script>
export default {
  data() {
    return {
      
    }
  },
  methods: {
    // 控制是否为必答项
    isRequired(boo) {
      // 利用 eventBus 事件总线传值
      if(boo.type == 'radio') {
        this.eventBus.$emit('radio', boo.validate[0].required)
      } else if (boo.type == 'checkbox') {
        this.eventBus.$emit('checkbox', boo.validate[0].required)
      } else if (boo.type == 'input') {
        this.eventBus.$emit('input', boo.validate[0].required)
      } else {
        console.log('假 boo' + boo)
      }
    }
  }
}
</script>

第三步:在子组件 B 中,在 created 或 mounted 等生命周期函数上,监听那个事件和获取那个值。

src / views / edit / components / container.vue  ( 关于 容器 的 子组件 )


Vue 中如何动态的绑定图片

在项目中遇到需要动态的改变图片路径,图片路径并非是从后台获取过来的数据。

因此在 data 中必须用 require 加载,否则会当成字符串来处理。

<img :src="item.src" alt="" />

{
  ...
  src: require("../../assets/01单选题.png"),
  ...
}


Vue 动态绑定背景图片

分为两种,第一种是动态绑定后台传来的图片,第二种是我们自己文件夹的图片
1. 绑定后台传来的图片

<div class="img" :style="{backgroundImage: 'url(' + srcImgUrl + ')', backgroundSize:'100% 100%', backgroundRepeat: 'no-repeat'}">

2. 文件夹的图片 ( 注意,这种方式一定要用 require 的方式 )

<div class="assets" :style="{ 'background': 'url(' + require('../../assets/001.png/') + ') no-repeat center center', 'background-size': '100% 100%'}">

3. 也可以在 data 中存储先,在引用

<div :style="{backgroundImage: 'url(' + src + ')', backgroundSize:'contain'}">
   data(){
            return{
              // 这种方式也要使用 require
                src: require('../../assets/images/other/002.jog')
            }
        }

4. 属性:
4.1
background-repeat  属性: 背景图像 - 设置定位与不平铺
background-repeat: no-repeat;
4.2
background-position: 设置背景图像的起始位置。
4.3
background-origin:background-Origin 属性指定 background-position 属性应该是相对位置。
4.4
background-size: background-size 属性指定背景图片大小
语法:background-size: length|percentage|cover|contain;


Vue 中 v-on 如何绑定多个事件 ?

<el-button
  size="mini"
  type="primary"
  @click="addElements(), batchAddVisible = false"
>
  保存
</el-button>

将块元素旋转 90 °

.rotate90{
     height: 50px;
     width: 300px;
     border:2px solid red;

     -webkit-transform: rotate(90deg);
     -moz-transform: rotate(90deg);
     -o-transform: rotate(90deg);
     -ms-transform: rotate(90deg);
     transform: rotate(90deg);
 }

vue-router 如何判断是从哪个路径跳转过来的 ?

日常项目中经常会出现这种效果  点击添加 和 编辑 跳转 至 编辑页 或 添加页后,通过

保存 el-tab-pane 这个组件还是要指向原来的地方

在这里插入图片描述

方法一、通过 beforeRouteEnter 实现

但是要注意哦  beforeRouteEnter 不能访问 this 
解决方法如下

在这里插入图片描述

  beforeRouteEnter(to, from, next) {
    next(vm => {
      if (from.path == "/channel/index/addAdvert") vm.activeName = "fourth";
    });
  },

方法二:通过 watch 监听实现

watch : {
    '$route' (to, from) {
        // from 对象中要 router 来源信息.
        // do your want
    }
}

处理后端返回的列表数据

因为是一个 Tab 切换型列表 , 而且还可以通过点击查看更多展示下一页数据

所以此种情况需要对请求回来的数据进行两种分别的请求数据处理

( 1 )首先就是如果你点击列表下面的 “ 加载更多 ” , 就会接着加载出下一页的数据

这种情况最好就是使用 concat 数组拼接的方式来处理请求的数据

    // 获取列表数据的请求
    async getList() {
      let data = {
        userId: this.userId, // 用户 Id
        updateTime: this.pageData.currentPage, // 页数
        fetchNum: this.pageData.pageSize, // 一页显示的条数
        iscomplete: this.iscomplete, // iscomplete = 0 未完成 iscomplete = 1 已完成
      };
      let res = (await getMattersListApi(data)) || {};
      const { code, result } = res;
      if (code === "0") {
        this.pageData.total = res.result.totalCount; // 总条数
        this.pageData.totalPages = res.result.totalPage; // 总页数
        if (result.listItems && result.listItems.length > 0) {
          if (this.is_concat) {
            // 如果为查看更多操作则利用 concat 处理后端返回的列表数据
            this.tableList = this.tableList.concat(result.listItems);
          } else {
            // 如果为 tab 切换操作则利用赋值处理后端返回的列表数据
            this.tableList = result.listItems;
          }
        }
      }
    },

( 2 )其次就是如果你是进行的 Tab 切换列表的操作的话 , 那就可以将新请求来的数据

进行重新赋值覆盖


导出数据结果

// 导出数据结果
    exportItem: debounce(function (item) {
      this.setFormData.surveyId = item.surveyId;
      axios
        .post(
          "/api/exportAnswer" +
            `?surveyId=${this.setFormData.surveyId}` +
            `?userId=${this.setFormData.userId}`,
          {},
          {
            responseType: "blob",
          }
        )
        .then((response) => {
          let str = response.headers["content-disposition"]
            .split(";")[1]
            .split("=")[1];
          let fileName = decodeURI(str);
          if (window.navigator.msSaveOrOpenBlob) {
            // 兼容 IE 10
            navigator.msSaveBlob(new Blob([response.data]), fileName);
          } else {
            let url = window.URL.createObjectURL(new Blob([response.data]));
            let link = document.createElement("a");
            link.style.display = "none";
            link.href = url;
            link.setAttribute("download", `${fileName}`);
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
          }
          this.importFileLoading = false;
        })
        .catch((err) => {
          this.$message.success("导出失败!");
        });
    }, 500),

模板下载

// 模板下载
    handleImportFile: debounce(function () {
      this.importFileLoading = true;
      axios
        .post("/api/downloadUserGroup", {
          responseType: "blob",
        })
        .then((response) => {
          let str = response.headers["content-disposition"]
            .split(";")[1]
            .split("=")[1];
          let fileName = decodeURI(str);
          if (window.navigator.msSaveOrOpenBlob) {
            // 兼容 IE 10
            navigator.msSaveBlob(new Blob([response.data]), fileName);
          } else {
            let url = window.URL.createObjectURL(new Blob([response.data]));
            let link = document.createElement("a");
            link.style.display = "none";
            link.href = url;
            link.setAttribute("download", `${fileName}`);
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
          }
          this.importFileLoading = false;
        })
        .catch((err) => {
          this.$message.success("下载失败!");
        });
    }, 1000),

如何查看 .vsd 结尾格式的流程图文件

下载使用 Visio 软件程序打开。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值