Ⅰ
node_modules文件夹:项目依赖
public文件夹:放置静态资源(图片)
注意:放在public文件夹中的静态资源,webpack进行打包时候
会原封不动打包到dist文件夹中
src文件夹(程序员文件夹):
assets:放置静态资源(一般放置多个组件共用的静态资源)
注意:放置在assets里面的静态资源在webpack打包的时候
会把静态资源当作一个模块,打包到JS文件里面
components文件夹:一般放置的是非路由组件(全局组件)
比如:三级联动组件(TypeNav)、轮播图(Carsousel)、分页器(Pagination)
头部导航栏(Header)、页尾(Footer)
App.vue:唯一的根组件,vue当中组件(.vue)
main.js:程序入口文件,也是整个程序最先执行的文件
babel.config.js:配置文件(babel相关)eg.可以把ES6语法翻译成ES5语法
package.json文件:认为是项目“身份证”,记录项目叫做什么,有哪些依赖,项目怎么运行
package-lock.json文件:缓存性文件
README.md:说明性文件
2.1项目运行起来浏览器自动打开
(1)找到package.json文件
在scripts中"serve":"vue-cli-serviceserve--open"
(2)eslint校验工具关闭,它可以检测
在根目录下,创建vue.config.js(已存在就直接添加)
lintOnSave:false
因为:声明变量变量未使用eslint校验工具就报错,因此关闭它
(3)src文件夹简写方式,配置别名,@
一般已配置完毕[@代表的是src文件夹,方便查找]
jsconfig.json配置别名@提示,要不然路径查找输写困难
{
"compilerOptions":{
"baseUrl":'./',
"paths":{
"@/*":["src/*"]
}
},
"exclude":["node_modules","dist"]
}
3.项目路由的分析
vue-router
前端所谓路由:kv键值对,
key:URL(地址栏中的路径)
value:相应路由组件
该项目是上中下结构
路由组件:
home首页路由组件,search路由组件,login登录路由,register注册路由
所以可以把头部和尾部定为非路由组件
非路由组件:(共用header和footer)
Header【在首页,搜索页】
Footer【在首页,搜索页】但是在登录页|注册页没有
1.书写静态页面(HTML+CSS)
2.拆分组件
3.获取服务器的数据动态展示
4.完成相应的动态业务逻辑
注意1:组件结构+组件样式+图片资源
注意2:项目采用的less样式,浏览器不识别less样式,需要通过less、less-loader进行处理
把less样式变为css样式,浏览器才能够识别
注意3:如果让组件识别less样式,需要在style标签的身上加上lang:less属性
使用组件的步骤(非路由组件)
创建与定义
引入
注册
使用
5.路由组件的搭建
共有路由组件四个——vue-router
:Home\Search\Login\Register
-components文件夹:放置的是非路由组件(共用全局组件)
-pages|views文件夹:放置路由组件
5.1配置路由
项目当中配置的路由一般放置在router文件夹中
5.2总结
路由组件与非路由组件的区别?
1.路由组件一般放置在pages|views文件夹中,非路由组件放置在components文件夹中
2.路由组件一般要在router文件夹中进行注册(使用的即为路由的名字),非路由组件一般是以标签的形式调用<header><footer>
$route:一般获取路由信息[路径、query、params等等]
$router:一般进行编程式导航进行路由跳转[push|replace]
3.注册完路由,不管是路由组件,还是非路由组件身上都有$router和$route属性
但是在访问根目录的时候一般要去到首页,所以需要重定向
path:'/',
redirect:需要跳转到的路径
5.3路由的跳转
有两种形式:声明式和编程式
声明式导航router-link,可以进行路由跳转
编程式导航push|replace,可以进行路由导航
编程式导航:声明式导航能做的,编程式导航都能做
编程式导航除了路由跳转也可以实现其他业务逻辑
补充小知识:
push和replace的区别?
router.push(location)会向histroy栈添加一条新的记录,当用户点击浏览器后退按钮时,回到之前的URL
<router-link:to=''>相当于router.push(...字符串路径|描述地址的对象)
eg.
router.push('home')//字符串
this.$router.push({path:'/login?url='+this.$router.path})//对象
router.push({name:'user',params:{userId:123})//命名路由
router.replace(location)
导航是不会留下histroy,替换掉当前的histroy
<router-link:to="..."replace></router-link>
//编程式
router.replace(...)
this.$router.push({
path:'/home',replace:true
})
params:/router1/:id,/router1/123,/router1/789,这里的id叫做params
query:/router1?id=123,/router1?id=456,这里的id叫做query。
6.Footer组件显示与隐藏
显示与隐藏组件使用:v-if(频繁操作DOM)|v-show
Footer组件:在Home,Select显示,在登录、注册时候隐藏
6.1我们可以直接使用v-show='$route.path="url"'来获取当前路由身上的信息,通过路由的路径判断Footer,但是不太方便因为如果一旦网页数量过多那么代码量也会很多
6.2使用路由元信息在router的route里加上meta属性它的返回值是boolean所以可以直接写meta:{show:xxx(boolean)}
路由要的是配置信息,不能随便写参数属性
v-show:$route.meta.show
7路由传参
7.1路由跳转有几种方式
声明式导航:router-linkto属性,可以实现路由的跳转
编程式导航:利用的组件实例$router.push|replace方法,可以实现路由的跳转
8.2路由传参,参数有几种写法
params参数:属于路径当中的一部分,注意,在配置路由的时候需要占位
query参数:不属于路径中的一部分,类似于ajax的queryString
/home?=k=v&kv=,配置路由的时候不需要占位
补充
路由传递参数
- 字符串形式---直接拼接
this.$router.push(‘/search/’+this.keyword+’?k=’+this.keyword.toUpperCase());
- 模板字符串
this.$router.push(`/search/${this.keyword}?k=${this.keyword.toUpperCase()}`)
- 对象--常用
this.$router.push({name:’search’,params:{keyword:this.keyword},query:{k:this.keyword.toUpperCase()}})
//1.题目:路由传参(对象写法)可以path与params结合使用吗
//不可以,只能结合query
//this.$router.push({path:'/search',params:{keyword:this.keyword},query:{k:this.keyword.toUpperCase()}})
//2.题目:如何指定params参数可传可不传
//如何指定params参数可以传递或者不传递,就是在配置路由的时候
//在占位后面加上问号(?),表示可传可不传
//this.$router.push({name:'search',query:{k:this.keyword.toUpperCase()}})
eg.path:'/search/:keyword?'
//3.题目:params可传也不传,但是传过来是空值,如何解决
/因为如果传了空串还是会有路径问题
//使用undefined解决params参数可传可不传的问题(包括空字符串)
//this.$router.push({
//name:"search",
//params:{keyword:""||undefined},
//query:{k:this.keyword.toUpperCase()},
//});
//4.题目:路由组件能不能传递props参数
//可以,有三种写法:
//,query:{k:this.keyword.toUpperCase()}
//this.$router.push({name:'search',params:{keyword:this.keyword||undefined}});
//如果有query参数也不能忽略
props:true,布尔值类型,只用params,可以把params属性作为路由组件中的属性
props:{a:1,b:2}对象类型,给路由多传递一些参数props
props:($route)=>{
return{keyword:$route.params.keyword,k:this.$route.k}
}
函数类型,可以params参数和query参数,通过props传递给路由组件
//路由组件是可以传递props
//props:['keyword','k']
Ⅱ
1.编程式路由跳转到当前路由(参数不变),多次执行会抛出NavigationDuplicated的警告错误
路由跳转有两种形式:
声明式导航和编程式导航
--对于声明式导航没有报错,因为在vue-router已经处理好了
1.1为什么编程式导航就有这个错误
'vue-router':'^3.5.3':最新的vue-router引入promise
functionpush(){
returnnewPromise((resolve,reject)=>{
})
}
回答:通过push方法传递相应的成功、失败的回调函数,可以捕获到当前错误,可以解决
通过底部代码,可以解决问题
this.$router.push({name:'search',params:{keyword:this.keyword},query:{k:this.keyword.toUpperCase()}},()=>{},(error)=>{
console.log(error);
})
但是这种写法治标不治本,其他别的组件中,就是编程式导航中还是会有这个问题,都要使用回调函数获取异常会导致代码高耦合
说明:
this:是当前组件实例(search),
this.$router属性:
属性值@VueRouter类的一个实例,当在入口文件注册路由的时候,已经给组件实例添加$router和$route
push:VueRouter类上的一个实例
functionVueRouter(){}
//这个是原型对象的方法
VueRouter.prototype.push=function(){
//这个函数的上下文为VueRouter类的一个实例
}
let$router=newVueRouter();
$router是VueRouter的一个实例,可以借用原型对象身上的push方法
$router.push(xxx)
治本重写VueRouter身上的push
把VueRouter.push()重写
1.先保存因为我们要继承
2.重写,实例上下文要继承VueRouter
如果有参数就覆盖(resolve,reject),没有就使用默认的添加(这样才不会抛出异常报错,异常都被截取了)
意思就是它会返回promise->会有resolve和reject两种返回表示该路由跳转是否成功或失败
但是我们在实际应用中不管这条数据就会报错
所以在路由配置中重写了push和replace两个方法
首先,保存原本的原型方法
letoriginPush=VueRouter.prototype.push;
letoriginReplace=VueRouter.prototype.replace;
再次,重写push|replace方法
VueRouter.prototype.push=function(location,resolve,reject)
{
//不能直接调用originPush();因为它的上下文是window
//而是要改变它的指向
if(resolve&&reject){
originPush.call(this,location,resolve,reject)
}else{
originPush.call(this,location,()=>{},()=>{}) } }
VueRouter.prototype.replace同上
2.Home模块组件拆分
--先把静态页面完成
--拆分出静态组件
--获取服务器的数据进行展示
--动态业务
3.三级联动组件完成
---由于三级联动,在Home、Search、Detail,把三级联动注册为全局组件。
好处:只需要注册一次,就可以在项目任意地方使用
importTypeNavfrom‘@/components/TypeNav’
Vue.component(TypeNav.name,TypeNav)
4.完成其余静态组件
HTML+CSS+图片资源------信息[结构、样式、图片资源]
5.一般要先测试接口是否能够使用
POSTMAN测试接口
--如果服务器返回code为200表示服务器返回数据成功
--整个项目,接口前缀都有/api的字样
6.axios二次封装
XMLHttpRequest,fetch,JQ,axios
为什么需要二次封装axios
理由:请求拦截器,响应拦截器:请求拦截器可以在发送请求之前可以处理有些业务,响应拦截器当服务器返回之后做一些业务
1.首先要引入inportaxiosfrom‘axios’
- request就是axios,只是可以进行配置
constrequests=axios.create({
//配置对象,像是基础路径baseURL或请求超时的时间设置timeout
})
- 配置请求拦截器
requests.interceptors.request.use((config)=>{
returnconfig;
})
requests.interceptors.response.use((res)=>{
returnres.data;
}),
(error)=>{
//响应失败的回调函数
returnPromise.reject(newError(‘faile’))
}
6.2在项目中出现的API文件夹【axios】
接口当中路径都带有/api
baseURL:'/api'(就是基础路径)
7.接口统一管理
如果项目很小:可以在组件的生命周期函数中发请求
如果项目很大:axios.get('xxx');
7.1跨域问题
跨域:协议、域名、端口号相同
如有一个不同就 违背同源策略
http://localhost:8080/#/home---前端项目本地服务器
http://39.98.123.211---后台服务器
解决跨域的几个方法:
JSONP\CORS\代理 补充:document.domain 只能跨子域,需要主域相同才能使用
location.hash+iframe
window.name+iframe
postMessage
nginx代理跨域
CORS分为简单请求和非简单请求
简单请求,浏览器自动添加一个Origin字段
同时后端要给响应头 允许跨域
response.setHeader(‘Access-Control-Allow-Origin);
服务端响应头想要被浏览器允许接收生效
reponse.setHeader(‘Access-Control-Exponse-Headers)
Access-Control-Allow-Credentials 是否可传cookie
要是想传cookie,在前端需要设置xhr.withCredentials=true,后端设置Access-Control-Allow-Credentials
———————————————————————————————————————
在webpack中DevServer.proxy---webpack.config.js(即vue.config.js)
devServer:{
proxy:{
“/api”:{
target:’服务器url’,
changeOrigin:true,
pathRewrite:{ "^/api": ""}}}}
8.nprogress进度条的使用
发请求进度条执行,响应之后取消进度条
安装nprogress插件
cnpm install--savenprogress
要在api/request.js中添加,因为是在发请求之前和响应之前做的事情,所以在拦截器中使用
1.首先引入 import nProgress from “nprogress” start:进度条开始 done:进度条结束
2.添加样式,即nprogress/nprogress.css中可以直接修改
3.在拦截器中添加方法
start:进度条开始
done:进度条结束
9.vuex状态管理库
9.1vuex是官方提供的一个插件,状态管理库,集中式管理项目中组件共用的数据:
不是所有项目都需要vuex,如果项目很大,组件很多,数据维护很费劲,vuex
state,mutations,getters,actions,modules
9.2vuex基本使用
9.3vuex实现模块式开发
当项目过大,组件过多,接口也很多,数据很多
可以让vuex实现模块式开发
模块式开发,从小仓库中引入数据,每个小仓库负责对应的数据
export default new Vuex.Store({
modules:{
home,
search,
}
})
10.动态展示三级联动
全局组件应该放到components中,并修改在main.js中的路径
知识点1:查找数据需要服务器+接口
所以在配置基础路径的时候baseURL,需要
http://gmall-h5-api.atguigu.cn(这是服务器)|
/api/product/getBaseCategoryList(这是接口)
接口放在服务器后面
最终拼接路径是http://gmall-h5-api.atguigu.cn/api/product/getBaseCategoryList
所以在baseURL:http://gmall-h5-api.atguigu.cn/api(这是服务器+/api)
建vuex库去发ajax请求
- 在store文件夹下,新建search文件夹中index,js文件
- 初始化仓库,就是state,mucations,actions,gettters,再对外暴露
- 拉接口,三连环,在actions发请求,因为会返回promise所以使用async和await接
大致代码:
//通过API里的接口函数调用,向服务器发请求,获取服务器的数据
const state={
//注意服务器返回的是一个数组,所以数据默认初始化不能随便写,返回是对象就初始对象,返回是数组就初始数组
categoryList:[],},
const mutations={
CATEGORYLIST(state,categoryList)
{
CATEGORYLIST(state,categoryList){
state.categoryList=categoryList;
}
}},
const actions={
async categoryList({commit}){
let result=await reqCategoryList();
if(result.code==200)
{
commit(‘CATEGORYLIST’,result.data);}}
}
当然也是需要挂载在钩子上,但是为了避免重复挂载所以在源组件中
this.$route.dispatch(“categoryList”)
知识点2:在v-for循环中第一个是值,第二是键,第三个索引
所以可以选择性循环,当然不能丢了:key=值的属性,
选择性用v-if='index<=多少',就输出多少内容
一级分类中有二级分类,二级分类有三级分类
[
{
id:1,
name:'电子书',
child:[
{
id:2,
name:'很多书',
child:[{},{}]
},{
id:3,
name:'非常多的书'
child:[{},{}]
}
]
},{},{}
]
Ⅲ
如何实现三级列表显示?
1.完成一级分类动态添加背景颜色
第一种解决方案:采用样式完成
第二种解决方案:
(1)因为v-for(c1,index) in categpryList,c1是值,index是键值,
(2)所以我们可以监听mouseenter获取index后(@mouseenter='changeIndex(index)'),去添加方法进行处理
methods:{
//鼠标进入从修改响应式数据currentIndex数据
//changeIndex(index){
//知识点:
正常情况:鼠标缓慢进入一级分类中都会触发
但是会出现另一种不正常情况:经过测试,只有部分触发了样式,是由于用户行为过快,导致浏览器反应捕获,回调函数中一大堆事件,浏览器根本反应不过来,就会让浏览器卡顿
所以不能直接赋值
//this.currentIndex=index;
_.throttle(是全部引入),因为他是默认暴露就不需要_.
throttle回调函数别用箭头函数,可能出现上下文this
changeIndex:throttle(function(index){
this.currentIndex=index;
},50),
}
}
,值就是放在
data(){
return {
currentIndex:-1,
}
}
(3)当index==currentIndex(判断)时,添加样式
使用:class={cur:currentIndex==index},在css添加样式cur
(4)把移除事件挂载到父盒子上去监听,就是事件委派|事件委托(真正监听的是这个委托监听的子元素)
leaveShow(){
this.currentIndex=-1;
}
2.通过JS控制二三级商品分类的显示与隐藏
最开始的时候,是通过CSS样式display:block|none显示与隐藏二三级商品分类
所以当currentIndex==index时候显示分类页面
用:style=''控制显示
:style="{display:currentIndex==index?'block':'none'}"
3.显示卡顿现象
正常:事件触发非常频繁,每次触发都要执行回调函数(如果时间很短,且回调函数内部有计算,就可能出现浏览器卡顿)
节流:在规定的间隔时间范围内不会重复触发回调,只有大于时间间隔才会触发,把频繁触发变为少量触发(回血量,技能点)
防抖:前面的所有触发都被取消,最后一次执行在规定时间之后才会触发,如果连续快速触发,只会执行一次(回城)
(向服务器去发送请求)
下载lodash插件:里面封装的防抖与节流的业务(闭包+延迟器)
//1.lodash函数库对外暴露_函数
下划线函数
let result=_.debounce(function(){
console.log('我在一秒之后执行一次')
},1000)
result;
eg.是回调函数,前面所有的触发都会被取消(因为会被覆盖),当结束输入后1s才执行事件
input.οninput=_.debounce(function(){
},1000);
会返回一个函数
节流,计数器
eg.
button.οnclick=_.throttle(function(){
count++;
span.innerHTML=count;
},1000)
//防抖:用户操作很频繁,但是只能执行一次
//节流:用户操作很频繁,但是把频繁操作变成少量操作,给浏览器给予充裕的事件进行解析代码
完成三级联动节流的操作
且vuex本身就有lodash插件
4.三级联动组件的路由跳转与传递参数
三级联动用户可以点击的:一级分类、二级分类、三级分类,当点击时Home模块跳转到Search模块,一级会把用户选中的产品(产品的名字,产品ID),路由跳转的时候,进行传递。
路由跳转:
声明式导航:router-link
编程式导航:push|replace
三级联动,如果使用声明式导航router-link,可以实现路由跳转传递路由参数,但是会造成卡顿的现象。
router-link:当作一个组件使用,当服务器数值返回,循环很多router-link组件,就会创建很多实例1000+,一瞬间创建很耗内存,会出现卡顿现象。
使用@click监听绑定事件也不是最优解,因为每一个a标签都要绑定一个回调
最优解是使用:
编程式导航+事件委派
但是怎么查找到点击的是a标签
如何获取参数
5.完成三级联动路由跳转与传递参数
【1】首先如何解决事件委派时到底是哪个元素进行的点击,即点击a标签时,怎么确定是哪个目标a
【2】其次,当能够确定点击标签,到底是哪一层级标签进行了点击
解决1:
因为是根据点击a标签进行跳转,所以给每一个a标签一个自定义属性,就能够确定点击的是否是a标签
实际解决方案:把子节点当中的a标签都加上自定义属性data-categoryName,其余子节点没有
解决2:
使用event.target得到点击对象,并在每个a标签上再自定义一个属性来确定到底是哪层级别(自定义属性名)不一致
实际解决方案:使用event.target可以获取到当前触发事件的节点
然后用{}来解构,{属性名1,属性名2,属性名3,属性名4}=element.dataset;dataset可以得到自定义属性名
if(属性名1)
{
if(属性名1){}else if(属性名2){}...
}
最后是跳转路径怎么写
this.$router.push({name:"search",query:{categoryName:'xxx',2id:'xxx'}})
实际解决总结:
- 在ul上添加监听事件,因为事件委派的原理可以向下委派
- 再获取当前点击的触发事件节点
let element=event.target;
解构点击节点身上的自定义属性
注意浏览器会把所有大写的子图改成小写所以解构中的变量也要是小写
dataset是取出标签自定义属性
let { categoryname, category1id, category2id, category3id } =element.dataset;
- 如果存在当前categoryname属性判断是哪一级别的
if(categoryname)
{
//无论是1,2,3级都要整理路由跳转的参数,所以开始整理获取的数据
let location={name:”search”}//跳转路径
let query={categoryName:categoryname}
if (category1id) {
query.category1Id = category1id;
} else if (category2id) {
query.category2Id = category2id;
} else if (category3id) {
query.category3Id = category3id;
}
//判断跳转的时候是否带有params参数,携带了也传递进行
if(this.$route.params)
{
location.params=this.$route.params;
location.query=query;
this.$router.push(location);
}
}
Ⅳ
复习:
1.商品分类三级列表静态变为动态形式【获取服务器数据:解决跨域问题】 jsonp\CORS\插件 package中直接配置vue.config.js devServer proxy
2.函数防抖与节流[重要]
3.路由跳转:声明式导航、编程式导航
使用编程式导航,为什么
由于声明式导航是个组件router-link,一旦使用要生成很多组件很耗内存,卡顿
编程式导航:采用事件委派
自定义属性 dataset event.target
4.开发search模块中Typenav商品分类菜单(过渡动画效果)
过渡动画:前提组件|元素务必有v-if|v-show指令才可以进行过渡动画——transition标签
[1]首先把全局组件Typenav添加到search上,因为已经在main.js中定义为全局组件,所以直接使用
[2]如何让三级列表在首页显示,而在search不经过就隐藏呢?
第一,先在三级联动中添加v-show功能,并在data中存储初始状态为true
因为标题是显示的所以挂载dd标签上
第二,mounted挂载钩子中,判断所在路径,如果是首页显示不是就隐藏
this.$route.path 这表示的是一开始的隐藏或显示
第三,添加经过和离开三级联动显示隐藏的方法,mouseenter还是mouseleave用show
因为事件委派的原理,所以把监听事件添加在父盒子上
@mouseleave-->leaveShow @mouseenter-->enterShow
leaveShow(){
//判断如果是search路由组件的时候才会执行
if(this.$route.path!==”/home”)
{this.show=false;}}
//当鼠标移入的时候让商品列表显示
enterShow(){
if(this.$route.psth!==”/home”){
this.show=true;
}}
第四,添加过渡动画。transition包裹三级联动列表,并以name定义name='sort'
有了name就不用v-来定义
.sort-enter{} .sort-enter-to{}
.sort-leave{} .sort-leave-to{}
定义动画的时间
.sort-enter-active{transition:all .3s linear !important;}注意层级问题
三级列表优化?
主要是减少发送请求的次数,把挂载在三级列表中发送请求的方法挂载到App.vue中,因为只会渲染一次App根组件,所以其实也只要发送其次请求获取参数就可以了
5.合并参数
为了满足两种情况
【1】点击完三级联动后又在查找框中查找具体内容
【2】先查找内容后点击三级联动
要满足params和query都能获取
所以在三级联动和搜索框跳转时先去判断是否有params和query然后把已有的添加进去再进行跳转
6.开发Home首页中ListContainer组件与Floor组件
但是没有提供
使用mock数据(模拟)
需要用到一个插件mockjs
(它的作用:提供假数据,拦截ajax)
mockjs使用步骤
1.在src中添加一个文件夹mock
2.准备json数据(在mock文件夹中创建相应的JSON文件)
使用的数据一定要格式化后,不能有空格
3.把mock数据需要的图片放置到public文件夹中
public文件夹打包时,会把相应的资源原封不动打包到dist文件夹中
4.开始mock虚拟数据,通过mockjs实现
创建mockServe.js通过mockjs插件实现模拟数据(Mock.mock(url请求地址,参数请求数据))
var Mock=require(‘mockjs’);
//JSON数据需要被引入,因为JSON未对外暴露,但是可以引入
//webpack默认对外暴露的有:图片、JSON数据格式
import banner from ‘./banner.json’;
//mock数据,第一季是参数请求地址 第二个参数是请求数据
Mock.mock(“/mock/banner”,{code:200,data:banner});//这是首页轮播图的数据
5.mockServe.js文件在入口文件中引入(至少需要执行一次,才能模拟数据)
import mock from '@/mock/mockServe'
把所需的资源获取遍历
【1】拷贝一份改变请求基础路径配置是/mock,并配置发送请求的基本信息
【2】在轮播图页面发送请求向仓库获取资源,仓库去请求虚拟数据并备份
export default reqGetBannerList=()=>mockRequests.get(‘/banner’);
【3】轮播图页面引入仓库mapState得到相应的资源state.home.bannerList
7.swiper基本使用(适用于轮播图)PC端移动端都适用
【1】引包(相应JS|CSS)
【2】页面中结构务必要有
【3】在以上前提下:new Swiper实例,轮播图添加动态效果
8.安装ListContainer组件开发重点?
安装swiper插件:最新版本6,安装的是swiper5
npm install --save swiper@5
如果直接在mounted实例化swiper实例,由于当前仓库还未进行修改轮播图数据所以不能实现,因为DOM中根本还没渲染完成,而new Swiper的实例前提是页面结构完整,就是要考虑页面异步渲染
!!!注意:swiper5以上版本vue2不兼容(用不了),所以下载cnpm来下载swiper5,因为npm也下载不了swiper5及以下版本
1.引包,在入口文件中引入CSS样式
//轮播图样式插件,样式不需要a from b,直接引入即可
import 'swiper/css/swiper.css'
- 在需要使用的组件中引入JS文件
import Swiper from “swiper”
- 引入相关的结构
<div class="swiper-container col_329" ref="floorSwiper">
//轮播图的骨架
<a href="#" class="swiper-wrapper">
//每一张轮播图片