一、前言

二、主要内容

1、实现效果(其实可以直接在父组件中操作子组件的显示隐藏,但是这里通过在子组件定义自己的显示隐藏效果,让父组件调用,训练一下这种方式)

2、分析:

  (1)点击父组件的某一个li项,跳出这个商品详情(子组件项)

(2)子组件中还是需要接收到父组件中的food,但是这个food不像上一篇那样是固定的,所以这里的这个food是根据我们点击的不同的项,传进去的

(3)为了实现上一步分析:我们需要在data中定义一个对象,点击的时候,将当前对象的food传进去,然后在传给子组件,这样就能实现动态传递food了

3、具体实现

  (1)父组件中先引入并且使用子组件

  (2)在父组件的每一项上添加一个点击事件,并且将当前项的food通过定义的这个函数传给子组件

<!--点击的时候将当前的food传进去-->
<li class="food-item bottom-border-1px" v-for="(food, index) in good.foods" :key="index" @click="showFood(food)">//省略</div></div>
</li>

  (3)metods:中定义这个方法接收并传过去

 <template><Food :food="food" ref="food"></Food>
</template><script>data(){return{scrollY:0,tops:[], //存放每一个类的初始位置
        food:{}}}components:{Food}// 显示点击的food
      showFood (food) {// 设置foodthis.food = food}
</script>

  (4)在子组件中要定义该组件的显示隐藏方法,先用一个标识来标记

export default {props: {food: Object},data () {return {isShow: false}},methods: {toggleShow () {this.isShow = !this.isShow}},components: {CartControl}}

  (5)父组件中用this.$refs.refname.method()来得到子组件的方法,并且执行

 // 显示点击的food
      showFood (food) {// 设置foodthis.food = food// 显示food组件 (在父组件中调用子组件对象的方法)this.$refs.food.toggleShow()}

4、完整代码:

父组件:

<template><div><div class="goods"><div class="menu-wrapper"  ><ul><!--current--><li class="menu-item " v-for="(good,index) in goods" :key="index" :class="{current:index===currentIndex}" @click="clickMenuItem(index)"><span class="text bottom-border-1px"><img class="icon" :src="good.icon" v-if="good.icon" >{{good.name}}</span></li></ul></div><div class="foods-wrapper"><ul ref="foodsUl"><li class="food-list-hook" v-for="(good, index) in goods" :key="index" ><h1 class="title">{{good.name}}</h1><ul><li class="food-item bottom-border-1px" v-for="(food, index) in good.foods" :key="index" @click="showFood(food)"><div class="icon"><img width="57" height="57" :src="food.icon"></div><div class="content"><h2 class="name">{{food.name}}</h2><p class="desc">{{food.description}}</p><div class="extra"><span class="count">月售{{food.sellCount}}份</span><span>好评率{{food.rating}}%</span></div><div class="price"><span class="now">¥{{food.price}}</span><span class="old" v-if="food.oldPrice">¥{{food.oldPrice}}</span></div><div class="cartcontrol-wrapper"><CartControl :food='food'></CartControl></div></div></li></ul></li></ul></div><Food :food="food" ref="food"></Food></div></div>
</template><script>import {mapState} from 'vuex'import BScroll from 'better-scroll'import CartControl from '../../../components/CartControl/CartControl'import Food from '../../../components/Food/Food'export default {data(){return{scrollY:0,tops:[], //存放每一个类的初始位置
        food:{}}},components:{CartControl,Food},//这里的数据是异步显示的,所以我们要等数据异步请求之后再创建这个滑动列表
      mounted(){//异步请求可以传过去两个参数,this.$store.dispatch('getShopGoods',()=>{//数据请求完之后再执行这里了//初始化滚动this.$nextTick(()=>{//初始化,并且实时获取滚动坐标this._initScrollY()//初始化右边的数组this._initTops();})       })},methods:{//初始化BScroll
          _initScrollY(){new BScroll('.menu-wrapper',{click:true})//创建右边的this.foodswrapper = new BScroll('.foods-wrapper',{click:true,probeType:3})//给右侧绑定的BScroll绑定监听事件,但是你会发现并没有调用this.foodswrapper.on('scroll',({x,y})=>{console.log(x,y)//默认没有分发滚动事件this.scrollY=Math.abs(y);})//获取停下来的位置//给右侧绑定的BScroll绑定监听事件,但是你会发现并没有调用this.foodswrapper.on('scrollEnd',({x,y})=>{//console.log(x,y)//默认没有分发滚动事件this.scrollY=Math.abs(y);})}//初始化数组,获取到每个li 的坐标
        ,_initTops(){var tops=[] //定义一个空数组let top=0;tops[0]=0 //第一个li的坐标为0var lis = this.$refs.foodsUl.children; //获取到了每个liArray.prototype.slice.call(lis).forEach((li,index)=>{top = top + li.clientHeight//当前的位置,等于上一个的位置,加上这一个的高度
                tops.push(top)})this.tops=topsconsole.log(tops)},
//将当前的index传进来
        clickMenuItem(index){//先得到目标位置scrollYconst top = this.tops[index];// 立即更新scrollY,更新当前分类,点击的分类项成为当前this.scrollY=top//平滑滚动右侧列表this.foodswrapper.scrollTo(0, -top, 3);},// 显示点击的food
      showFood (food) {// 设置foodthis.food = food// 显示food组件 (在父组件中调用子组件对象的方法)this.$refs.food.toggleShow()}},computed:{...mapState(['goods']),currentIndex(){return this.tops.findIndex((top,index)=>{return this.scrollY>=top && this.scrollY<this.tops[index+1]})}}}</script><style lang="stylus" rel="stylesheet/stylus">@import "../../../common/stylus/mixins.styl".goodsdisplay: flexposition: absolutetop: 195pxbottom: 46pxwidth: 100%background: #fff;overflow: hidden.menu-wrapperflex: 0 0 80pxwidth: 80pxbackground: #f3f5f7.menu-itemdisplay: tableheight: 54pxwidth: 56pxpadding: 0 12pxline-height: 14px&.currentposition: relativez-index: 10margin-top: -1pxbackground: #fffcolor: $greenfont-weight: 700.textborder-none().icondisplay: inline-blockvertical-align: topwidth: 12pxheight: 12pxmargin-right: 2pxbackground-size: 12px 12pxbackground-repeat: no-repeat.textdisplay: table-cellwidth: 56pxvertical-align: middlebottom-border-1px(rgba(7, 17, 27, 0.1))font-size: 12px.foods-wrapperflex: 1.titlepadding-left: 14pxheight: 26pxline-height: 26pxborder-left: 2px solid #d9dde1font-size: 12pxcolor: rgb(147, 153, 159)background: #f3f5f7.food-itemdisplay: flexmargin: 18pxpadding-bottom: 18pxbottom-border-1px(rgba(7, 17, 27, 0.1))&:last-childborder-none()margin-bottom: 0.iconflex: 0 0 57pxmargin-right: 10px.contentflex: 1.namemargin: 2px 0 8px 0height: 14pxline-height: 14pxfont-size: 14pxcolor: rgb(7, 17, 27).desc, .extraline-height: 10pxfont-size: 10pxcolor: rgb(147, 153, 159).descline-height: 12pxmargin-bottom: 8px.extra.countmargin-right: 12px.pricefont-weight: 700line-height: 24px.nowmargin-right: 8pxfont-size: 14pxcolor: rgb(240, 20, 20).oldtext-decoration: line-throughfont-size: 10pxcolor: rgb(147, 153, 159).cartcontrol-wrapperposition: absoluteright: 0bottom: 12px
</style>

父组件.vue

子组件:

<template><div class="food" v-if="isShow"><div class="food-content"><div class="image-header"><img :src="food.image"><p class="foodpanel-desc">{{food.info}}</p><div class="back" @click="toggleShow"><i class="iconfont icon-arrow_left"></i></div></div><div class="content"><h1 class="title">{{food.name}}</h1><div class="detail"><span class="sell-count">月售{{food.sellCount}}份</span><span class="rating">好评率{{food.rating}}%</span></div><div class="price"><span class="now">¥{{food.price}}</span><span class="old" v-show="food.oldPrice">¥{{food.oldPrice}}</span></div><div class="cartcontrol-wrapper"><CartControl :food="food"/></div></div></div><div class="food-cover" @click="toggleShow"></div></div>
</template><script>import CartControl from '../CartControl/CartControl.vue'export default {props: {food: Object},data () {return {isShow: false}},methods: {toggleShow () {this.isShow = !this.isShow}},components: {CartControl}}
</script><style lang="stylus" rel="stylesheet/stylus" scoped>@import "../../common/stylus/mixins.styl".foodposition: fixedleft: 0top: 0bottom: 48pxz-index: 101width: 100%&.fade-enter-active, &.fade-leave-activetransition opacity .5s&.fade-enter, &.fade-leave-toopacity 0.food-contentposition absoluteleft 50%top 50%transform translate(-50%, -50%)width 80%height 65%z-index 66background #fffborder-radius 5px.image-headerposition: relativewidth: 100%height: 0padding-top: 100%imgposition: absolutetop: 0left: 0width: 100%height: 100%.foodpanel-descfont-size 10pxcolor #dddletter-spacing 0position absolutebottom 0left 0right 0padding 0 10px 10px.backposition: absolutetop: 10pxleft: 0.icon-arrow_leftdisplay: blockpadding: 10pxfont-size: 20pxcolor: #fff.contentposition: relativepadding: 18px.titleline-height: 14pxmargin-bottom: 8pxfont-size: 14pxfont-weight: 700color: rgb(7, 17, 27).detailmargin-bottom: 18pxline-height: 10pxheight: 10pxfont-size: 0.sell-count, .ratingfont-size: 10pxcolor: rgb(147, 153, 159).sell-countmargin-right: 12px.pricefont-weight: 700line-height: 24px.nowmargin-right: 8pxfont-size: 14pxcolor: rgb(240, 20, 20).oldtext-decoration: line-throughfont-size: 10pxcolor: rgb(147, 153, 159).cartcontrol-wrapperposition: absoluteright: 12pxbottom: 12px.buyposition: absoluteright: 18pxbottom: 18pxz-index: 10height: 24pxline-height: 24pxpadding: 0 12pxbox-sizing: border-boxborder-radius: 12pxfont-size: 10pxcolor: #fffbackground: rgb(0, 160, 220)&.fade-transitiontransition: all 0.2sopacity: 1&.fade-enter, &.fade-leaveopacity: 0.food-coverposition absolutetop 0right 0bottom -48pxleft 0z-index 55background-color rgba(0, 0, 0, 0.5)</style>

子组件.vue

三、总结

转载于:https://www.cnblogs.com/xxm980617/p/10859233.html

vue(ref父组件使用子组件中定义的方法)相关推荐

  1. js代码 父页面调用子页面中的js方法,子页面调用父页面中的js方法

    文中代码亲测可用,转载以示尊重!!! <!--主页面中的JS代码--> <script type="text/javascript"> //调用子页面的方法 ...

  2. 父页面与子ifream传值,父页面获取子页面document元素与方法

    1.父页面获取子ifream中document元素方法 window.document.getElementById('warnIfream').contentWindow.document.getE ...

  3. Vue中父组件调用子组件的方法

    场景 SpringBoot+Vue+Echarts实现选择时间范围内数据加载显示柱状图: SpringBoot+Vue+Echarts实现选择时间范围内数据加载显示柱状图_BADAO_LIUMANG_ ...

  4. 【Vue 组件化开发 三】父组件给子组件传递数据、组件通信(父传子、子传父)、父访问子(children、ref)、动态组件(is、component)

    目录 一.前言 完整内容请关注: 二.父组件给子组件传递数据 1.使用props属性,父组件向子组件传递数据 1.使用组件的props属性 2.向cmessage对象传值 2. props属性使用 1 ...

  5. vue中组件之间调用方法——子组件调用父组件的方法 父组件调用子组件的方法

    vue中组件之间调用方法--子组件调用父组件的方法 & 父组件调用子组件的方法 1.vue中子组件调用父组件的方法 1.1.第一种方法是直接在子组件中通过this.$parent.event来 ...

  6. vue ref是在组件里唯一吗_父组件伸手子组件的方式总结

    1. 前言 这篇文章就是总结react,vue父组件如何伸手获取子组件的数据以及调用子组件方法的. 2. react 以下的代码都是基于16.8版本. 2.1 类组件 react在hook出来前,只要 ...

  7. 042——VUE中组件之子组件使用$on与$emit事件触发父组件实现购物车功能

    <!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8" ...

  8. Vue.js父与子组件之间传参 父向子组件传参   例子:App.vue为父,引入componetA组件之后,则可以在template中使用标签(注意驼峰写法要改成componet-a写法,因为ht

    Vue.js父与子组件之间传参 父向子组件传参 例子:App.vue为父,引入componetA组件之后,则可以在template中使用标签(注意驼峰写法要改成componet-a写法,因为html对 ...

  9. Vue 中 props 传值,父组件向子组件传递对象/数组可以直接修改的问题

    vue 中父子组件通信最常用的方式是 props 和 $emit,所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行.这 ...

最新文章

  1. OpenCV之imgproc 模块. 图像处理(4)直方图均衡化 直方图计算 直方图对比 反向投影 模板匹配
  2. lnmp mysql 路径_LNMP笔记:更改网站文件和MySQL数据库的存放目录
  3. ▲教你如何轻易的做linux计划任务▲——小菜一碟
  4. (六)数据结构之“集合”
  5. matlab的grayscale,Python 是否等效于Matlab函数“imfill”的grayscale??
  6. SMO写的查看数据库信息的代码
  7. 【转】PHP面试题总结
  8. mysql不能做端点测试吗_端点测试的分步介绍
  9. 问题二十一:怎么模拟ray tracing图形中不同材料的颜色(diffuse and metal)
  10. 第006讲 多媒体页面 标签汇总
  11. linux 搭建文件服务器(vsftpd)
  12. instead of 的用法
  13. 【高项备考】质量管理的质量管理工具学习
  14. 一个纯粹的中文搜索引擎【Doge Doge】多吉搜索
  15. KETTLE4个工作中有用的复杂实例--1、数据定时自动(自动抽取)同步作业
  16. ctfshow web入门 命令执行:55-57
  17. elasticsearch7.12 agg分组聚合分页同段同句查询
  18. vue移动端开启键盘 页面底部样式乱了
  19. Unexpected Exception caught setting '' on 'class com.: Error setting expression '' with value ['', ]
  20. R包之tm:文本挖掘包

热门文章

  1. php 零宽断言,正则表达式之零宽断言
  2. 计算机常用汉字输入法的使用,计算机的基本操作汉字输入法--.ppt
  3. java 压缩包添加文件,如何在Java中向现有zip文件添加条目?
  4. build openposewith opencv-2.4.13,cuda9(9.0 - 9.2)
  5. DE25 Homogeneous Linear Systems with Constant Coefficients
  6. 基于集成学习的小麦赤霉病高光谱图像识别方法研究
  7. 为什么两个controller的session的id不一样_新笑傲江湖手游服务器名字为什么不一样解答...
  8. python123下载失败_安装python3.5时出现严重错误无法完成安装,请问这个是什么情况?怎么解决??...
  9. 知识图谱组队学习Task04——知识库的查询语句
  10. vue 两个table 并排_从零到部署:用 Vue 和 Express 实现迷你全栈电商应用(六)