一、前言

二、主要内容

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. android 图片作为背景图片,Android设置网络图片为手机背景图片的方法
  2. 设计模式中的开闭原则
  3. sealos kubernetes(k8s)高可用安装教程
  4. [渝粤教育] 西南科技大学 高速公路 在线考试复习资料
  5. Spring学习总结(22)——spring-framework-bom解决spring的不同模块依赖版本不同问题...
  6. python的设计哲学是优雅明确简单_Python简单教程
  7. vue2.0 element学习
  8. spring中的@Bean是否一定要与@Configuration一起用
  9. too many files open
  10. IT学生解惑真经(转) (真的好经典!)
  11. 友达37寸长条液晶屏P370IVN04.1-原厂长条屏
  12. matlab T检验(ttest,ttest2)
  13. 2022年我国城镇污水处理运营市场空间可达730亿元
  14. 【链环科技】微信公众号商城开发优势
  15. java斗地主发牌_java斗地主发牌程序
  16. 雄关漫道真如铁,而今迈步从头越 | 挥别2022,再战2023!
  17. 爬取起点网站图书信息(书名、作者、简介、图片url)
  18. C++的std::move及相关概念
  19. ux设计工具_UX设计中的工具和实用主义
  20. ARCGIS SERVER:未指定的错误

热门文章

  1. maven打包忽略注解_Maven打包时遇到的一些坑和解决方案
  2. android带动画的饼图,Android部分源码资源共享(视屏转GIF图片工具、仿抖音、仿朋友圈、仿红包、饼状图、引导图,图灵源码等)...
  3. 解决Ubuntu下Qt Creator无法输入中文
  4. PDE9 wave equation: general solution
  5. PDE34 Transport equation: derivation general solution
  6. ubuntu中wine的安装位置
  7. position based dynamics
  8. snapmix与Bi-Tempered Logistic Loss(自制数据集纯度不高效果好)
  9. stretchlim函数
  10. 让我们了解下什么是智能客服(问答)