vue 封装面包屑组件教程

我看过一篇关于程序员写博客的文章,他说很多的程序员过了两年写了很多的代码,但是回想起来自己具体做了哪些技术点,遇到坑几乎没有印象,所以说文字是记录的最好方式,好记性不如烂笔头,可以方便自己以后查看,在写的过程中也会再加深一遍印象,我也来折腾折腾。

第一次写文章就写一个比较有意义的吧,18年四月末来到目前所在的这家公司,熟悉了一周环境和代码后,新的任务就是使用vue+element-ui来重构之前老版本的项目,我主要负责就是用户管理的一个模块,因为之前没有用过vue所以恶补了一周的vue了解了一些指令和vuex就开始做项目,排版使用的就是element-ui,这个ui框架用起来是比较方便的,因为对于金融行业pc端来说页面没有太炫他华丽,这个ui框架刚好符合我们的需求

遇到的第一个功能点就是面包屑,因为每个页面都会需要用到,所以经理提议把它封装起来

效果图

子组件

首先新建一个页面(子组件),把页面的基本样式实现出来,这里是自己写的div+css

子组件是封装好的一个例子,而父组件是每一个页面,页面中需要用到面包屑时就引入

父组件

调用子组件

引入子组件路径

注册组件

给子组件传的值

局部组件注册在components,可以在里面注册多个

这个里面涉及到一个点就是父组件给子组件传参

总的来说父传子就是这三个步骤:父组件中定义值、调用子组件并引用、在引用的标签上给子组件传值。

获取父组件的数据的方式props,定义接收值的类型,文章中接收值的类型是数组

但是有要注意的点:

子组件接受的父组件的值分为——引用类型和普通类型两种,

普通类型:字符串(String)、数字(Number)、布尔值(Boolean)、空(Null)

引用类型:数组(Array)、对象(Object)

其中,普通类型是可以在子组件中更改,不会影响其他兄弟子组件内同样调用的来自父组件的值,

但是,引用类型的值,当在子组件中修改后,父组件的也会修改,那么后果就是,其他同样引用了改值的子组件内部的值也会跟着被修改。除非你有特殊的要求这么去做,否则最好不要这么做。

补充知识:vue element组件实现步骤条形式的复杂表单信息的注册

实际效果如下

vue代码如下

<template>
 <div id="bdy">
  <Head/>
 <div class="tbody">
<el-steps :active="active" finish-status="success">
 <el-step title="上传头像"></el-step>
 <el-step title="个人信息"></el-step>
 <el-step title="专业信息"></el-step>
 <el-step title="证书信息"></el-step>
</el-steps>
<!-- 个人信息 -->
 <el-form ref="form" :model="form" label-width="80px">
<div class="info" v-if="active==1">
 <el-form-item label="上传头像" prop="imageUrl">
   <el-upload
 class="avatar-uploader"
 action="https://jsonplaceholder.typicode.com/posts/"
 :show-file-list="false"
 :on-success="handleAvatarSuccess"
 :before-upload="beforeAvatarUpload" >
 <img v-if="form.imageUrl" :src="form.imageUrl" class="avatar">
 <i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
 </el-form-item>
</div>
<div class="info" v-if="active==2">
<el-form-item label="真实姓名" prop="username">
 <el-input v-model="form.username"></el-input>
 </el-form-item>
 <el-form-item label="手机号码" prop="tell">
 <el-input type="text" v-model="form.tell" autocomplete="off"></el-input>
 </el-form-item>
 <el-form-item label="身份证" prop="indentity">
 <el-input type="text" v-model="form.indentity" autocomplete="off"></el-input>
 </el-form-item>
</div>
<div class="info" v-if="active==3">

 <el-form-item label="专长领域:" prop="area">
  <br>
 <el-checkbox-group v-model="form.area" @change="handleCheckedCitiesChange" >
 <el-checkbox v-for="city in form.cities" :label="city" :key="city">{{city}}</el-checkbox>
 </el-checkbox-group>
 </el-form-item>
 <el-form-item label="从业资质:" prop="quality">
  <br>
 <el-radio-group v-model="form.quality">
 <el-radio :label="0">国家二级咨询师</el-radio>
 <el-radio :label="1">国家三级咨询师</el-radio>
 <el-radio :label="2">注册系统咨询师</el-radio>
  <el-radio :label="3">注册系统督导师</el-radio>
  <el-radio :label="4">其他</el-radio>
 </el-radio-group>
</el-form-item>
</div>
<div class="info" v-if="active==4">
<el-form-item label="证书编号" prop="number">
 <el-input type="text" v-model="form.number" autocomplete="off"></el-input>
 </el-form-item>
 <el-form-item label="从业年限" prop="time">
 <el-input type="text" v-model="form.time" autocomplete="off"></el-input>
 </el-form-item>
 <el-form-item label="个人简介" prop="instroduce">
 <el-input type="text" v-model="form.instroduce" autocomplete="off"></el-input>
 </el-form-item>
 <el-form-item>
 <el-button type="primary" @click="onSubmit">申请入驻</el-button>
 </el-form-item>
</div>
<el-button style="margin-top: 12px;" @click="next" v-if="active<4">下一步</el-button>
<el-button style="margin-top: 12px;" @click="pre" v-if="active>1">上一步</el-button>
</el-form>
</div>
</div>
</template>
<style>
.tbody{
 width:80%;
 margin-left:10%;
 margin-top: 2%;
}
/* 表单 */
.avatar-uploader .el-upload {
 border: 1px dashed #d9d9d9;
 border-radius: 6px;
 cursor: pointer;
 position: relative;
 overflow: hidden;
 }
 .avatar-uploader .el-upload:hover {
 border-color: #409EFF;
 }
 .avatar-uploader-icon {
 font-size: 28px;
 color: #8c939d;
 width: 178px;
 height: 178px;
 line-height: 178px;
 text-align: center;
 }
 .avatar {
 width: 178px;
 height: 178px;
 display: block;
 }
</style>
<script>
//表单js代码
import Head from "../../components/common/Head";
import axios from "axios";
import Qs from "qs";
import router from "../../router/router.js";
 const cityOptions = ['婚姻家庭', '情绪管理', '恋爱心理', '个人成长','人际关系','心理健康','职场心理','亲子教育','性心理'];
 export default{
 components: {
 Head
 },
 data() {
  return {
   active: 1,
   form: {
   area: ['个人成长'],
   checkAll: false,
   cities: cityOptions,
   isIndeterminate: true,
   quality: 0,
   imageUrl: '',
   username : '',
   tell: '',
   indentity: '',
   number:'',
   instroduce:'',
   time:''
  }
  }
 },
 methods: {
  onSubmit() {
   //this.form.checkedCities获取多选框的内容 zxs[this.form.radio] this.form.imageUrl
  //开始提交 在这里进行跨域请求
   this.axios({
   method: "post",
   url: "/api/PsychoSys/tuser.action",
   data: Qs.stringify(this.form)
   })
   .then(res => {
    this.$router.push("/tinfo");
   })
   .catch(function(err) {
    console.log(err);
   });
   /*在这里进行跨域请求*/
  //开始提交
  },
  handleAvatarSuccess(res, file) {
  this.form.imageUrl = URL.createObjectURL(file.raw);
  },
 beforeAvatarUpload(file) {
  const isJPG = file.type === 'image/jpeg';
  const isLt2M = file.size / 1024 / 1024 < 2;
  if (!isJPG) {
   this.$message.error('上传头像图片只能是 JPG 格式!');
  }
  if (!isLt2M) {
   this.$message.error('上传头像图片大小不能超过 2MB!');
  }
  return isJPG && isLt2M;
  },
  handleCheckAllChange(val) {
  this.form.area = val ? cityOptions : [];
  this.isIndeterminate = false;
  },
  handleCheckedCitiesChange(value) {
  let checkedCount = value.length;
  this.checkAll = checkedCount === this.form.cities.length;
  this.isIndeterminate = checkedCount > 0 && checkedCount < this.form.cities.length;
  }, next() {
  if (this.active++ > 3) this.active = 1;
  },
  pre() {
  if (this.active-- < 2) this.active = 1;
  }
 }
 }
//表单js代码
</script>

后台是用java的ssh框架做的

package cn.com.service;
import java.io.IOException;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.ServletActionContext;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import cn.com.bean.Teacher;

import com.opensymphony.xwork2.ModelDriven;
@Repository(value="teacherUser")
@Scope("prototype")
public class TeacherUser implements ModelDriven<Teacher>{
 @Autowired
 private SessionFactory sf;
 @Autowired
 private Teacher tea;
 private List<String> area;
 public List<String> getArea() {
 return area;
 }
 public void setArea(List<String> area) {
 this.area = area;
 }
 @Transactional
 public String regedit_user(){
   //普通用户注册 ,用户名不能重复
 Session session=sf.getCurrentSession();
 //查询是否重复
 String sql="from Teacher where username=?";
 Query query=session.createQuery(sql);
 query.setString(0, tea.getUsername());
 Teacher t=(Teacher)query.uniqueResult();
 String toast="";
 String [] zxs ={"国家二级咨询师","国家三级咨询师","注册系统咨询师","注册系统督导师","其他"};
 String q="";
 if(t!=null){
 toast="fail";
 }else{
 //处理数据
 Integer o=Integer.parseInt(tea.getQuality());
 tea.setQuality(zxs[o]);
 tea.setAreas(area.toString());
 toast="success";
 session.save(tea);
 }
 HttpServletResponse response = ServletActionContext.getResponse();
 response.setCharacterEncoding("utf-8");
 try {
 response.getWriter().write(toast);
 } catch (IOException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }
 return null;
 }

 public Teacher getModel() {
 return tea;
 }
}

以上这篇vue 封装面包屑组件教程就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Vuex,iView UI面包屑导航使用扩展详解

    本案例是基于Vuex的公共数据库,你在了解本案例之前要了解Vuex的使用方法. https://www.iviewui.com/components/breadcrumb 打开网址我们可以知道这个组件的面包屑导航是基于路由跳转的.但是我们项目中常常用到单页面查询面包屑导航.小生开始为这个纠结好久.然后和小伙伴一起研究出来一套单页面不用路由跳转的使用方法. 先看看效果图 1,首次进来 2,查询结果 3,再次点击面包屑导航 4,查询结果 基本的效果是这样的 下面看代码 <template> <

  • Vue 解决多级动态面包屑导航的问题

    固定路由的面包屑导航 我们在配置router的时候,可以将面包屑数据配置在meta中, 例如 路由配置: { path: '/project/process/:id', name: 'process', component: () => import('@/views/project/process/main.vue'), meta: [ { name: '项目管理列表' }, { name: '项目列表', url: '/project/list' }, { name: '里程碑' }, ],

  • VUE+elementui面包屑实现动态路由详解

    我的路由: const routerMap = [ { path: '/', redirect: 'dashboard', component: Layout, name:'Dashboard', children: [ { path: 'dashboard', component: () => import('@/view/dashboard'), name: 'Dashboard', meta: { title: 'dashboard', icon: 'dashboard', noCache

  • vue element-ui实现动态面包屑导航

    vue element-ui动态面包屑导航,供大家参考,具体内容如下 直接上代码 一.template代码 // 这是单独的组件 <template> <el-breadcrumb separator-class="el-icon-arrow-right"> // 首页我是写死的,其他的遍历出来 <el-breadcrumb-item :to="{ name: 'home' }">首页</el-breadcrumb-item

  • Vue动态面包屑功能的实现方法

    面包屑应该是我们在项目中经常使用的一个功能,一般情况下它用来表示我们当前所处的站点位置,也可以帮助我们能够更快的回到上个层级. 今天我们就来聊聊如何在 Vue 的项目中实现面包屑功能.以下案例都是使用 Element-UI 进行实现. 最笨的方式 首先我们想到的最笨的方法就是在每个需要面包屑的页面中固定写好. <template> <div class="example-container"> <el-breadcrumb separator="

  • vue 使用localstorage实现面包屑的操作

    mutation.js代码: changeRoute(state, val) { let routeList = state.routeList; let isFind = false; let findeIdex = 0; //菜单栏和下拉的二级菜单 if (val['type'] == 'header' || val['type'] == 'secondHeader') { routeList.length = 0; //顶级菜单清除缓存 localStorage.removeItem("r

  • vue+elementUI动态生成面包屑导航教程

    效果如下所示: 项目需要动态生成面包屑导航,并且首页可以点击.其余为路径显示 <el-menu :unique-opened="true" router :default-active="$route.path" @select="handleSelect"> <div class="user-menu-box" v-for="menu in menus" :key="menu.

  • vue中的面包屑导航组件实例代码

    vue的面包屑导航组件 用来将其放到navbar中: Breadcrumb/index.vue <template> <el-breadcrumb class="app-breadcrumb" separator="/"> <transition-group> <el-breadcrumb-item v-for="(item,index) in levelList" :key="item.pat

  • vue 封装面包屑组件教程

    我看过一篇关于程序员写博客的文章,他说很多的程序员过了两年写了很多的代码,但是回想起来自己具体做了哪些技术点,遇到坑几乎没有印象,所以说文字是记录的最好方式,好记性不如烂笔头,可以方便自己以后查看,在写的过程中也会再加深一遍印象,我也来折腾折腾. 第一次写文章就写一个比较有意义的吧,18年四月末来到目前所在的这家公司,熟悉了一周环境和代码后,新的任务就是使用vue+element-ui来重构之前老版本的项目,我主要负责就是用户管理的一个模块,因为之前没有用过vue所以恶补了一周的vue了解了一些

  • vue+elementUI面包屑组件封装方法详解

    本文实例为大家分享了vue+elementUI面包屑组件封装的具体代码,供大家参考,具体内容如下 一.选择用哪种样式 二.在组件文件夹下创建组件 三.在Bread.vue复制如下代码 <template>   <!-- 面包屑 -->   <div class="bread">  <el-breadcrumb separator-class="el-icon-arrow-right">  <el-breadcru

  • vue面包屑组件的封装方法

    vue中自己封装面包屑组件,供大家参考,具体内容如下 要实现效果 前言 很多电商类产品都需要实现面包屑导航,用来优化用户体验 一.初级面包屑封装组件 1.封装基础结构组件 Bread.vue <template> <div class='xtx-bread'> <div class="xtx-bread-item"> <RouterLink to="/">首页</RouterLink> </div&g

  • vue3自己封装面包屑功能组件的几种方式

    目录 前言 一.为什么需要面包屑? 二.初级封装 1. 实现思路 2. 代码演示 3. 使用 4. 不足 三.进阶封装 1. 实现思路 2. 代码演示 3. 使用 4. 不足 四.高阶封装 1. 思路 2. 代码演示 3. 使用 五.使用jsx优化 总结 前言 面包屑导航可以将浏览过的页面记录下来,方便很快速的跳转回某一个页面,本文介绍了几种自己封装面包屑组件的方式,我们一起来看看如何实现的吧~ 一.为什么需要面包屑? 面包屑导航(BreadcrumbNavigation)这个概念来自童话故事"

  • vue实现面包屑的方法

    vue中面包屑的实现方法,供大家参考,具体内容如下 面包屑是什么: 面包屑是作为辅助和补充的导航方式(secondary navigation scheme),它能让用户知道在网站或应用中所处的位置并能方便地回到原先的地点. 最常见的面包屑的样式是:横向的文字链接,由大于号“>”分开,这个符号也暗示了它们的层级关系 实现原理: 1.在router配置中加入meta(元数据)对象,存放一些自定义的内容.例如在面包屑的实现中加入title变量,这个变量则是面包屑展示出来的多级标题. 2.在用到面包屑

  • vue封装可复用组件confirm,并绑定在vue原型上的示例

    如下所示: 首先我们需要创建 confirm.vue , confirm.js这两个文件,一个实现dom结构,一个实现相关逻辑 confirm.vue <template> <div class="confirm" v-if="isShow"> <div class="con_box" > <div class="context"> <h6>{{text.type}}

  • Vue封装全局toast组件的完整实例

    目录 前言 一. 借助 vue-cli 1. 定义 Toast 组件 2. 在 main.js 里面配置 3. 在其他组件内使用 二.不借助 vue-cli 1. 注册 toast 组件 2. 注册 toast 插件 3. 在其他组件内使用 总结 前言 最近体验了下Vue,Toast都是前端常用组件,本文详细介绍了Vue封装全局toast组件的过程,下面话不多说了,来一起看看详细的介绍吧 一. 借助 vue-cli 1. 定义 Toast 组件 // components/Toast <temp

  • Vue封装通用table组件的完整步骤记录

    目录 前言 为什么需要封装table组件? 第一步:定义通用组件 第二步:父组件与子组件进行render通信 第三步:使用组件 总结 前言 随着业务的发展和功能的增多,我们发现不少页面都具备相似的功能,这里举几个比较俗的例子:可以多选的下拉菜单,带输入的对话框,日期选择器等等,于是我们会想办法将这些共有的功能抽取成一个个公共组件,以便能够在不同的页面或业务中使用. 为什么需要封装table组件? 后台管理系统表格使用频率高,减少关于table的业务代码,且便于后期统一修改.便于后期维护.如给ta

随机推荐