目录
路由跳转之编程式导航
编程式导航 就是 通过 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 软件程序打开。