手写移动端导航栏(仿京东)实例【VUE3】

一.创建VUE3工程写移动端导航栏实例

1.1 项目大纲

需求:根据图片内容完成项目代码

image-20230316233043377

先创建一个新的VUE项目,使用脚手架汇总vite方式创建。

image-20230316203620757

项目主入口为App.vue(父),创建TabControl.vue(子)组件。

需要的图片放到:(本作业使用动态src绑定)

Vue3\01_TypeScript\03_Vue3\work-demo\src\assets

1.2 App.vue

  1. template层:
<div>
    <tab-control :titles="titles" @titleClick="titleClick"></tab-control>
    <h2>{
   
   { contents[currentIndex] }}</h2>
</div>

解释:

tab-control是自定义标签,对应子组件。

:titles=“titles”,将titles的值传给子组件。

@titleClick=“titleClick”,点击事件,检查页面下标。

{ { contents[currentIndex] }}:对应页面的内容。

  1. JS代码层:

规范的VUE项目,这里应该写TS代码,由于企业课程没有讲ts所以这里使用JS。

import TabControl from './components/TabControl.vue';
export default {
    
    
  components: {
    
    
    TabControl
  }, data() {
    
    
    return {
    
    
      titles: [{
    
     name: "首页", urld: 22, urlo: 27 }, {
    
     name: "新品", urld: 23, urlo: 28 }, {
    
     name: "逛", urld: 24, urlo: 29 },
      {
    
     name: "购物车", urld: 25, urlo: 30 }, {
    
     name: "我的", urld: 26, urlo: 31 }],
      contents: ["1", "2", "3", "4", "5"],
      currentIndex: 0
    }
  },
  methods: {
    
    
    titleClick(index) {
    
    
      this.currentIndex = index;
    }
  }
}

解释:

import TabControl from ‘./components/TabControl.vue’;:引入子组件

components->TabControl:放行TabControl子组件

return : 返回定义值。

methods:方法,这里写自定义函数,目的,获取子组件传参,进行改变页面内容。

[{ name: “首页”, urld: 22, urlo: 27 }:titles解释:name为导航栏文字,urld为未选中图标,urlo为选中图标。

1.3 TabControl.vue

1.template层:

div盒子的类名用驼峰命名法,将单词之间使用-连接,改为小写。

<div class="tab-control-item" :class="{ active: currentIndex === index }" v-for="(title, index) in titles"
            v-bind:key="title" @click="itemClick(index)">
            <div v-if=" currentIndex === index">
                <img :src="require(`@/assets/${title.urlo}.png`)" alt="" style="width: 25px; height: 25px;"><br/>
            </div>
            <div v-if=" currentIndex != index">
                <img :src="require(`@/assets/${title.urld}.png`)" alt="" style="width: 25px; height: 25px;"><br/>
            </div>
            <span>{
   
   { title.name }}</span>
        </div>

主要代码解释:

:class="{ active: currentIndex === index }:主要作用于文字选中下标红色,如果currentIndex(当前页面下标)和index (循环下标)相同时,返回Ture,class标签新加active,下面css代码有所体现。

v-for=“(title, index) in titles” v-bind:key=“title” :使用for循环,将父页面的titles进行循环渲染(5个按钮文字)。

@click="itemClick(index):获取点击事件,获取当前页面下标。

下方代码解释:

使用判断语句,继续筛选渲染,如果下标相同说明选中改图标,显示选中图标,反之选中正常图标。

特殊说明:img标签在一开始发现无法正确的获取到地址,然后使用src动态绑定的方法,见下方代码:

<div v-if=" currentIndex === index">
    <img :src="require(`@/assets/${title.urlo}.png`)" alt="" style="width: 25px; height: 25px;"><br/>
</div>
<div v-if=" currentIndex != index">
    <img :src="require(`@/assets/${title.urld}.png`)" alt="" style="width: 25px; height: 25px;"><br/>
</div>

2.JS层:

export default {
    
    
    emits: ["titleClick"],
    props: {
    
    
        titles: {
    
    
            type: Array,
            default() {
    
    
                return []
            }
        }
    },
    data() {
    
    
        return {
    
    
            currentIndex: 0
        }
    },
    methods: {
    
    
        itemClick(index) {
    
    
            console.log(this.currentIndex);
            this.currentIndex = index;
            this.$emit("titleClick", index);
        }
    }

解释:

props:一个组件需要显式声明它所接受的 props,这样 Vue 才能知道外部传入的哪些是 props,哪些是透传 attribute

这里声明titles。

数据返回当前选中页面的下标。

methods:获取到当前页面下标,返回值给父组件。

3.CSS:CSS没有什么需要解释的。

<style scoped>
.tab-control {
    
    
    display: flex;
    flex-wrap:wrap;
}

.tab-control-item {
    
    
    flex: 1;
    text-align: center;
}

.tab-control-item.active {
    
    
    color: red;
}

.tab-control-item.active span {
    
    
    border-bottom: 3px solid red;
    padding: 5px 10px;
}
</style>

二.效果展示

测试没有问题,写的时候吧内容放到了下面,不过功能已经实现,这个并不重要,介意的直接把app.vue里的内容和导航栏互换一下位置,然后把导航栏进行一个绝对定位即可完成。

image-20230316232828757

image-20230316232836483

image-20230316233021711

猜你喜欢

转载自blog.csdn.net/weixin_52908342/article/details/129603931