Vue学习笔记(6)——自定义组件

Stars-one 2020年11月24日 98次浏览 本篇字数为4,421字

本文为作者原创,转载请注明出处,谢谢配合
作者:Stars-one
链接:https://stars-one.site/2020/11/24/vue-study-6


最近在整一个Web系统,用来发布软件更新,便于对软件版本进行管理

做着过程中,就需要用到了侧边栏点击切换右边内容的效果,思索了一下,觉得使用Vue自定义的组件比较快捷,而且之后也更容易进行复用,便于有了今天这篇文章的分享

本篇需要读者具有Vue组件相关的知识,可以参考我的前几篇文章,希望大家能从中有所启发

做之前,可以先上效果图,让大家对接下来的代码实现效果有所印象

切换iframe

1.实现点击按钮,显示不同内容的文本

首先,我们得考虑之后的使用情况,我考虑的是由后台返回菜单的json数据,之后,再由Vue进行数据的填充,之后实现我们的点击菜单切换内容功能

我们可以先直接定义好返回的json数据,方便测试,以下是简单的一个json数组数据:

[{
    id: 0,
    text: "按钮0",
    url: "https://www.stars-one.site"
}, {
    id: 1,
    text: "按钮1",
    url: "www.stars-one.site1"
}]

通过上面json,我们来切换不同内容的文本

注册组件:

Vue.component('nav-componet', {
    data: function() {
        return {
            selectIndex: 0,
            navList: [{
                id: 0,
                text: "按钮0",
                url: "https://www.stars-one.site"
            }, {
                id: 1,
                text: "按钮1",
                url: "www.stars-one.site1"
            }]
        }
    },
    //模版,这里我单独抽出来了,见下面的代码块
    template: ``,
    methods: {
        //按钮点击调用此方法,更改selectIndex变量的数据
        setSelectIndex: function(index) {
            this.selectIndex = index;
        }
    },
    computed: {
        //自动计算属性,依赖于selectIndex,当selectIndex发生改变,contentUrl也会发生改变
        contentUrl: function() {
            console.log(this.selectIndex);
            return this.navList[this.selectIndex].url;
        }
    }
});

<div>
    <button v-for="item in navList" v-on:click="setSelectIndex(item.id)">{{item.text}}</button>
    <p>{{contentUrl}}</p>
</div>
  • selectIndex表示当前是哪个菜单被选择
  • setSelectIndex()方法用来改变selectIndex的数值
  • contentUrl表示文本要显示的内容,依赖于selectIndex

可能上面的代码有点多,不过实际的思路其实挺简单,我们通过定义一个selectIndex来表示当前是哪个菜单被选择的,默认为0,即为第一个菜单选项被选中

当按钮点击的时候,**通过setSelectIndex()方法,改变selectIndex的数据,**由于contentUrl是依赖于selectIndex,所以,selectIndex的数据发生改变,contentUrl数值也会发生改变

这里的selectIndex定义为0,其实也是方便取值,contentUrl的数值是从之前上面的json数据中拿到的

可以看到效果:
按钮切换内容

2.点击按钮,切换iframe的src

通过上面,我们已经实现了切换内容功能,接下来就很简单了,只要把那个contentUrl绑定为iframe的src属性,即可达到切换页面的效果

<div>
    <button v-for="item in navList" v-on:click="setSelectIndex(item.id)">{{item.text}}</button>
    <iframe v-bind:src="contentUrl"></iframe>
</div>

由于第二个不是对应的网址,所以iframe显示为空白

切换iframe

PS:考虑到美观的效果,我们还可以使用Vue进行样式的绑定,点击某项,该菜单选项就会有个激活的样式

3.自定义组件属性,接收json数据

使用props,在组件注册的时候定义属性

Vue.component('nav-componet', {
    //nav-componet定义个属性
    props: ["data-nav"],
    data: function() {
        return {
            selectIndex: 0,
        }
    },
    template: ``,
    methods: {
        setSelectIndex: function(index) {
            this.selectIndex = index;
        }
    },
    computed: {
        contentUrl: function() {
            if (this.dataNav==null || this.dataNav.length == 0) {
                return "404";
            }
            return this.dataNav[this.selectIndex].url;
        }
    }
});
<div id="components-demo">
    <nav-componet v-bind:data-Nav="list"></nav-componet>
</div>

new Vue({
    el: '#components-demo',
    data: {
        list: [{
            id: 0,
            text: "按钮0",
            url: "https://www.stars-one.site"
        }, {
            id: 1,
            text: "按钮1",
            url: "www.stars-one.site1"
        }]
    }
});

PS:这里有个坑,没记错的话在之前也有提到过,你自定义属性可以是驼峰,也可以是以-隔开,但无论你使用哪一种方式,最后在html文件中的属性必须是以-隔开,否则会无法调用属性...

以上步骤就是可以搭好了一个十分简单的Vue组件,之后还得稍微改造美化就可以拿到项目上使用了

最后补上终极效果图:

终极效果图

参考代码如下:

Vue.component('nav-componet', {
        props: ["data-nav"],
        data: function() {
            return {
                selectIndex: 0
            }
        },
        template: `<div class="mdui-row-md-10">
                    <div class="mdui-col-md-2">
                        <div class="mdui-list">
                             <a v-for="item in dataNav" class="mdui-list-item mdui-ripple" @click="setSelectIndex(item.id)" v-bind:class="{'mdui-color-theme-100' : isSelect(item.id)}">{{item.text}}</a>
                        </div>
                    </div>
                    <div class="mdui-col-md-10" style="padding: 10px">
                        <iframe :src="contentUrl" frameborder="0" width="100%" height="630px"></iframe>
                    </div>
            </div>`,
        methods: {
            setSelectIndex: function(index) {
                this.selectIndex = index;
            },
            isSelect: function(index) {
                return this.selectIndex == index;
            }
        },
        computed: {
            contentUrl: function() {
                if (this.dataNav == null || this.dataNav.length == 0) {
                    //错误页面,一般定义为404页面
                    return "http://stars-one.site";
                }
                return this.dataNav[this.selectIndex].url;
            }
        }
    });

下回再见!

相关标签