尚品汇VUE项目实战知识点总结

Vue尚硅谷项目

一个模块组件的实现流程:
1.存储数据,存储于vuex
2.书写静态页面
3.拆分组件
4.获取服务器数据
5.展示数据
6.开发动态业务

1. 脚手架目录
  • Public:一般放置静态资源(图片)
  • Src:程序员的代码文件
  • Assets:文件夹里面的资源会webpack会打包成一个模块放进js文件夹里面
  • components:一般放置非路由组件(或者项目共用的组件)
  • Pages:放路由组件
  • App.vue 唯一的根组件
  • main.js 入口文件【程序最先执行的文件】
  • babel.config.js:babel配置文件
  • package.json:看到项目描述、项目依赖、项目运行指令
  • README.md:项目说明文件
2.src文件夹的别名的设置

设置src文件夹的别名的好处,找文件会方便一些
创建jsconfig.json文件

{
    "compilerOptions": {
        "baseUrl": "./",
        "paths": {
            "@/*": [
                "src/*"
            ]
        }
    },
    "exclude": [
        "node_modules",
        "dist"
    ]
}
3.路由组件的配置

a.前后台区别:
后台而言:
K即为URL地址(网络资源定位符)
V即为相应的中间件
http://localhost:8080/0607

app.get("/0607",(res,req)=>{
   res.send('我是祖国的老花骨朵');
});

前端路由:
K即为URL(网络资源定位符)
V即为相应的路由组件

b.商品汇前端页面:SPA页面的核心

  • 路由组件:一般是固定在那里(Home、Search、Login)
    • 1.创建路由组件【一般放在views|pages文件夹】
    • 2.配置路由,配置完四个路由组件router文件夹中
// 配置路由的地方
import Vue from 'vue'
import VueRouter from 'vue-router'

// 使用路由插件
Vue.use(VueRouter)

// 引入路由组建
import Home from '@/pages/Home'
import Login from '../pages/Login'

// 配置路由
export default new VueRouter({
    // 配置路由
    routes:[
        {
            path:"/home",
            component:Home,
            meta:{
                show:true
            }
        },
  • 非路由组件:进行页面的切换((Header 、Footer)(components文件夹中)
    • 1.全局组件(main页面进行全局注册)
      - 组件name属性的作用?
      1.开发者工具中可以看见组件的名字
      2.注册全局组件的时候,可以通过组件实例获取相应组件的名字
    • 2.非全局组件
    • 非路由组件使用分为几步:
      - 第一步:定义
      - 第二步:引入
      - 第三步:注册
      - 第四步:使用

c.路由组件的结构的搭建:

  • 1.结构 + 样式 +图片资源
  • 2.相应位置放入对应组件标签

d.路由的跳转

  • 路由的跳转就两种形式:声明式导航(router-link:务必要有to属性)
    编程式导航push||replace
  • 编程式导航更好用:因为可以书写自己的业务逻
  • $router:进行编程式导航的路由跳转
    • this. r o u t e r . p u s h ∣ t h i s . router.push|this. router.pushthis.router.replace
    • $route:可以获取路由的信息|参数
    • this.$route.path
    • this.$route.params|query
    • this.$route.meta

e.路由传参

  • params参数:路由需要占位,程序就崩了,属于URL当中一部分?keyword
  • query参数:路由不需要占位,写法类似于ajax当中query参数
    小问题:

1)编程式导航路由跳转到当前路由(参数不变), 多次执行会抛出NavigationDuplicated的警告错误?
注意:编程式导航(push|replace)才会有这种情况的异常,声明式导航是没有这种问题,因为声明式导航内部已经解决这种问题。
这种异常,对于程序没有任何影响的。
为什么会出现这种现象:
由于vue-router最新版本3.5.2,引入了promise,当传递参数多次且重复,会抛出异常,因此出现上面现象,
第一种解决方案:是给push函数,传入相应的成功的回调与失败的回调
第一种解决方案可以暂时解决当前问题,但是以后再用push|replace还是会出现类似现象,因此我们需要重新写(重新配置push和replace方法)

1:重写push与replace方法
工作的时候想处理掉,不想处理对于你的程序没有任何影响
function push(){
    return new Promise(resolve,reject){

    }
}

d+e路由的跳转与传参

1.第一种声明式导航:为什么使用router-link组件的时候,会出现卡顿那?
router-link是一个组件:相当于VueComponent类的实例对象,一瞬间
new VueComponent很多实例(1000+),很消耗内存,因此导致卡顿。
{{ c1.categoryName }}

2.第二种编程式导航:push|replace

三级分类由于使用router-link的时候,会出现卡顿现象,因此采用编程式导航。
因为是有很多的级联,v-for循环得到的,因此在循环过程中,回调函数也会依次增加
优化:编程式导航+事件委派的冒泡原理将绑定一个回调函数,则会相应的隐射到每一个子节点

路由跳转的时候【home->search】:需要进行路由传递参数【分类的名字、一、二、三级分类的id】

this.$router.push()
{
 name:'search',
 query:{
    categoryName:'电子书',
    category2Id:4
 }
}
// 三级联动路由跳转和传递参数的业务
    goSearch(event) {
      // alert(444)
      // 问题1:如何判断点击子节点的是A标签
      // 答:把子节点当中的a标签,加上自定义的属性,其余子节点是没有的(自定义属性:浏览器会将驼峰命名转换为一般的命名)
      // 问题2:如何判断是几级的目录?
      // 答:也是根据自定义属性加上的自身的ID值进行条件判断
      // 问题3:如何获取当前的事件 答:event

      // event.target :获取到的是触发事件的元素(h3,a,dt,dl)
      let node = event.target;
      // 节点有一个属性dataset属性,可以获取自定义属性与属性值 (这里一定要小写,不是给你说了么,浏览器会将自定义属性变为全部小写)
      let { categoryname, category1id, category2id, category3id } =
        node.dataset;
      console.log(event);
      // 当这个标签是A标签的时候才会进入判断
      if (categoryname) {
        /*         {
        name:'search',
        query:{
            categoryName:'电子书',
            category2Id:4
        } */
        // 准备路由跳转的参数 设置对象
        let location = { name: "search" };
        let query = { categoryname: categoryname };
        // 一级目录
        if (category1id) {
          query.category1id = category1id;
        } else if (category2id) {
          query.category2Id = category2id;
        } else {
          query.category3id = category3id;
        }

        // 路由跳转前要合并参数
        // 1.判断路由中是否有params参数,有则进行合并
        if (this.$route.params) {
          // 动态的给location添加params属性
          location.params = this.$route.params;
          // 动态的给location添加query属性
          location.query = query;
        }
        this.$router.push(location);
      }
    },
4.Vuex:

以前基础课程的时候,发请求操作如下:在组件的mounted中书写axios.get||post,获取到数据存储到组件的data当中进行使用

  • mounted:模板已经变为真是DOM【只不过没有数据,显示空白】,因为ajax是异步,需要时间的。
  • created:稍微好那么一丢丢(不算啥)
    现在:
  • vuex:Vue官方提供的一个插件,插件可以管理项目共用数据。
  • vuex:项目大的时候,需要有一个地方‘统一小仓库中请求数据,管理数据’即为仓库store
  • Vuex核心概念:state、actions、mutations、getters、modules(三连环)
  • state
  • actions
  • mutations
  • getters
  • modules
5.一级分类的背景效果

第一种解决方案:CSS hover 怎么简单怎么来
第二种解决方案:JS逻辑解决 20集尚硅谷完成三级联动动态背景颜色

6.完成动态展示2|3联动结构

最开始是通过css的display:none 和display block来进行显示和隐藏
JS方法::style="{display:currentIndex == index?‘block’:‘none’}"动态绑定样式

7.搜索模块中的三级联动与过渡动画

在home模块当中,使用了一个功能三级联动功能---->[typeNav]
在search模块当中,也使用三级联动的功能------->[typeNav]

a.TypeNav组件业务分析?

  • 三级联动在home模块正常显示
  • 三级联动在search一会显示、一会隐藏 —解决方案:通过一个响应式属性控制三级联动显示与隐藏
    b.问题1
    开发的时候的出现问题:在home模块下不应该出现显示与隐藏的效果
  • 现在这个问题【三级联动:本身在search模块应该有显示与隐藏的业务】 ,但是在home模块下不应该出现显示与隐藏的业务
    说白了:你需要让三级联动组件知道谁在用它。
  • 通过$route让组件区分在那个模块下
    以后在功的时候,如果出现某一个组件要区分当前在哪一个模块中【home、search】

c.解决办法
1.TypeNav组件添加v-show进行动态绑定
2.data方法中设置 show的初始值
3.通过$route路由信息区分

    // 当鼠标移入时,全部商品分类列表进行展示
    enterShow() {
      if (this.$route.path != "/home") {
        this.show = true;
      }
    },
    // 当鼠标离开的时候,全部商品类别进行影藏
    leaveShow() {
      if (this.$route.path != "/home") {
        this.show = false;
      }
  • 路由跳转的时候,相应的组件会把重新销毁与创建----【kepp-alive】

d.过渡效果

  • 最早接触的时候:CSS3
  • Vue当中也有过渡动画效果—transition内置组件完成
 HTML<transition name="sort"> 相应的节点和组件</transition>
 CSS// 过渡动画的样式
    // 开始进入状态
    .sort-enter {
      height: 0;
    }
    // 结束状态
    .sort-enter-to {
      height: 461px;
    }
    // 定义动画的时间和速率
    .sort-enter-active {
      transition: all 0.5s linear;
    }
  • 注意1,在Vue当中,你可以给 (某一个节点)|(某一个组件)添加过渡动画效果
  • 节点|组件务必出现v-if|v-show指令才可以使用。
    e.TypeNav三级联动性能优化?
    项目:home切换到search或者search切换到home,组件在频繁的向服务器发请求,获取三级联动的数据进行展示。
    项目中如果频繁的向服务器发请求,很好性能的,因此咱们需要进行优化。

为什么会频繁的向服务器发请求获取三级联动的数据那?
三级联动的数据是全局组件,使用的组件中进行跳转,因为路由跳转的时候,组件会进行销毁的【home组件的created:在向vuex派发action,因此频繁的获取三级联动的数据】
只需要发一次请求,获取到三级联动的数据即可,不需要多次。
最终解决方案:在App中的moutend只会执行一次
main虽然也是执行一次,但是它不是组件,没有this,组件才有$store属性

8.合并参数

进入搜索页面的时候需要传递各种的参数,从而才能向服务器发请求获得相应的数据
1)合并参数*****
为什么需要合并参数(query|params):因为这些参数,对于search是有用的,因为search通过这些参数
向服务器发请求,需要把这些参数携带给服务器,服务器就会返回相应的用户的搜索的数据,search就可以进行展示。

1.1:开发的三级联动业务,当你点击a标签的时候,会进行路由的跳转,将产品的名字与id传递给search模块----(query)
1.2:点击搜索按钮的时候,用户输入进来的关键字,点击按钮的时候会通过params参数传递给search模块-----(params)
1.3路由跳转(home->search),两个地方,三级联动(typeNav)、Header组件(搜索按钮)

 // 路由跳转前要合并参数
        // 1.判断路由中是否有params参数,有则进行合并
        if (this.$route.params) {
          // 动态的给location添加params属性
          location.params = this.$route.params;
          // 动态的给location添加query属性
          location.query = query;
        }
        this.$router.push(location);
      }
9.mock数据

作用:生成随机数据,拦截 Ajax 请求:
拦截ajax请求:请求发布出去【浏览器会进行拦截:笨想,因为服务器】,只是项目当中本地自己玩耍数据。
对于项目而言:真实的接口 /api/xxxx 模拟的数据/mock/xxxx
模拟数据JSON:没有空格,最好使用格式化插件进行格式化。
注意:
mock(模拟数据)数据需要使用到mockjs模块,可以帮助我们模拟数据。
mockjs【并非mock.js mock-js】
http://mockjs.com/ 官方地址
模拟的数据一般:对象、数组
{
‘a|1-10’:‘我爱你’
}
使用步骤:

第一步:安装依赖包mockjs

第二部:在src文件夹下创建一个文件夹,文件夹mock文件夹。

第三步:准备模拟的数据
把mock数据需要的图片放置于public文件夹中!public文件夹会将相应的资源原封不动的打包到dist文件夹中
比如:listContainer中的轮播图的数据
[
{id:1,imgUrl:‘xxxxxxxxx’},
{id:2,imgUrl:‘xxxxxxxxx’},
{id:3,imgUrl:‘xxxxxxxxx’},
]
第四步:在mock文件夹中创建一个server.js文件
注意:在server.js文件当中对于banner.json||floor.json的数据没有暴露,但是可以在server模块中使用。
对于webpack当中一些模块:图片、json,不需要对外暴露,因为默认就是对外暴露。

第五步:通过mock模块模拟出数据

通过Mock.mock方法进行模拟数据

mock->servers:
// 这里使用mock模拟数据
// 1.引入mock
import Mock from 'mockjs'
// 2.把json数据引入进来  JSON数据不需要暴露
// webpack默认对外暴露:JSON 图片
import banner from './banner.json'
import floor from './floor.json'

// 3.mock数据:第一个请求数据是地址地址一定要写对 第二个参数:请求数据
Mock.mock("/mock/banner",{code:200,data:banner}) //模拟首页轮播图的数据
Mock.mock("/mock/floor",{code:200,data:floor})

第六步:回到入口main文件,引入serve.js
mock需要的数据|相关mock代码页书写完毕,关于mock当中serve.js需要执行一次,
如果不执行,和你没有书写一样的。

// 引入mockServe.js
import "@/mock/mockServe"

第七步:在API文件夹中创建mockRequest【axios实例:baseURL:‘/mock’】
专门获取模拟数据用的axios实例。

api->mockAjax(mock对应axios的二次封装)
const requests = axios.create({
    // create里面可以传配置对象

    // 配置对象
    // 基础路径:baseURL就是给每个请求的路径上自动加上所配置的,就不用自己再去书写
    baseURL: '/mock', //基础路径更改即可
    // 请求超时的时间
    timeout: 5000
})

api->index(// 这个文件进行统一的API管理)
//获取floor的数据/floor后台接口路径
export const reqGetFloor = ()=>mockrequest.get('/floor')

// 获取search的数据   这个函数需要不需要外部传递的参数?要给服务器带参进行params给服务器传递参数 调这个函数得有相应的参数     错错错需要接收home页传递过来的params数据和query数据/api/list
// 当前这个接口。给服务器发请求的时候,至少得是一个空对象
export const reqGetSearchInfo = (params)=>requests({

在开发项目的时候:切记,单元测试,某一个功能完毕,一定要测试是否OK

10.swiper基本的使用?

常用的场景即为轮播图----【carousel:轮播图】,swiper移动端可以使用,pc端也可以使用。

Swiper使用步骤:

  • swiper安装到项目当中
  • 第一步:相应组件引入依赖包【swiper.js|swiper.css】
  • 第二步:静态页面中结构必须完整【container、wrap、slider】,类名不能瞎写
  • (初始化swiper实例之前,页面中的节点(结构)务必要有)
  • 第三步:初始化swiper实例
import Swiper from "swiper"

注意!

  • home模块很多组件都使用到swiper.css,没必要在每一个组件内部都引入样式一次,
    只需要在入口文件引入一次即可。
// 引入swiper样式
import "swiper/css/swiper.css"

1.初始化swiper实例在哪里书写?

  • 对于Vue一个组件而言,mounted[组件挂载完毕:相应的结构不就有了吗]
    mounted–>组件挂载完毕

2.动态效果为什么没有出来?

  • Swiper需要获取到轮播图的节点DOM,才能给swiper轮播添加动态效果,
    因为没有获取到节点。

3.第一种解决方案,延迟器(不是完美的解决方案)
created里面:created执行与mounted执行,时间差可能2ms,白扯
updated里面:如果组件有很多响应式(data),只要有一个属性值发生变化updated还会再次执行,再次初始化实例。

总结:第一种解决方案可以通过延迟器(异步)去解决问题,
但是这种解决方案存在风险(无法确定用户请求到底需要多长时间),因此没办法确定
延迟器时间。

4.Swiper在Vue项目中使用完美解决方案

  • 第一种解决方案问题出现在哪里:v-for,在遍历来自于Vuex(数据:通过ajax向服务器发请求,存在异步)

  • watch:监听属性,watch可以检测到属性值的变化,当属性值发生变化的时候,可以出发一次。

  • Vuex当中的仓库数据bannerList(组件在使用):
    bannerList仓库数据有没有发生过变化?
    一定是有的:bannerList初始值空数组,当服务器的数据返回以后,它的bannerList存储的属性值会发生变化【变为服务器返回的数据】
    组件实例在使用仓库中的bannerList,组件的这个属性bannerList一定是发生过变化,watch可以监听到。
    但是直接在watch里面写也是不可以的!
    原因:1.此时只是有数据,但是v-for的遍历也是需要时间的遍历数据渲染结构的(没法保证v-for的遍历完成)

组件实例的一个方法:$nextTick + watch
this.$nextTick(()=>{

})

5.nextTick官网解释:
在下次DOM更新, 循环结束之后,执行延迟回调。在 修改数据之后 立即使用这个方法,获取更新后的DOM。
作用:可以保证页面的结构是一定有的。(DOM已经全部存在)
注意:组件实例的$nextTick方法,在工作当中经常使用,经常结合第三方插件使用,获取更新后的DOM节点

11.开发Floor组件(组件之间的通信)

开发Floor组件:Floor组件它被复用的(重复使用两次)

1.Floor组件获取mock数据,发请求的action书写在哪里?

答:派发action应该是在父组件的组件挂载完毕生命周期函数中书写,因为父组件需要通知Vuex发请求,父组件获取到mock数据,通过v-for遍历 生成多个floor组件,因此达到复用作用。
2.父组件派发action,通知Vuex发请求,Home父组件获取仓库的数据,通过v-for遍历出多个Floor组件
3.v-for|v-show|v-if|这些指令可以在自定义标签(组件)的身上使用
4.为什么在Floor组件的mounted中初始化SWiper实例轮播图可以使用.
答:因为父组件的mounted发请求获取Floor组件,当父组件的mounted执行的时候。
Floor组件结构可能没有完整,但是服务器的数据回来以后Floor组件结构就一定是完成的了,因此v-for在遍历来自于服务器的数据,如果服务器的数据有了,Floor结构一定的完整的。
否则,你都看不见Floor组件

12.carousel全局组件(全局组件的拆分,父子之间的通信)

如果项目当中出现类似的功能,且重复利用,封装为全局组件----【不封装也可以】
为了封装全局的轮播图组件:让Floor与listContainer组件中的代码一样,如果一样完全可以独立出来封装为一个全局组件。
此时的floor和新的carousel全局组件也存在父子之间的组件之间的通信

  • 0
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值