vue两组件间值传递 $router.push实现方法


Posted in Javascript onMay 15, 2019

两组件间传值,可能包含多种情况,有父子组件和非父子组件,对于父子组件网上有很详细的方法讲解,但非父子组件传值有用bus总线,还有一些其他方法,其中的使用路由跳转的方法讲解太过简洁,难以理解。因为是公司项目,采用的是公司封装的UI框架,但基本上还是采用vue框架,ts编写。所以一些样式结构可能没有参考价值,但我会讲解清楚每一部分作用,主要是路由跳转部分的代码实现。

首先,需求如下图,树状列表每一项有一个编辑按钮,点击按钮之后跳转到另一个路由页面,会将树状列表中每一项数据带过来。

vue文件部分:

<tree
  :data="dataList"
  node-key="id"
  default-expand-all
  :expand-on-click-node="false">
  <span class="custom-tree-node" slot-scope="{ node, data }" :class="$style.list">
    <span :class="$style.listText">{{ node.label }}</span>
    <span :class="$style.listBtn">
      <button
        :class="$style.btn"
        type="text"
        size="mini"
        @click="() => edit(data)">
      </button>
    </span>
  </span>
</tree>
<router-view></router-view>

这是封装好的树状列表,使用 scoped slot 会传入两个参数 node 和 data ,分别表示当前节点的 Node 对象和当前节点的数据。当点击button会路由跳转页面显示在 <router-view>中。

那我们先来看一下ts中edit这个方法是怎么写的。

edit(info: Idata) {
  this.$router.push({
    name: `ListEdit`,
    query: {
      label: info.label,
      scene: info.scene,
    },
  });
},

终于看到主角 $router.push ,它会带两个参数,name表示即将跳转到的路由名字,还有一个参数可以是query,也可以是params,它们的区别简单来说,就相当于 get 和 post ,query == get ,params == post,query 会把携带的参数显示在 url 中。那query中的参数就是所需要携带的参数,那这一步总体来说就意味着跳转到ListEdit这个路由页面,并携带label、scene 这两个参数。

至于其中的 info:Idata 这样的写法是因为ts,ts接口了解一下。

现在编辑按钮这部分内容ok了,它确定了要跳转的地方还有需要携带的参数,那么我们这个ListEdit路由页面就应该做好准备接收人家带来的参数呀。在页面创建期间和路由发生改变期间,都会有一个传值的动作,那就再created钩子函数和监听路由函数中写入代码。

created() {
  const {label= "", scene= ""} = this.$route.query;
  this.form = {
    name: label.toString(),
    initScene: scene.toString(),
  };
},
watch: {
  $route(to, from) {
    if (to.path === "/list/listEdit") {
      const {label= "", scene= ""} = to.query;
      this.form = {
        name: label.toString(),
        initScene: scene.toString(),
      };
    }
  },
},

我感觉这样半截的代码实在难以说明,name、initScene都是前面定义的,还是放出完整代码体验一下吧。

树状列表编辑按钮vue文件部分:

<template>
  <tree
    :data="dataList"
    node-key="id"
    default-expand-all
    :expand-on-click-node="false">
    <span class="custom-tree-node" slot-scope="{ node, data }" :class="$style.list">
      <span :class="$style.listText">{{ node.label }}</span>
      <span :class="$style.listBtn">
        <button
          :class="$style.btn"
          type="text"
          size="mini"
          @click="() => edit(data)">
        </button>
      </span>
    </span>
  </tree>
  <router-view></router-view>
</template>
<script src="./index.ts" lang="ts"></script>

树状列表编辑按钮ts文件部分:

import Vue from "vue";
interface Idata {
  id: string;
  label: string;
  scene: string;
  children?: Idata[];
}
export default Vue.extend({
  data() {
    const data: Idata[] = [{
      id: "1",
      label: "1",
      scene: "场景1",
    }, {
      id: "2",
      label: "2",
      scene: "场景2",
      children: [{
        id: "4",
        label: "2-1",
        scene: "场景1",
      }],
    }, {
      id: "3",
      label: "3",
      scene: "场景2",
    }];
    return {
      data,
      dataList: JSON.parse(JSON.stringify(data)),
    };
  },

  methods: {
    edit(info: Idata) {
      this.$router.push({
        name: `VisListEdit`,
        query: {
          label: info.label,
          scene: info.scene,
        },
      });
    },
  },

});

这里,ts接口定义可以递归实现,children的类型定义还是Idata,就可以直接自我调用。

ListEdit 路由页面vue文件部分:

<template>
  <div>
    <form :model="form" ref="form">
      <form-item :label="目录名称">
        <input v-model="form.name"></input>
      </form-item>
      <form-item :label="选择场景">
        <select v-model="form.initScene" placeholder="请输入场景">
          <option  
            v-for="item in sceneOption" 
            :key="item.id" 
            :label="item.name" 
            :value="item.id"> 
          </option>
        </select>
      </form-item>
    </form>
    <div>
      <button type="primary" @click="submitForm">保存</button>
    </div>
  </div>
</template>
<script src="./index.ts" lang="ts"></script>

ListEdit 路由页面ts文件部分:

import Vue from "vue";
interface Iscenes {
  id: string;
  name: string;
  selected: boolean;
}
export default Vue.extend({
  data() {
    const sceneOption: Iscenes[] = [{
      id: "1",
      name: "场景1",
      selected: false,
    },{
      id: "2",
      name: "场景2",
      selected: false,
    },{
      id: "3",
      name: "场景3",
      selected: false,
    }];
    return {
      form: {
        name: "",
        initScene: "",
      },
      sceneOption,
    };
  },
  created() {
    const {label= "", scene= ""} = this.$route.query;
    this.form = {
      name: label.toString(),
      initScene: scene.toString(),
    };
  },
  watch: {
    $route(to, from) {
      if (to.path === "/list/listEdit") {
        const {label= "", scene= ""} = to.query;
        this.form = {
          name: label.toString(),
          initScene: scene.toString(),
        };
      }
    },
  },
  methods: {
    submitForm() {
      console.log("test");
    }
  },

});

最后,再来看一下,路由部分的配置:

import ListDetail from "../views/list-detail/index.vue";
import List from "../views/list/index.vue";
import { MenuConfig } from "./index";

export const listRouter: MenuConfig = {
  path: "/list",
  component: List,
  title: "目录管理",
  key: "list",
  name: "list",
  hasPermission: true,
  subShow: false,
  children: [{
    path: "listEdit",
    title: "编辑目录",
    hasPermission: true,
    name: "ListEdit",
    key: "ListEdit",
    component: ListDetail,
  }],
};

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js loading加载效果实现代码
Nov 24 Javascript
window.name代替cookie的实现代码
Nov 28 Javascript
利用try-catch判断变量是已声明未声明还是未赋值
Mar 12 Javascript
JQuery限制复选框checkbox可选中个数的方法
Apr 20 Javascript
jQuery实现右侧显示可向左滑动展示的深色QQ客服效果代码
Oct 23 Javascript
React实现点击删除列表中对应项
Jan 10 Javascript
微信通过页面(H5)直接打开本地app的解决方法
Sep 09 Javascript
JavaScript设计模式之观察者模式(发布订阅模式)原理与实现方法示例
Jul 27 Javascript
详解angular部署到iis出现404解决方案
Aug 14 Javascript
通过javascript实现段落的收缩与展开
Jun 26 Javascript
简单了解微信小程序的目录结构
Jul 01 Javascript
详解JavaScript作用域、作用域链和闭包的用法
Sep 03 Javascript
JavaScript+HTML5 canvas实现放大镜效果完整示例
May 15 #Javascript
详解微信UnionID作用
May 15 #Javascript
小程序:授权、登录、session_key、unionId的详解
May 15 #Javascript
javascript+HTML5 canvas绘制时钟功能示例
May 15 #Javascript
详解小程序用户登录状态检查与更新实例
May 15 #Javascript
基于vue如何发布一个npm包的方法步骤
May 15 #Javascript
浅谈 Webpack 如何处理图片(开发、打包、优化)
May 15 #Javascript
You might like
php下实现农历日历的代码
2007/03/07 PHP
layui框架实现文件上传及TP3.2.3(thinkPHP)对上传文件进行后台处理操作示例
2018/05/12 PHP
Laravel如何实现自动加载类
2019/10/14 PHP
一步一步教你写一个jQuery的插件教程(Plugin)
2009/09/03 Javascript
JavaScript设置IFrame高度自适应(兼容各主流浏览器)
2013/06/05 Javascript
快速解决FusionCharts联动的中文乱码问题
2013/12/04 Javascript
JavaScript indexOf方法入门实例(计算指定字符在字符串中首次出现的位置)
2014/10/17 Javascript
JS失效 提示HTML1114: (UNICODE 字节顺序标记)的代码页 utf-8 覆盖(META 标记)的冲突的代码页 utf-8
2017/06/23 Javascript
Angular实现下载安装包的功能代码分享
2017/09/05 Javascript
js处理包含中文的字符串实例
2017/10/11 Javascript
浅谈VUE监听窗口变化事件的问题
2018/02/24 Javascript
vue router+vuex实现首页登录验证判断逻辑
2018/05/17 Javascript
详解微信JS-SDK选择图片遇到的坑
2018/08/15 Javascript
解决vue接口数据赋值给data没有反应的问题
2018/08/27 Javascript
Koa日志中间件封装开发详解
2019/03/09 Javascript
微信小程序学习笔记之获取位置信息操作图文详解
2019/03/29 Javascript
node使用async_hooks模块进行请求追踪
2021/01/28 Javascript
python的dataframe和matrix的互换方法
2018/04/11 Python
详解Python Qt的窗体开发的基本操作
2019/07/14 Python
Python文件路径名的操作方法
2019/10/30 Python
python pygame实现滚动横版射击游戏城市之战
2019/11/25 Python
如何利用pygame实现简单的五子棋游戏
2019/12/29 Python
Python 判断时间是否在时间区间内的实例
2020/05/16 Python
打印tensorflow恢复模型中所有变量与操作节点方式
2020/05/26 Python
详解css3自定义滚动条样式写法
2017/12/25 HTML / CSS
解决CSS3的opacity属性带来的层叠顺序问题
2016/05/09 HTML / CSS
图片上传插件ImgUploadJS:用HTML5 File API 实现截图粘贴上传、拖拽上传
2016/01/20 HTML / CSS
澳大利亚最受欢迎的美发和美容在线商店:Catwalk
2018/12/12 全球购物
音乐器材管理制度
2014/01/31 职场文书
教师党员承诺书
2014/03/25 职场文书
初级党校心得体会
2014/09/11 职场文书
2014年学生会生活部工作总结
2014/11/07 职场文书
教师年度个人总结
2015/02/11 职场文书
中小学教师继续教育心得体会
2016/01/19 职场文书
2019请假条的基本格式及范文!
2019/07/05 职场文书
vue使用节流函数的踩坑实例指南
2021/05/20 Vue.js