• 【Vue2】VantUI项目入门教程


    1、安装VantUI及项目中测试Vant组件

    1.1 安装VantUI

    官网地址: https://vant-contrib.gitee.io/vant/#/zh-CN/
    项目目录下安装vant:

    npm i vant@2
    
    • 1

    1.2 项目中使用Vant组件

    在views/Home.vue的script标签中:

    import Vue from 'vue';
    import { Button } from 'vant';
    import 'vant/lib/button/style';
    Vue.use(Button);
    
    • 1
    • 2
    • 3
    • 4

    在views/Home.vue的template标签中:

    <div class="home">
        <van-button type="primary">主要按钮van-button>
    div>
    
    • 1
    • 2
    • 3

    1.3 优化Vant的在项目的目录使用

    将来在页面中会用到很多vant组件,所以把引入工作单独抽离在src/vantui中的index.js中:

    import Vue from 'vue';
    import { Button } from 'vant';
    import 'vant/lib/button/style';
    Vue.use(Button);
    
    • 1
    • 2
    • 3
    • 4

    在src/main.js中:

    import "@/vantui"
    
    • 1

    1.4 设置自动按需引入

    项目目录下安装插件:

    npm i babel-plugin-import 
    
    • 1

    安装完成后,打开 babel.config.js 写入:

    module.exports = {
      presets: [
        '@vue/cli-plugin-babel/preset'
      ],
      plugins: [
        ['import', {
          libraryName: 'vant',
          libraryDirectory: 'es',
          style: true
        }, 'vant']
      ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    删除vantui.index.js中的:

    import 'vant/lib/button/style';
    
    • 1

    重启服务器,查看页面样式效果

    1.5 搜索框的引入使用

    search组件: https://vant-contrib.gitee.io/vant/#/zh-CN/search
    vantui/index.js中

    import { Button,Search } from 'vant';
    Vue.use(Search);
    
    • 1
    • 2

    views/Home.vue中

    <template>
      <div class="home">
        <van-search v-model="searchVal" disable placeholder="请输入搜索关键词" />
      div>
    template>
    <script>
    export default {
      name: 'Home',
      data() {
        return {
          searchVal: ''
        };
      },
      components: {
      }
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    2、样式配置调整

    2.1 背景颜色设置

    页面背景颜色为:#efefef
    App.vue中:

    <style lang="less">
    #app {
      font-family: Avenir, Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      min-height: 100%;
      background-color: #efefef;
    }
    html,body{
      height: 100%;
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2.2 rem单位换算

    App.vue的样式中:

    html{
      font-size: 100px;  
    }
    
    • 1
    • 2
    • 3

    问:如果此时要设置字体为16px, 需要写成多少rem?
    此时1个rem为100px,?rem/1rem = 16px/100px 需要写成 .16rem

    2.3 样式清除工作

    app中添加字体大小样式:

    #app {
      ...
      font-size: .14rem;
    }
    
    • 1
    • 2
    • 3
    • 4

    安装模块 reset-css

    npm i reset-css
    
    • 1

    main.js中添加引入

    import Vue from 'vue'
    import App from './App.vue'
    import router from './router'
    import store from './store'
    import 'reset-css'
    import "@/vantui"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.4 解决html字体大小样式被覆盖问题

    安装完reset-css后,html字体大小样式会被覆盖

    p{
      width: 1rem;
      height: 1rem;
      background-color: red;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    设置完上面样式后达不到想要的效果,原因是样式被覆盖reset-css源代码覆盖了
    可通过!important提升html标签字体大小属性的权重至最高,达到不被任何代码覆盖的效果

    html{
      font-size: 100px!important;  
    }
    
    • 1
    • 2
    • 3

    3、数据请求

    3.1 安装axios并发起请求

    安装axios

    npm i axios
    
    • 1

    在Home.vue中书写axios代码:

    created(){
        axios.get("http://kumanxuan1.f3322.net:8001/index/index")
        .then(res=>{
          	console.log(res.data);
        })
        .catch(err=>{
          	console.log(err);
        })
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3.2 代理配置

    vue.config.js 进行配置:

    module.exports = {
        devServer: {
            port: 8080,
            proxy: {
                '/api': {
                    target: "http://kumanxuan1.f3322.net:8001/",
                    pathRewrite: {
                        '^/api': ''
                    }
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    由于配置文件修改了,这里一定要记得重新 npm run serve !!

    3.3 API与Request封装

    src 下新建 request目录 ,在request目录下新建 request.js
    request.js 中:

    import axios from "axios"
    const instance = axios.create({
        baseURL:"http://kumanxuan1.f3322.net:8001/index/index",
        timeout:5000
    })
    
    instance.interceptors.request.use(config=>{
        console.log("每一次发起请求前,都会先执行这里的代码");
        console.log(config); //config本次请求的配置信息
        return config
    },err=>{
        return Promise.reject(err)
    })
    
    instance.interceptors.response.use(res=>{
        console.log("每一次接收到响应,都会先执行这里的代码,再去执行成功的那个回调函数then");
        return res
    },err=>{
        return Promise.reject(err)
    })
    
    export default instance
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    查看接口文档,首页接口地址为:preUrl+/index/index
    为了更好地管理我们的这些接口,我们把所有请求都抽取出来在一个api.js中
    在request目录下新建 api.js, api.js 中:

    import request from './request'
    // 请求首页的数据
    export const GetHomeLists = () => request.get('/index/index')
    
    • 1
    • 2
    • 3

    3.4 发起请求

    Home.vue 中:

    import {GetHomeLists} from "@/request/api"
    
    created() {
      GetHomeLists().then((res) => {
        if (res.status === 200) {
          console.log(res.data) // 成功拿到所有首页数据
        }
      })
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3.5 请求实践-轮播图

    组件文档地址: https://vant-contrib.gitee.io/vant/#/zh-CN/swipe

    Home.vue中:

    <template>
      <div class="home">
        <van-search v-model="searchVal" disable placeholder="请输入搜索关键词" />
        <van-swipe class="my-swipe" :autoplay="3000" indicator-color="red">
            <van-swipe-item v-for="item in banner" :key="item.id">
               <img :src="item.image_url" alt="" width="100%">
            van-swipe-item>
        van-swipe>
      div>
    template>
    
    <script>
    import { GetHomeLists } from '@/request/api'
    export default {
      name: 'HomeView',
      data() {
        return {
          searchVal: '',
          banner: []
        }
      },
      created() {
        GetHomeLists().then((res) => {
          const { banner } = res.data
          this.banner = banner
          console.log(this.banner)
        }).catch(err => {
          console.log('Error')
          console.log(err)
        })
      }
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    4、点击搜索弹出层结构

    需求:点击首页搜索模块会从右侧弹出一个弹出层
    由于在移动端开发中,在这个弹出层的时候按 “返回键” 可以直接回到首页,这意味着需要实现路由的跳转,而不是简单的盒子展示效果。

    4.1 结构和路由设置

    这就需要把这个弹出层当成一个页面来看,views中新建页面SearchPopup.vue

    <template>
      <div>弹出层div>
    template>
    <script>
    export default {
      data() {
        return {}
      }
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在首页中路由中开辟一个子路由:

    {
        path: '/home',
        name: 'Home',
        component: Home,
        children:[
          {
            path: '/home/searchPopup',
            name:'SearchPopup',
            component:()=>import(/* webpackChunkName: "SearchPopup" */ '../views/SearchPopup.vue')
          }
        ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在Home组件中添加一个组件。用于展示这个子组件。
    最后点击search组件跳转

    <van-search v-model="SearchVal" shape="round" placeholder="请输入搜索关键词" disabled @click="$router.push('/home/searchPopup')"/>
    
    • 1

    4.2 SearchPopup样式调整

    SearchPopup.vue中:

    <style lang="less" scoped>
    .popup {
      width: 100%;
      height: 100%;
      position: absolute;
      right: 0;
      top: 0;
      background-color: rgba(0, 0, 0, 0.5);
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    4.3 滑动进场

    transition的使用文档: https://cn.vuejs.org/guide/built-ins/transition.html#transition

    官方原版:

    在进入/离开的过渡中,会有 6 个 class 切换。

    1. v-enter-from:进入动画的起始状态。在元素插入之前添加,在元素插入完成后的下一帧移除。
    2. v-enter-active:进入动画的生效状态。应用于整个进入动画阶段。在元素被插入之前添加,在过渡或动画完成之后移除。这个 class 可以被用来定义进入动画的持续时间、延迟与速度曲线类型。
    3. v-enter-to:进入动画的结束状态。在元素插入完成后的下一帧被添加 (也就是 v-enter-from 被移除的同时),在过渡或动画完成之后移除。
    4. v-leave-from:离开动画的起始状态。在离开过渡效果被触发时立即添加,在一帧后被移除。
    5. v-leave-active:离开动画的生效状态。应用于整个离开动画阶段。在离开过渡效果被触发时立即添加,在过渡或动画完成之后移除。这个 class 可以被用来定义离开动画的持续时间、延迟与速度曲线类型。
    6. v-leave-to:离开动画的结束状态。在一个离开动画被触发后的下一帧被添加 (也就是 v-leave-from 被移除的同时),在过渡或动画完成之后移除。

    在Home.vue中添加:

    <transition name="slide">
      <router-view>router-view>
    transition>
    
    <style lang="less">
    .slide-enter-from {
      /*进场初始效果*/
      right: -100%;
    }
    .slide-enter-active {
      transition: all 0.2s;
    }
    .slide-enter-to {
      /*进场最终效果*/
      right: 0;
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    4.4 离场动画

    <style lang="less">
    .slide-enter-from,.slide-leave-to{
      right:-100%;
    }
    .slide-enter-active,.slide-leave-active{
      transition:all .2s linear;
    }
    .slide-enter-to,.slide-leave-from{
      right:0;
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    其实vant中直接提供了这个进场动画,所以也可以不需要我们去写这些类
    文档: https://vant-contrib.gitee.io/vant/#/zh-CN/style

    直接把类名换成:

    <transition name="van-slide-right">
       <router-view>router-view>
    transition>
    
    • 1
    • 2
    • 3

    4.5 popup中的搜索框组件的展示

    在SearchPopup.vue中

    <template>
      <div class="popup">
        <van-search
          v-model="searchVal"
          show-action
          :placeholder="placeholderVal"
          @search="onSearch"
          @cancel="onCancel"
        />
      div>
    template>
    <script>
    export default {
      data() {
        return {
          searchVal: '',
          placeholderVal: ''
        }
      },
      methods: {
        onSearch(val) {
          console.log('按了回车')
        },
        onCancel() {
          // 点击了取消
          this.$router.go(-1)
        }
      }
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    5、搜索栏下方三个区域的展示

    5.1 历史记录和热门搜索展示

    在components下新建模块HistoryHot.vue

    <template>
      <div class="history-hot">
        <div class="his-hot">
          <div class="hd">
            <h4>历史记录h4>
            <van-icon name="delete" />
          div>
          <div class="bd">
            <van-tag plain type="default">标签van-tag>
            <van-tag plain type="default">标签van-tag>
            <van-tag plain type="default">标签van-tag>
            <van-tag plain type="default">标签van-tag>
            <van-tag plain type="default">标签van-tag>
            <van-tag plain type="default">标签van-tag>
            <van-tag plain type="default">标签van-tag>
          div>
        div>
    
        <div class="his-hot">
          <div class="hd">
            <h4>热门搜索h4>
          div>
          <div class="bd">
            <van-tag plain type="default">标签van-tag>
            <van-tag plain type="default">标签van-tag>
            <van-tag plain type="default">标签van-tag>
            <van-tag plain type="default">标签van-tag>
            <van-tag plain type="default">标签van-tag>
            <van-tag plain type="default">标签van-tag>
            <van-tag plain type="default">标签van-tag>
          div>
        div>
      div>
    template>
    
    <script>
    export default {
      data() {
        return {}
      }
    }
    script>
    
    <style lang="less" scoped>
    .his-hot {
      margin-bottom: 0.2rem;
      background-color: #fff;
      padding: 2%;
      .hd {
        padding-top: 2%;
        display: flex;
        justify-content: space-between;
        font-size: 0.22rem;
        margin-bottom: 0.1rem;
        h4 {
          font-size: 0.2rem;
        }
      }
      .van-tag {
        padding: 0.04rem;
        margin-right: 0.1rem;
      }
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    在SearchPopup.vue中使用上面HistoryHot组件

    <template>
        <div class="popup">
            <van-search ... />
            <HistoryHot />
        div>
    template>
    <script>
    
    import HistoryHot from "@/components/HistoryHot"
    export default {
        ...
        components:{
            HistoryHot
        }
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    5.2 历史记录和热门搜索的数据渲染

    由于前面我们已经对axios请求进行封装,所以请求数据的三部曲如下:
    1、在api.js中按需到出
    2、在需要发送请求的组件中按需导入
    3、发送请求
    api.js中

    // 历史记录和热门搜索数据的请求
    export const GetPopupData = () => request.get('/search/index')
    
    • 1
    • 2

    SearchPopup.vue中发送请求:

    <template>
        <div class="popup">
            ...
            <HistoryHot 
                :searchHistoryData = "searchHistoryData" 
                :searchHotData="searchHotData"
            />
        div>
    template>
    <script>
    ...
    import {GetPopupData} from "@/request/api"
    export default {
       data () {
           return {
               ...
               placeholderVal:"",
               searchHistoryData:"",
               searchHotData:""
           }
       },
      created() {
        GetPopupData().then((res) => {
          this.placeholderVal = res.data.defaultKeyword.keyword
          this.searchHistoryData = res.data.historyKeywordList
          this.searchHotData = res.data.hotKeywordList
        })
      },
        ...
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    HistoryHot中:

    <template>
        <div class="history-hot">
            <div class="his-hot">
                ...
                <div class="bd">
                    <van-tag v-for="(item,index) in searchHistoryData" :key="index" plain type="default">{{item}}van-tag>
                div>
            div>
    
            <div class="his-hot">
               ...
                <div class="bd">
                    <van-tag v-for="(item,index) in searchHotData" :key="index"   plain :type="item.is_hot?'danger':'default'">{{item.keyword}}van-tag>
                div>
            div>
        div>
    template>
    
    <script>
    export default {
    	...
        props:["searchHistoryData", "searchHotData"]
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    5.3 搜索提示列表

    我们需要一个变量来决定搜索框下方显示哪个组件(上面分析的三种情况)
    SearchPopup.vue中:

    <HistoryHot 
        v-if="blockShow==1"
        :searchHistoryData = "searchHistoryData" 
        :searchHotData="searchHotData"
    />
    <SearchTipsList 
    	v-else-if="blockShow==2"
        :searchTipsArr="searchTipsArr"
    />
    
    ...
    <script>
    import SearchTipsList from "@/components/SearchTipsList"
    data () {
        return {
            ...
            /* 
                blockShow决定区块展示,
                如果是1,展示历史记录和热门搜索 HistoryHot
                如果是2,展示搜索提示列表 SearchTipsList
                如果是3,展示搜索出来内容
            */
            blockShow:2searchTipsArr: [1,2,3,4,5],   // 请求数组从父组件传到子组件
        }
    },
    components:{
        HistoryHot,
        SearchTipsList
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    components中新建SearchTipsList.vue组件:

    <template>
      <div>
        <van-list v-model="loading" :finished="finished" finished-text="没有更多了">
          <van-cell v-for="item in searchTipsArr" :key="item" :title="item" />
        van-list>
      div>
    template>
    
    <script>
    export default {
      data() {
        return {
          loading: false,
          finished: true
        }
      },
      props: ['searchTipsArr']
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    注意:这里还需要在vantui/index.js中多注册一个Cell组件,否则报错

    5.4 请求搜索提示列表数据

    1、在api.js中按需到出
    2、在需要发送请求的组件中按需导入
    3、发送请求
    api.js中: (注意,这里需要设置传参)

    export const GetSearchTipsListData = (params) => request.get("/search/helper",{params});
    
    • 1

    SearchPopup.vue中:

    <van-search
        ...
        @input="onInput"   // 这里添加input事件
    />
    
    import {GetPopupData, GetSearchTipsListData} from "@/request/api"
    methods: {
        
       	...
        onInput(val) {
          this.blockShow = 2
          // 这个val就是用户输入的文字
          GetSearchTipsListData({ keyword: val }).then((res) => {
            console.log(res.data)
            this.searchTipsArr = res.data
          })
        }
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    6、搜索产品展示区块

    6.1 展示组件及下拉菜单

    使用到的组件为:DropdownMenu 下拉菜单 https://vant-contrib.gitee.io/vant/#/zh-CN/dropdown-menu
    components中新建SearchProducts.vue组件:

    <template>
        <div>
            <van-dropdown-menu>
                <van-dropdown-item title="综合" disabled v-model="value1" :options="option1" />
                <van-dropdown-item title="价格" v-model="value2" :options="option2" />
                <van-dropdown-item title="分类" v-model="value2" :options="option2" />
            van-dropdown-menu>
        div>
    template>
    
    <script>
    export default {
        data () {
            return {
                value1: 0,
                value2: 'a',
                option1: [
                    { text: '全部商品', value: 0 },
                    { text: '新款商品', value: 1 },
                    { text: '活动商品', value: 2 },
                ],
                option2: [
                    { text: '默认排序', value: 'a' },
                    { text: '好评排序', value: 'b' },
                    { text: '销量排序', value: 'c' },
                ],
            }
        }
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    SearchPopup.vue中:

    <template>
        <div class="popup">
           ...
            <SearchTipsList 
                v-else-if="blockShow==2"
                :searchTipsArr="searchTipsArr"
            />
            <SearchProducts v-else/>
        div>
    template>
    <script>
    
    import SearchProducts from "@/components/SearchProducts"
    ...
        ...
        components:{
                HistoryHot,
                SearchTipsList,
                SearchProducts
            }
        }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    6.2 添加产品组件和空组件

    components中添加产品组件 Products.vue 组件, 并在SearchProducts.vue组件中引入和使用。
    配合vant中的Empty组件

    SearchProducts.vue中

    <template>
        <div>
           ...
            <van-empty v-if="isEmpty" image="search" description="抱歉,搜索不到产品" />
            <Products />
        div>
    template>
    <script>
    import Products from "./Products"
    export default {
        data () {
            return {
                ...
                isEmpty:false
            }
        },
        components:{
            Products
        }
    
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    6.3 产品组件样式布局

    Products.vue中:

    <template>
        <ul>
            <li >
                <img :src="imgSrc" style="display:block;" width="100%" alt="" />
                <div class="van-ellipsis">产品名称div>
                <div class="price">{{99 | RMBformat}}div>
            li>
        ul>
    template>
    
    <script>
    export default {
        data () {
            return {
                imgSrc:require("@/assets/logo.png")
     
            }
        }
    }
    script>
     
    <style lang = "less" scoped>
    ul{
        padding: .1rem 2%;
        display: flex;
        justify-content: space-between;
        flex-wrap: wrap;
        li{
            width: 49%;
            margin-bottom: .1rem;
            background: #fff;
            text-align: center;
            line-height: .3rem;
            .price{
                color: darkred;
            }
        }
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    main.js中添加全局过滤器:

    Vue.filter("RMBformat",val=>{
      return "¥ "+val.toFixed(2)+" 元"
    })
    
    • 1
    • 2
    • 3

    6.4 发送搜索请求

    api.js中

    // 获取搜索产品内容
    export const GetSearchData = (params) => request.get("/goods/list",{params});
    
    • 1
    • 2

    Searchpopup.vue中

    import {GetPopupData, GetSearchTipsListData, GetSearchData} from "@/request/api"
    
    onSearch(val) {
        GetSearchData().then(res=>{
            if(res.errno===0){
                this.blockShow=3;
                console.log(res.data);
            }  
        }).catch(err=>{
            console.log(err);
        })
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    6.5 传递商品列表数据和分类数据 到对应组件中去使用

    Searchpopup.vue中

    
    <SearchProducts v-else
    	:goodList="goodList"
    	:filterCategory="filterCategory"
    />
    
    onSearch(val) {
        GetSearchData().then(res=>{
            if(res.errno==0){
                this.goodsList = res.data.goodsList
                this.filterCategory = res.data.filterCategory
            }
    
        }).catch(err=>{
            console.log(err);
        })
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    SearchProducts.vue中接收:

    <Products :goodsList="goodsList"/>
    
    
    props:["goodsList", "filterCategory"]
    
    • 1
    • 2
    • 3
    • 4

    Products.vue中接收:

    props:["goodsList"]
    
    • 1

    7、关于重复点击同一个路由出现的报错问题解决

    在新版本的vue-router中,重复点击同一个路由会出现以下报错:
    解决方案如下:

    方案1、直接在push方法最后添加异常捕获,例如:

    <van-search v-model="SearchVal" shape="round" placeholder="请输入搜索关键词" disabled @click="$router.push('/home/searchPopup').catch(err=>{})"/>
    
    • 1

    方案2、直接修改原型方法push(推荐)

    // 把这段代码直接粘贴到router/index.js中的Vue.use(VueRouter)之前
    const originalPush = VueRouter.prototype.push;
    VueRouter.prototype.push = function(location) {
      return originalPush.call(this, location).catch(err => {})
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    (个人笔记)EDEM耦合Recurdyn流程
    Colocate Join :ClickHouse的一种高性能分布式join查询模型
    鸿蒙HarmonyOS应用开发者(基础+高级)认证
    Ubuntu server 24 (Linux) 安装部署smartdns 搭建智能DNS服务器
    浏览器播放rtsp视频,基于nodeJs
    IAP固件升级进阶(Qt上位机)
    Mysql高级——索引创建和使用
    计算机竞赛 基于深度学习的人脸表情识别
    c++实现dijskstra算法
    DevOps敏捷转型常见误区及避坑指南
  • 原文地址:https://blog.csdn.net/shentian885/article/details/126680476