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 相关文章推荐
javascript动画之圆形运动,环绕鼠标运动作小球
Jul 20 Javascript
js拦截alert对话框另类应用
Jan 16 Javascript
利用Javascript判断操作系统的类型实现不同操作系统下的兼容性
Jan 29 Javascript
JS动态获取当前时间,并写到特定的区域
May 03 Javascript
js调用css属性写法
Sep 21 Javascript
JavaScript中this关键词的使用技巧、工作原理以及注意事项
May 20 Javascript
JavaScript实现的一个计算数字步数的算法分享
Dec 06 Javascript
Vue.js教程之axios与网络传输的学习实践
Apr 29 Javascript
js正则取值的结果数组调试方法
Oct 10 Javascript
vue实现循环切换动画
Oct 17 Javascript
vue 动态表单开发方法案例详解
Dec 02 Javascript
Vue封装Axios请求和拦截器的步骤
Sep 16 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
ini_set的用法介绍
2014/01/07 PHP
CodeIgniter启用缓存和清除缓存的方法
2014/06/12 PHP
在JS中最常看到切最容易迷惑的语法(转)
2010/10/29 Javascript
通过JavaScript控制字体大小的代码
2011/10/04 Javascript
HTML中的setCapture和releaseCapture使用介绍
2012/03/21 Javascript
jQuery把表单元素变为json对象
2013/11/06 Javascript
jquery退出each循环的写法
2014/02/26 Javascript
JavaScript通过this变量快速找出用户选中radio按钮的方法
2015/03/23 Javascript
jQuery实现的简单分页示例
2016/06/01 Javascript
用js写的一个路由(简单实例)
2016/09/24 Javascript
JavaScript实现类似拉勾网的鼠标移入移出效果
2016/10/27 Javascript
快速入门Vue
2016/12/19 Javascript
详解Angular2中Input和Output用法及示例
2017/05/21 Javascript
解决vue v-for 遍历循环时key值报错的问题
2018/09/06 Javascript
vue 中 beforeRouteEnter 死循环的问题
2019/04/23 Javascript
详解小程序云开发数据库
2019/05/20 Javascript
Python首次安装后运行报错(0xc000007b)的解决方法
2016/10/18 Python
Python实现发送QQ邮件的封装
2017/07/14 Python
python flask中静态文件的管理方法
2018/03/20 Python
详解pandas的外部数据导入与常用方法
2019/05/01 Python
python3射线法判断点是否在多边形内
2019/06/28 Python
利用4行Python代码监测每一行程序的运行时间和空间消耗
2020/04/22 Python
python保留格式汇总各部门excel内容的实现思路
2020/06/01 Python
python中K-means算法基础知识点
2021/01/25 Python
CSS3解决移动页面上点击链接触发色块的问题
2016/06/03 HTML / CSS
AmazeUI导航的示例代码
2020/08/14 HTML / CSS
白俄罗斯女装和针织品网上商店:Presli.by
2019/10/13 全球购物
荷兰家电购物网站:Expert.nl
2020/01/18 全球购物
盖尔斯工厂店:GUESS Factory
2020/01/21 全球购物
超市营业员求职简历的自我评价
2013/10/17 职场文书
幼儿园的门卫岗位职责
2014/04/10 职场文书
社区志愿者活动总结
2014/06/26 职场文书
法定代表人身份证明书
2015/06/18 职场文书
幼儿园庆六一主持词
2015/06/30 职场文书
创业计划书之干洗店
2019/09/10 职场文书
SQL Server内存机制浅探
2022/04/06 SQL Server