Vue基础知识巩固

5 篇文章 0 订阅

结合情景联想记忆是一种很棒的记忆方法,本篇博客咱们通过一个小案例来加深对部分vue基础知识的理解和应用。

实现初版效果

小案例的应用场景是有一家好吃的炒面店,店里炒面的种类有很多,咱们要将炒面分成吃过和没吃过的两部分,同时因为店里炒面的种类可能会增加,所以咱们还要有添加炒面的部分,下面咱们来着手实现一下。最后的效果如下图:

首先新建一个noodles.html文件,这个文件就是开始案例的入口,再新建一个components文件夹,不同部分放到不同的JS文件(组件)中,在该文件夹下新建App.js(充当根组件),在noodles.html文件中对vue进行引入,由于根组件被导入之后直接用在createApp()中,所以并不需要进行组件注册,noodles.html文件的完整代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://unpkg.com/vue@3.2.31/dist/vue.global.js"></script>
</head>
<body>
    <div id="app"></div>
    <script type="module">
        import App from "./components/App.js"

        Vue.createApp(App).mount('#app')
    </script>
</body>
</html>

在componets文件夹下新建StoreSection.js文件,因为App.js充当根组件,根组件放的内容相对简洁,所以只需在根组件中引入写有主要内容的组件即可,咱们会在StoreSection.js文件写主要内容,这里就需要进行组件注册之后使用,使用组件标签时用驼峰命名法,“驼峰”之间的连接用的是 - ,App.js的完整代码如下:

import StoreSection from './StoreSection.js'

export default {
    components: { StoreSection },
    template: /*html*/`
        <store-section></store-section>
    `
}

在StoreSection.js中完成最初版效果,通过将炒面菜单存放到foods数组中,每一份炒面味道和食材不同,所以它们是数组中不同的food对象,利用v-for将炒面遍历到li标签中,同时我们为了方便区分,利用filter判断food中的state来区分吃过还是没吃过,如果一种炒面都没吃过,就先不显示吃过部分,如果每种炒面都吃完了,那就不显示没吃过部分,通过吃过或者没吃过的炒面数组长度,利用v-show来决定是否显示该部分。如下图:

 

添加新口味炒面的部分,通过v-on(可以用@代替)绑定提交的事件,再用prevent实现局部刷新,添加的按钮是为submiit类型,点击之后触发form标签调用add方法,添加的方法直接利用push添加新的炒面对象,属性与原来的炒面对象一致(包括id,name,state),同时通过newFood变量利用v-model双向获取输入框中的内容,进行新口味炒面的添加,添加完毕之后将newFood置零,如下图所示:

 StoreSection.js初版完整代码如下:

export default {
    template: /*html*/`
    <section v-show="foods.filter(item => !item.state).length">
        <h2>没吃过</h2>
        <ul>
            <li v-for="food in foods.filter(item => !item.state)" :key="food.id">
                <span>{{ food.name }}</span>
                <input type="checkbox" v-model="food.state">
            </li>
        </ul>
    </section>

    <section v-show="foods.filter(item => item.state).length">
        <h2>吃过</h2>
        <ul>
            <li v-for="food in foods.filter(item => item.state)" :key="food.id">
                <span>{{ food.name }}</span>
                <input type="checkbox" v-model="food.state">
            </li>
        </ul>
    </section>
    
    <form @submit.prevent="add"> 
        <input type="text" v-model="newFood">
        <button type="submit">添加</button>
    </form>
    `,
    data() {
        return {
            foods: [
                { id: 1, name: '干妈肉丝炒面', state: false},
                { id: 2, name: '火爆肉丝炒面', state: false},
                { id: 3, name: '玉米鸡丁炒面', state: false},
            ],
            newFood: '',
        }
    },
    methods: {
        add() {
            this.foods.push({
                id: this.foods.length + 1,
                name: this.newFood,
                state: false,
            }),
            this.newFood = ''
        }
    },
}

这样初版本就完成了。

初版代码简化

上面箭头所指部分内容相同,可以封装成一个方法,便于复用,需要注意对data中的数据进行操作需要放到computed中进行,封装之后代码如下: 

    computed: {
        filters() {
            return {
                beforeBuy: this.foods.filter(item => !item.state),
                afterBuy: this.foods.filter(item => item.state)
            }
        }
    }

拆分组件进行代码优化

可以看到代码中仍有许多重复的部分,为了进一步提高代码简洁性,咱们可以对是否吃过和添加新类型炒面两部分分别进行整合封装,这样可以深化理解组件关系,还便于进行复用。

遍历部分优化

在componets文件夹下新建StoreEat.js组件,将遍历炒面的部分复制到StoreEat.js(子组件)中,如果把StoreSection.js(父组件)中关于炒面的数据全都拿过来就有些复杂了,理理逻辑,咱们想在子组件中用父组件的数据,那么就可以用props将子组件需要数据的格式标准定义出来,在父组件中给予数据,具体见下图:

 

添加部分优化

在components文件夹下新建StoreAdd.js(子组件)文件,将form表单部分剪切到StoreAdd.js文件中,并在子组件中新建add方法,为了便于区分父子组件之中的add方法,将StoreSection.js中的add方法改为fatherAdd方法,我们通过$emit将add方法暴露给父组件,当sumbit触发之后,调用子组件的add方法,最后调用父组件的fatherAdd方法实现添加炒面的操作,父组件的调整如下图

 

 StoreAdd.js(子组件)的完整代码如下:

export default  {
    template: /*html*/`
    <form @submit.prevent="add"> 
        <input type="text" v-model="newFood" placeholder="输入新添加的炒面">
        <button type="submit">添加</button>
    </form>
    `,
    data() {
        return {
            newFood: ''
        }
    },
    methods: {
      add() {
        this.$emit('add', this.newFood);
      }  
    },
}

修改完毕,咱们就得到拆分之后的版本,同时知识也在场景中得到应用和加深。

注意事项

1.在运行为了解决跨域问题,安装Live Server插件,运行时右键,选择open with live server强制在同一作用域下运行;

2.使用/*html*/之前,安装es6-string-html插件;

3.如果报错,可以多留意是否漏写return和this。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值