vue路由传参+案例(使用mock模拟后端数据)

路由传参

跳转路由时,可以给路由对应的组件内传参

声明式导航

/path?参数名=值
/path/值 —需要路由对象提前配置 path: ‘/path/:参数名’

对应的页面组件接收传递过来的值

$route.query.参数名
$route.params.参数名

router/index.js

import Vue from 'vue'
// 1. 导入路由
import VueRouter from "vue-router"// 引入组件
// import Home from '../views/Home'
// import Login from '../views/Login'
// import Register from '../views/Register'// 2. 使用路由插件
// 在vue中,使用vue插件,需要调用Vue.use()
Vue.use(VueRouter)// 3. 创建路由规则
const routes = [{path: '/',redirect: '/list'},{path: '/list',component: () => import('../views/List')},{path: '/part',component: () => import('../views/Part')},{path: '/detail/:name',component: () => import('../views/Detail')},{path: '*',component: () => import('../views/NotFound')},
]// 4. 创建路由对象,传入规则
const router = new VueRouter({// routes: routes,routes,mode: 'history',
})// 导出路由对象
export default router

App.vue

<template><div><router-view></router-view></div>
</template><script>
export default {}
</script><style scoped></style>

List.vue

<template><div><router-link to="/part?name=张三">好友---张三</router-link><router-link to="/detail/王五">好友---王五</router-link>// to一定要加: 进行属性绑定,动态属性传值<router-link :to="'/part?name='+ n1">朋友---{{ n1 }}</router-link><router-link :to="'/detail/'+ n2">朋友---{{ n2 }}</router-link></div>
</template><script>
export default {data() {return {n1: '小米',n2: '小鹏',}},
}
</script><style scoped></style>

Part.vue

<template><div><p>关注的人</p>// 方式 1{{ $route.query.name }}<hr>{{ name }}</div>
</template><script>
export default {data() {return {name: '',}},created() {// 创建完成 第一次操作data中数据执行一次this.name = this.$route.query.nameconsole.log(this.name);}
}
</script><style scoped></style>

Detail.vue

<template><div>detail// 方式 2<p>{{ $route.params.name }}</p><hr>{{ name }}</div>
</template><script>
export default {data() {return {name: '',}},created() {this.name = this.$route.params.name}
}
</script><style scoped></style>

在这里插入图片描述

编程式导航

语法:
query/params 任选一个

this.$router.push({path: "路由路径",name: "路由名",query: {"参数名": "值",},params: {"参数名": "值",},
})

List.vue

<template><div><router-link to="/part?name=张三">好友---张三</router-link><router-link to="/detail/王五">好友---王五</router-link><router-link :to="'/part?name=' + n1">朋友---{{ n1 }}</router-link><router-link :to="'/detail/' + n2">朋友---{{ n2 }}</router-link><hr><span @click="fn1">朋友---{{ n1 }}</span><span @click="fn2">朋友---{{ n2 }}</span></div>
</template><script>
export default {data() {return {n1: '小米',n2: '小鹏',}},methods: {fn1() {this.$router.push({path: '/part',query: {// name: '小米',name: this.n1,}})},fn2() {// this.$router.push({//     // 不能用path,path会自动忽略params//     name: 'detail',//     params: {//         name: this.n2,//     }// })this.$router.push('/detail/' + this.n2) },},
}
</script><style scoped></style>

路由守卫

https://router.vuejs.org/zh/guide/advanced/navigation-guards.html

vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。这里有很多方式植入路由导航中:全局的,单个路由独享的,或者组件级的。

全局前置守卫

需求:在跳转路由前,判断用户是否登录,登录了才能跳转到"part"页面,未登录弹窗提示
在路由对象上使用固定的方法 beforeEach()


// 1. 在路由对象上使用固定的方法 beforeEach(一定要在创建路由之后使用该方法)
/*路由跳转"之前"先执行这里,决定是否跳转
router.beforeEach((to, from, next)=>{
to 要跳转的路由(路由对象信息) 目标 
from 从哪里跳转的路由(路由对象信息) 来源
next 函数体,next()  才会让路由正常的跳转切换,next(false)在原地停留  next("路由路径") 强制修改到另一个路由路径上
不调用next 页面留在原地
})*/
// 在跳转路由前,判断用户是否登录,登录了才能跳转到"part"页面,未登录弹窗提示
const isLogin = false  // 登录状态(未登录)
router.beforeEach((to, from, next) => {// console.log(to)// console.log(from)if (to.path === '/part' && isLogin === false) {alert('请先登录')next(false)} else {next()  // 正常放行}
})

Vant组件库

https://vant-contrib.gitee.io/vant/v2/#/zh-CN/

Vant轻量、可靠的移动端 Vue 组件库

安装

在当前项目根目录中打开终端输入以下命令

npm i vant@latest-v2 -S

导入所有的组件

main.js中导入

// 导入所有的组件
import Vant from 'vant'
import 'vant/lib/index.css'Vue.use(Vant)

使用组件

<van-button type="primary">主要按钮</van-button>
<van-button type="info">信息按钮</van-button>
<van-button type="default">默认按钮</van-button>
<van-button type="warning">警告按钮</van-button>
<van-button type="danger">危险按钮</van-button>

手动按需引入

只引入使用的组件

在不使用插件的情况下,可以手动引入需要的组件 —每一个组件都要引入

import Button from 'vant/lib/button';
import 'vant/lib/button/style';

注册
List.vue

<template><div><van-button type="primary">主要按钮</van-button><van-button type="info">信息按钮</van-button><van-button type="default">默认按钮</van-button><van-button type="warning">警告按钮</van-button><van-button type="danger">危险按钮</van-button></div>
</template><script>
// 组件要引入到要显示组件的那个vue中
import Button from "vant/lib/button";
import "vant/lib/button/style";
export default {components: {// VanButton: Button,[Button.name]: Button,},
};
</script>

自动按需引入

babel-plugin-import 是一款 babel 插件,它会在编译过程中将 import 的写法自动转换为按需引入的方式。

安装插件

npm i babel-plugin-import -D

在babel.config.js中配置完,要重新启动项目

module.exports = {presets: ['@vue/cli-plugin-babel/preset'],plugins: [['import', {libraryName: 'vant',libraryDirectory: 'es',style: true}, 'vant']]
};

main.js

import { Button, Icon } from 'vant'
Vue.use(Button)
Vue.use(Icon)

组件中使用

<template><div><van-button type="primary">主要按钮</van-button><van-button type="info">信息按钮</van-button><van-button type="default">默认按钮</van-button><van-button type="warning">警告按钮</van-button><van-button type="danger">危险按钮</van-button><van-icon name="chat-o" /><van-icon name="https://b.yzcdn.cn/vant/icon-demo-1126.png" /></div>
</template><script>
export default {};
</script><style scoped>
</style>

案例

路由配置

二级路由
组件

  • Layout.vue —总的框架
  • List.vue —商品列表
  • Search.vue —商品搜索
  • My.vue —我的信息

配置路由

import Vue from "vue";import VueRouter from 'vue-router'Vue.use(VueRouter)const routes = [{path: '/',redirect: '/list',component: () => import('../views/Layout'),children: [{path: '/list',component: () => import('../views/List'),},{path: '/my',component: () => import('../views/My'),},{path: '/search',component: () => import('../views/Search'),},]},{path: '*',component: () => import('../views/NotFound')}
]const router = new VueRouter({routes,mode: 'history'
})export default router

底部封装

  • 创建MyTabBar.vue组件
<template><div><van-tabbar v-model="active"><van-tabbar-item icon="home-o" to="/list">商品列表</van-tabbar-item><van-tabbar-item icon="search" to="/search">商品搜索</van-tabbar-item><van-tabbar-item icon="friends-o" to="/my">我的信息</van-tabbar-item></van-tabbar></div>
</template><script>
export default {data() {return {active: 0,};},
};
</script><style scoped>
</style>

顶部封装

  • 创建MyHead.vue组件
<template><div><div class="head">TabBar案例</div></div>
</template><script>
export default {};
</script><style scoped>
.head {height: 50px;line-height: 50px;color: #fff;background-color: blue;text-align: center;
}
</style>

MyTabBar.vue组件和MyHead.vue组件要注册并引入到 Layout.vue 组件中

商品列表

  • 封装MyTable.vue === 标签和样式
  • axios在MyGoodList.vue请求数据回来,把MyTable.vue引入到MyGoodList.vue中,再把MyGoodList.vue引入到List.vue中
  • 请求地址https://www.escook.cn/api/goods
  • 传入MyTable.vue中循环数据显示

List.vue

<template><div><my-good-list></my-good-list></div>
</template><script>
import MyGoodList from '@/components/MyGoodList.vue'
export default {components: { MyGoodList, }
}
</script><style scoped></style>

MyTable.vue

<template><div><table><thead><tr><th>#</th><th>名称</th><th>价格</th><th>标签</th><th>操作</th></tr></thead><tbody>// 循环遍历渲染数据<tr v-for="(item, index) in list"><td>{{ item.id }}</td><td>{{ item.goods_name }}</td><td>{{ item.goods_price }}</td><td>{{ item.tags }}</td><td><van-button type="primary">删除</van-button></td></tr></tbody></table></div>
</template><script>
export default {// 子组件props接收props: {list: Array,},
};
</script><style scoped>
table {width: 100%;border: 1px solid #eee;border-collapse: collapse;margin: 20px auto;
}
td,
th {height: 30px;border: 1px solid #eee;
}
</style>

axios在MyGoodList.vue请求数据回来

  • 下载axios
yarn add axios

MyGoodList.vue

<template><div>// 父传子 父自定义属性<my-table :list="list"></my-table></div>
</template><script>
import axios from "axios";
import MyTable from "./MyTable.vue";
export default {data() {return {list: [],};},components: {MyTable,},create() {// axios({//   url: "https://www.escook.cn/api/goods",// }).then((res) => {//   let {//     data: { data: result },//   } = res;//   console.log(result);// });this.getData();},methods: {async getData() {let {data: { data: result },} = await axios({ url: "https://www.escook.cn/api/goods" });console.log(result);this.list = result;},},
};
</script><style scoped>
</style>

商品表格—插槽

使用插槽技术,和作用于插槽技术,给MyTable.vue组件,自定义标题,自定义列标题,自定义表格内容

需求:允许用户自定义表头和表格单元格内容

  • 在MyTable.vue中准备slot
  • 使用MyTable组件时传入具体标签

步骤:

  • 提高组件==复用性和灵活性 ==,把表格列标题thead部分预留slot,设置 name 属性
  • 使用MyTable.vue时,传入列标题标签
  • 表格内容 td 部分也可以让组件使用者自定义,也给tbody预留 slot 和 name属性
  • 使用插槽需要用到插槽内的item对象上的数据,作用域插槽

MyTable.vue

<template><div><table><thead><tr>// <th>#</th>// <th>名称</th>// <th>价格</th>// <th>标签</th>// <th>操作</th><slot name="header"></slot></tr></thead><tbody><!-- 循环遍历渲染数据 --><tr v-for="(item, index) in list">// <td>{{ item.id }}</td>// <td>{{ item.goods_name }}</td>// <td>{{ item.goods_price }}</td>// <td>{{ item.tags }}</td>// <td>//   <van-button type="primary">删除</van-button>// </td><slot name="body" :row="item" :index="index"></slot></tr></tbody></table></div>
</template><script>
export default {// 子组件props接收props: {list: Array,},
};
</script><style scoped>
table {width: 100%;border: 1px solid #eee;border-collapse: collapse;margin: 20px auto;
}
td,
th {height: 30px;border: 1px solid #eee;
}
</style>

MyGoodList.vue

<template><div><!-- 父传子 父自定义属性 --><my-table :list="list"><template #header><th>#</th><th>名称</th><th>价格</th><th>标签</th><th>操作</th></template><template #body="{ row, index }"><td>{{ row.id }}</td><td>{{ row.goods_name }}</td><td>{{ row.goods_price }}</td><td>{{ row.tags }}</td><td><van-button type="primary">删除</van-button></td></template></my-table></div>
</template>

mock模拟后端数据

由于上面使用的接口挂了,所以改用mock模拟后端数据,并对axios进行了简单的二次封装

axios二次封装

src/utils/request.js

// 二次封装axiosimport axios from 'axios'const http = axios.create({// 通用请求的地址前缀baseURL: '/api',timeout: 10000, // 超时时间
})// 添加请求拦截器
http.interceptors.request.use(function (config) {// 在发送请求之前做些什么return config;
}, function (error) {// 对请求错误做些什么return Promise.reject(error);
});// 添加响应拦截器
http.interceptors.response.use(function (response) {// 2xx 范围内的状态码都会触发该函数。// 对响应数据做点什么return response;
}, function (error) {// 超出 2xx 范围的状态码都会触发该函数。// 对响应错误做点什么return Promise.reject(error);
});export default http // 对外暴露 http 实例

封装getData方法对外暴露,使用http.get()请求列表页数据

arc/api/index.js

import http from '../utils/request'// 请求列表页数据
export const getData = () => {// 返回一个promise对象return http.get('/list/getData')
}

MyGoodList.vue中调用getData方法请求数据

MyGoodList.vue

import { getData } from '../api'
export default {created() {getData().then(({ data: { data: { data: list } } }) => {  // 解构得到请求的数据console.log(list)this.list = list})},
}

定义mock请求拦截

api/mock.js

import Mock from 'mockjs'
import listApi from './mockServeData/list'// 定义mock请求拦截
Mock.mock('/api/list/getData', listApi.getStatisticalData)// // 定义mock请求拦截
// Mock.mock('/api/home/getData', function () {
//     // 拦截到请求后的处理逻辑
//     console.log('拦截到了')
//     return []
// })

main.js中引入mock

main.js中配置

import './api/mock'

mock模拟列表数据

api/mockServeData/list.js

mock模拟列表数据

// 列表数据
// mock数据模拟
import Mock from 'mockjs'
export default {getStatisticalData: () => {return {code: 20000,data: {data: [{id: 1001,goods_name: '小米',goods_price: 2999,tags: ['性价比', '高性能'],inputValue: '',inputVisible: false,},{id: 1002,goods_name: '魅族',goods_price: 2999,tags: ['性价比', '高性能'],inputValue: '',inputVisible: false,},{id: 1003,goods_name: '华为',goods_price: 2999,tags: ['高性能'],inputValue: '',inputVisible: false,},{id: 1004,goods_name: '荣耀',goods_price: 2999,tags: ['高性能'],inputValue: '',inputVisible: false,},{id: 1005,goods_name: 'oppo',goods_price: 2999,tags: ['高性能'],inputValue: '',inputVisible: false,},{id: 1006,goods_name: 'vivo',goods_price: 2999,tags: ['高性能'],inputValue: '',inputVisible: false,}],}}}
}

商品表格tags

main.js中按需引入Tag组件

<td><van-tag v-for="(item, ind) in row.tags" :key="ind" type="primary">{{ item }}</van-tag>
</td>

商品表格—删除功能

点击删除按钮删除对应行的数据
main.js中按需引入Button组件

分析:

  • 删除按钮绑定点击事件
  • 作用域插槽绑定id
  • 传给删除方法,删除MyGoodList.vue里面数组的数据

MyGoodList.vue—注册点击事件

 <van-button type="primary" @click="removeBtn(row.id)">删除</van-button>

MyGoodList.vue 根据id删除数据

    methods: {removeBtn(id) {// 1. 根据id查找下标let index = this.list.findIndex((obj) => obj.id === id)// 2. 实现删除this.list.splice(index, 1)}},

商品表格—添加tab

需求:店家tab按钮,出现输入框自动获取焦点,失去焦点关闭输入框,会出新增tag,esc清空内容

main.js中按需引入Button组件、Field组件

  • 点击tab,按钮消失,输入框出现
  • 输入框自动获焦
  • 失去焦点,输入框消失,按钮出现
  • 监测输入框回车,若无数据进行拦截,有数据则添加
  • input输入框 按esc清空数据

点击tab,按钮消失,输入框出现

<td><div class="top"><van-field v-model="value" v-if="row.inputVisible" placeholder="请输入新标签" /><van-button type="info" size="small" v-else @click="row.inputVisible = true">Tag+</van-button></div><van-tag type="primary" v-for="(item, ind) in row.tags" :key="ind"> {{ item }} </van-tag>
</td>

输入框自动获焦

Vant组件使用autofocus自动获焦

<van-field 
v-model="value" 
v-if="row.inputVisible" 
placeholder="请输入新标签" 
:autofocus="true" />

失去焦点,输入框消失,按钮出现

blur事件 输入框失去焦点时触发

<van-field 
v-model="value" 
v-if="row.inputVisible" 
placeholder="请输入新标签" 
:autofocus="true" 
@blur="row.inputVisible = false"/>

监测输入框回车,若无数据进行拦截,有数据则添加

输入框要双向绑定mock数据中的inputValue
利用该数据中的inputValue添加标签内容到row.tags

  1. 监听input的回车事件
<van-field 
v-model="row.inputValue" 
v-if="row.inputVisible" 
placeholder="请输入新标签" 
:autofocus="true"
@blur="row.inputVisible = false" 
@keyup.enter="enterFn(row)" />
  1. 事件处理函数
// 在methods方法中定义enterFn方法
enterFn(row) {// console.log(row);// 非空判断if (row.inputValue.trim().length === 0) {return alert('添加标签不能为空!')}// 添加row.tags.push(row.inputValue)row.inputValue = ''
}

input输入框 按esc清空数据

  1. 监听input的esc事件
<van-field 
v-model="row.inputValue" 
v-if="row.inputVisible" 
placeholder="请输入新标签" 
:autofocus="true"
@blur="row.inputVisible = false" 
@keyup.enter="enterFn(row)" 
@keyup.esc="clearFn(row)"/>
  1. 事件处理函数
clearFn(row) {row.inputValue = ''
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/4480.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

生物数据下载

目录 1. 获取数据下载的地址 2. 生物数据常用的下载站点 1、核酸数据库 2、非编码RNA数据库 &#xff08;1&#xff09;.非编码小RNA数据库 &#xff08;2&#xff09;.长非编码RNA数据库&#xff1a; &#xff08;3&#xff09;.非编码RNA家族数据库 &#xff08;4&a…

【ISO26262】汽车功能安全第4部分:系统层面

第4部分:产品开发:系统层面 GB/T34590的本部分规定了车辆在系统层面产品开发的要求,包括: ———启动系统层面产品开发; ———技术安全要求的定义; ———技术安全概念; ———系统设计; ———相关项集成和测试; ———安全确认; ———功能安全评估;及 ———生产发布。

工地临边防护缺失识别检测算法 opencv

工地临边防护缺失识别检测系统通过opencvpython网络模型技术&#xff0c;工地临边防护缺失识别检测算法检测到没有按照要求放置临边防护设备时&#xff0c;将自动发出警报提示现场管理人员及时采取措施。Python是一门解释性脚本语言&#xff0c;是在运行的时候将程序翻译成机器…

浅尝Transformer和LLM

文章目录 TransformerTransformer的衍生BERTPre-trainingBERT与其他方法的关系怎么用BERT做生成式任务&#xff1f; GPTPre-trainingFine-Tuning Transformer工具开源库特点 LLM系列推理服务 大语言模型势不可挡啊。 哲学上来说&#xff0c;语言就是我们的一切&#xff0c;语言…

自然语言处理从入门到应用——预训练模型总览:预训练模型的拓展

分类目录&#xff1a;《自然语言处理从入门到应用》总目录 从大量无标注数据中进行预训练使许多自然语言处理任务获得显著的性能提升。总的来看&#xff0c;预训练模型的优势包括&#xff1a; 在庞大的无标注数据上进行预训练可以获取更通用的语言表示&#xff0c;并有利于下游…

短视频seo源码部署打包分享---开源

功能概要&#xff1a; 1. 按关键词搜索账号排名 2. 按关键词布局查询视频排名 3. 按天计费功能开发 4. 达标天数及关键词数量统计 开发概要&#xff1a; 区别于其他开发者&#xff0c;同类产品多用第三方&#xff0c;如&#xff1a;站长之家&#xff0c;本系统代码开发使…

手机便签软件推荐 有没有什么好用的手机便签软件app

在外出需要记事的时候&#xff0c;很多人会使用手机上的便签工具来完成。那手机便签软件推荐哪个比较好&#xff0c;有没有好用的手机便签软件app推荐呢&#xff1f;下面小编就为大家推荐一些用起来体验很不错的手机便签app软件。 一、敬业签 敬业签具备多种便签记事和提醒方式…

Vulnhub: EvilBox:One靶机

kali&#xff1a;192.168.111.111 靶机&#xff1a;192.168.111.130 信息收集 端口扫描 nmap -A -sC -v -sV -T5 -p- --scripthttp-enum 192.168.111.130 secret目录爆破 feroxbuster -k -d 1 --url http://192.168.111.130/secret/ -w /opt/zidian/SecLists-2022.2/Disco…

element封装 table表格 ,插槽的使用,修改el-table-column的值

举例 vue2这种不封装的 直接写的很罗嗦麻烦 下面圈起来的可以封装一个对象 进行循环 弊端: 循环后 无法进行获取更改某一列的值 比如data日期我需要转换年月日 不循环我直接在这个el-table-column的这一列进行写&#xff08;如下&#xff09; <el-table-column label&quo…

Vue Router replace 编程式导航 缓存路由组件

6.9.路由跳转的 replace 方法 作用&#xff1a;控制路由跳转时操作浏览器历史记录的模式浏览器的历史记录有两种写入方式&#xff1a;push和replace push是追加历史记录replace是替换当前记录&#xff0c;路由跳转时候默认为push方式 开启replace模式 <router-link :replac…

创业书籍推荐,这些书经商必读

对于许多想要创业的人来说&#xff0c;成功的关键在于掌握正确的知识和技能。虽然创业的实际经验是无可替代的&#xff0c;但是通过阅读经验丰富的人士写的书籍&#xff0c;可以提前了解创业、经商过程中可能遇到的挑战&#xff0c;并为成功奠定基础。在这篇文章中&#xff0c;…

CPU acceleration status: KVM requires a CPU that supports vmx or svm

关闭虚拟机&#xff0c;选择处理器将虚拟化引擎第一个选项选上&#xff0c;重新打开虚拟机&#xff0c;进行编译打开模拟器。 source build/envsetup.shlunch aosp_x86_64-engemulator