0

0

Vue框架中有关goods组件开发

亚连

亚连

发布时间:2018-06-09 16:08:08

|

1593人浏览过

|

来源于php中文网

原创

这篇文章主要介绍了vue框架之goodvs组件开发详解,现在分享给大家,也给大家做个参考。

一、 布局 Flex

Flex 布局,可以简便、完整、响应式地实现各种页面布局,Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。任何一个容器都可以指定为 Flex 布局。

// 指定为 Flex 布局
 display: flex;
flex : 等分 内容缩放 展位空间;
flex : 0 0 80px

// 主要属性
  flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
  flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。
  flex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大
  flex-shrink属性定义项目的缩小比例,默认为1,即如果空间不足,该项目将缩小,flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小
  flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小,设为跟width或height属性一样的值(比如350px),则项目将占据固定空间

二、图标组件

立即学习前端免费学习笔记(深入)”;

子组件 iconMap

<template lang="html">
 <span class="iconMap" :class="iconClassMap[iconType]"></span>
</template>
export default {
 props: { // 图标类型
 iconType: Number
 },
 created() { // 数组类名
 this.iconClassMap = ['decrease', 'discount', 'special', 'invoice', 'guarantee']
 }
}

父组件 goods

import iconMap from '../iconMap/iconMap' // 注意路径写法
// 注册组件
 components: {
 iconMap
 }
<ul>
 <li v-for='(item,index) in goods' class="menu-item">
 <span class="text"> // json 数据 根据 type 判断 是否有图标
 <iconMap v-show="item.type>0" :iconType="item.type"></iconMap>
 {{item.name}}
 </span>
 </li>
</ul>

三、better-scroll 应用

类似iscroll 实现滚动效果

安装

npm install better-scroll

引入

import BScroll from 'better-scroll'

说明

(1)原理:父容器wrapper,它具有固定的高度,当它的第一个子元素content 的高度超出了wrapper的高度,我们就可以滚动内容区了,若没有超出则不能滚动了。

(2)better-scroll 的初始化

better-scroll 的初始化时机很重要,因为它在初始化的时候,会计算父元素和子元素的高度和宽度,来决定是否可以纵向和横向滚动。因此,我们在初始化它的时候,必须确保父元素和子元素的内容已经正确渲染了。如果子元素或者父元素 DOM 结构发生改变的时候,必须重新调用 scroll.refresh() 方法重新计算来确保滚动效果的正常。所以 better-scroll 不能滚动的原因多半是初始化 better-scroll 的时机不对,或者是当 DOM 结构发送变化的时候并没有重新计算 better-scroll。

(3)better-scroll 结合 Vue

Vue.js 提供了我们一个获取 DOM 对象的接口—— vm.$refs。在这里,我们通过了 this.$refs.wrapper 访问到了这个 DOM 对象,并且我们在 mounted 这个钩子函数里,this.$nextTick 的回调函数中初始化 better-scroll 。因为这个时候,wrapper 的 DOM 已经渲染了,我们可以正确计算它以及它内层 content 的高度,以确保滚动正常。

这里的 this.$nextTick 是一个异步函数,为了确保 DOM 已经渲染,底层用到了 MutationObserver 或者是 setTimeout(fn, 0)。其实我们在这里把 this.$nextTick 替换成 setTimeout(fn, 20) 也是可以的(20 ms 是一个经验值,每一个 Tick 约为 17 ms),对用户体验而言都是无感知的。

(4)异步数据的处理

在我们的实际工作中,列表的数据往往都是异步获取的,因此我们初始化 better-scroll 的时机需要在数据获取后,代码如下:

<template>
 <p class="wrapper" ref="wrapper">
 <ul class="content">
 <li v-for="item in data">{{item}}</li>
 </ul>
 </p>
</template>
<script>
 import BScroll from 'better-scroll'
 export default {
 data() {
 return {
 data: []
 }
 },
 created() {
 requestData().then((res) => {
 this.data = res.data
 this.$nextTick(() => {
 this.scroll = new Bscroll(this.$refs.wrapper, {})
 })
 })
 }
 }
</script>

这里的 requestData 是伪代码,作用就是发起一个 http 请求从服务端获取数据,并且这个函数返回的是一个 promise(实际项目中我们可能会用 axios 或者 vue-resource )。我们获取到数据的后,需要通过异步的方式再去初始化 better-scroll,因为 Vue 是数据驱动的, Vue 数据发生变化(this.data = res.data)到页面重新渲染是一个异步的过程,我们的初始化时机是要在 DOM 重新渲染后,所以这里用到了 this.$nextTick,当然替换成 setTimeout(fn, 20) 也是可以的。

注意:这里为什么是在 created 这个钩子函数里请求数据而不是放到 mounted 的钩子函数里?因为 requestData 是发送一个网络请求,这是一个异步过程,当拿到响应数据的时候,Vue 的 DOM 早就已经渲染好了,但是数据改变 —> DOM 重新渲染仍然是一个异步过程,所以即使在我们拿到数据后,也要异步初始化 better-scroll。

使用

初始化需要滚动的dom结构

借助ref属性用来绑定某个dom元素,或者来说来绑定某个组件,然后在函数内用this.$refs.menuwrapper获取到dom。

说明:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素; 如果用在子组件上,引用就指向组件实例:

<p class="menu-wrapper" ref='menuWrapper'> </p>
<p class="foods-wrapper" ref="foodsWrapper"></p>

在ajax内执行_initScroll() 函数

在此之前我们要做一些准备和 注意事项

(1) dom结构完全加载完再调用_initScroll()方法才会生效

Magic AI Avatars
Magic AI Avatars

神奇的AI头像,获得200多个由AI制作的自定义头像。

下载

(2) 因为要监听内容区域的高度,所以初始化应在created过程中去监听dom结构是否完全加载,这里是在$nextTick对象中进行触发检测

ES6语法格式: this.$nextTick(() => {})

created (){ // 在实例创建完成后被立即调用 $el 属性目前不可见。
 axios.get('static/data.json').then((result) => {
 this.goods=result.data.goods
 //dom结构加载结束
 this.$nextTick(() => {
 this._initScroll(); // 初始化scroll
 })
 })
}

(3) 在methods方法里面定义一个_initScroll的函数,主要用来对左右两侧dom结构进行初始化

methods:{
 // 用来对左右两侧dom结构进行初始化
 _initScroll (){
 // 实例化 better-scroll 插件,传入要滚动的DOM 对象 
 this.meunScroll=new BScroll(this.$refs.menuWrapper,{
 click:true 
 });
 this.foodScroll=new BScroll(this.$refs.foodsWrapper,{
 click:true
 });
 
 }
 }

说明:vue中更改数据,DOM会跟着做映射,但vue更新DOM是异步的,用 $nextTick ()来确保Dom变化后能调用到_initScroll()方法。调用_initScroll()方法能计算内层ul的高度,当内层ul的高度大于外层wrapper的高度时,可以实现滚动。

此时俩侧可以分别滚动了!

(4) 实现左右联动

原理:我们计算出右侧实时变化的y值,落到哪一个区间,我们就显示那一个区间。首先我们要计算整体区间的一个高度,然后分别计算第一个区间的高度,第二个区间的高度,以此类推。然后将区间数存入一个定义好的数组。当我们在滚动的时候实时拿到y轴的高度,然后对比在哪一个区间,这样我们就会得到一个区间的索引值去对应左侧的菜品类别,最后我们用一个vue的class去绑定高亮文本。

1.定义一个方法在 _initScroll 下面,作为计算高度的方法叫做_calculateHeight () ,再定义一个listHeight:[]数组,存放获取到的每一块foods类的高度。然后通过给每个li 定义类名来供js 选择 从而计算出高度存放到listHeight数组里。

// 通过 方法 计算foods内部每一个块的高度,组成一个数组listHeight。
 // 每个li 定义一个类food-list-hook 通过获取该类 来计算 每一块的高度 存到数组listHeight里
 _calculateHeight (){
 // 获取 li 通过food-list-hook
 let foodList=this.$refs.foodsWrapper.querySelectorAll(".food-list-hook");
 let height=0;// 初始化高度
 this.listHeight.push(height) // 把第一个高度存入数组
 //通过循环foodList下的dom结构,将每一个li的高度依次送入数组
 for(let i = 0 ,l = foodList.length ; i < l ; i++){
 let item=foodList[i]; //每一个item都是刚才获取的food的每一个dom
 height += item.clientHeight; //获取每一个foods内部块的高度
 this.listHeight.push(height) // 将获取的值存放到数组里
 }
 
 }

2.我们获取到区间高度数组后,我们要实时获取到右侧的y值,和左侧的索引值做一个对比,定义一个scrollY变量用来存放实时获取的y值。bs插件为我们提供了一个实时获取y值的方法,我们在初始化this.foodScroll的时候加一个·属性probeType: 3,其作用就是实时获取y值,相当于探针的作用。

goods: [],// goods json 数组
listHeight: [],// 存放 foods 内部的每一块的高度
scrollY:0
this.foodScroll=new BScroll(this.$refs.foodsWrapper,{
 click:true,
 //探针作用,实时监测滚动位置
 probeType: 3
 });

3.我们再添加一个方法this.foodScroll.on('scroll',(pos) => {}),作用是实时滚动的时候把获取到的位置给暴露出来。代码如下。

//结合BScroll的接口使用,监听scroll事件(实时派发的),并获取鼠标坐标,当滚动时能实时暴露出scroll
 this.foodScroll.on("scroll",(pos) =>{ // 回调函数
 //scrollY接收变量 
 this.scrollY=Math.abs(Math.round(pos.y)) //滚动坐标会出现负的,并且是小数,所以需要处理一下,实时取得scrollY
 // console.log(pos.y)
 })

4.定义一个计算属性computed,获取到food滚动区域对应的menu区域的子块的索引i值,从而定位到左侧边栏的位置。

computed:{
 currentIndex (){ //计算到达哪个区域的区间的时候的对应的索引值
 // 利用 listHeight 存放 每一块 对应的高度
 for (let i=0,l=this.listHeight.length; i<l ; i++){
 let menuHeight_fir = this.listHeight[i] // 当前menu 子块区域的 高度
 let menuHeight_sec = this.listHeight[i + 1] // 下一个menu 子块区域的 高度
 // 当滑到底部时,menuHeight_sec 为 underfined,
 // 需要确定滑到俩个高度区间 
 if( !menuHeight_sec || (this.scrollY > menuHeight_fir && this.scrollY < menuHeight_sec) ){
 return i;
 }
 }
 },
 
 }

获取到i后,,然后通过设置一个class来做样式切换变化 :class="{'current':currentIndex === index}" ,当currentIndex和menu-item对应的index相等时,设置current的样式。这样就可以实现左右联动了。

<li v-for='(item,index) in goods' class="menu-item" :class="index === currentIndex?'menu-item-selected':'menu-item'">
...

在样式里提前设好 选中和正常的样式

5.最后实现左侧点击的功能。在左侧的li下绑定一个selectMenu的点击事件,并传入索引值,这样我们就可以知道点击的是哪一个li

<li v-for='(item,index) in goods' class="menu-item" @click="selectMenu(index,$event)" :class="index === currentIndex?'menu-item-selected':'menu-item'">
...
selectMenu (index, event){ // 点击左侧 ,右侧响应
 this.foodScroll.scrollTo(0, -this.listHeight[index], 300)
 }
scrollTo(x, y, time, easing)
//滚动到某个位置,x,y 代表坐标,time 表示动画时间,easing 表示缓动函数
scroll.scrollTo(0, 500)

参考: vue使用 better-scroll的参数和方法

6.关于在selectMenu中点击事件

在selectMenu中点击,在pc界面会出现两次事件,在移动端就只出现一次事件的问题

原因 : better-scroll 会监听事件(例如touchmove,click之类),并且阻止默认事件(prevent stop),并且他只会监听移动端的,pc端的没有监听

在pc页面上 better-scroll 也派发了一次click事件,原生也派发了一次click事件

// better-scroll 的事件,有_constructed: true
MouseEvent {isTrusted: false, _constructed: true, screenX: 0, screenY: 0, clientX: 0…}
//pc的事件
MouseEvent {isTrusted: true, screenX: -1867, screenY: 520, clientX: 53, clientY: 400…}

解决 : 针对better-scroll 的事件,有_constructed: true,所以做处理,return掉非better-scroll 的事件

selectMenu(index, event){
 if (!event._constructed) { //去掉自带的click事件点击,即pc端直接返回
 return;
 }
 let foodList=this.$refs.foodsWrapper.querySelectorAll(".food-list-hook"); // 获得监听元素
 let el = foodList[index]; // 获得 当前 监听元素的高度 
 this.foodScroll.scrollToElement(el, 300); //类似jump to的功能,通过这个方法,跳转到指定的dom
 }

goods 组件到此差不多了!

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

使用原生JavaScript实现放大镜效果

在nodejs中通过redis作为缓存实现的封装缓存类

Vue Socket.io源码详细分析

vue中调用methods的方法

Vue组件通信(详细教程)

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

38

2026.03.10

Kotlin Android模块化架构与组件化开发实践
Kotlin Android模块化架构与组件化开发实践

本专题围绕 Kotlin 在 Android 应用开发中的架构实践展开,重点讲解模块化设计与组件化开发的实现思路。内容包括项目模块拆分策略、公共组件封装、依赖管理优化、路由通信机制以及大型项目的工程化管理方法。通过真实项目案例分析,帮助开发者构建结构清晰、易扩展且维护成本低的 Android 应用架构体系,提升团队协作效率与项目迭代速度。

83

2026.03.09

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

97

2026.03.06

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

223

2026.03.05

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

458

2026.03.04

AI安装教程大全
AI安装教程大全

2026最全AI工具安装教程专题:包含各版本AI绘图、AI视频、智能办公软件的本地化部署手册。全篇零基础友好,附带最新模型下载地址、一键安装脚本及常见报错修复方案。每日更新,收藏这一篇就够了,让AI安装不再报错!

169

2026.03.04

Swift iOS架构设计与MVVM模式实战
Swift iOS架构设计与MVVM模式实战

本专题聚焦 Swift 在 iOS 应用架构设计中的实践,系统讲解 MVVM 模式的核心思想、数据绑定机制、模块拆分策略以及组件化开发方法。内容涵盖网络层封装、状态管理、依赖注入与性能优化技巧。通过完整项目案例,帮助开发者构建结构清晰、可维护性强的 iOS 应用架构体系。

246

2026.03.03

C++高性能网络编程与Reactor模型实践
C++高性能网络编程与Reactor模型实践

本专题围绕 C++ 在高性能网络服务开发中的应用展开,深入讲解 Socket 编程、多路复用机制、Reactor 模型设计原理以及线程池协作策略。内容涵盖 epoll 实现机制、内存管理优化、连接管理策略与高并发场景下的性能调优方法。通过构建高并发网络服务器实战案例,帮助开发者掌握 C++ 在底层系统与网络通信领域的核心技术。

34

2026.03.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Vue 教程
Vue 教程

共42课时 | 9.5万人学习

Vue3.x 工具篇--十天技能课堂
Vue3.x 工具篇--十天技能课堂

共26课时 | 1.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号