学习笔记-Vue 组件的运用(模板技术)

目录

全局组件

组件的根元素

组件的 data 属性

例子:自定义密码输入框组件

1. 下载图标

2. 定义组件

3. 调整布局

4. 添加事件

5. 验证

例子:自定义分页组件

1. 先找一个分页的实例

2. 获取数据

3. 计算分页数

4. 动态创建元素

5. 组件传值

1. 父传子

6. 高亮显示

2. 子传父


全局组件

全局组件需要在 Vue 创建实例前创建好

组件的根元素

在vue 2 中,只能有一个根元素,vue 3可以有多个

组件的 data 属性

组件内部的数据的 data 只能使用方法,不能使用对象

        在 Vue.js 中,组件的 data 属性必须被定义为一个函数而不是一个对象,这是因为每个组件实例都需要拥有自己独立的一份数据。当 data 被定义为一个函数时,每次创建一个新的组件实例时,这个函数都会被调用一次,从而返回一个新的对象。这样可以确保每个实例都有其独立的状态,不会因为共享数据而产生意外的副作用。

        如果 data 是直接定义为一个对象,那么所有基于这个组件创建的实例将会共享同一份数据。这意味着改变其中一个实例的数据会直接影响到其他所有实例的数据

在这种情况下,所有的 my-component 实例都将共享同一个 message 属性。如果你在一个实例中改变了 message,它会影响到所有其他的实例。

Vue.component('my-component', {
  template: '<div>{{ message }}</div>',
  data: {
    message: 'Hello'
  }
});

正确的做法是

Vue.component('my-component', {
  template: '<div>{{ message }}</div>',
  data: function () {
    return {
      message: 'Hello'
    };
  }
});

例子:自定义密码输入框组件

做一个类似华为网站登录界面的密码输入框

1. 下载图标

iconfont-阿里巴巴矢量图标库

2. 定义组件

3. 调整布局

创建一个css 文件,把调整好的格式复制到文件里

.password-input {
    position: relative;
}
.password-input input {
    width: 200px;
    height: 24px;
}
.password-input img {
    width: 30px;
    position: absolute;
    left: 175px;
    top: 2px;
}

4. 添加事件

<!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="../static/js/vue.js"></script>
    <link rel="stylesheet" href="../static/css/password.css">
</head>
<body>
    <div id="app">
        <my-password-input></my-password-input>
    </div>
    <script>
        Vue.component("my-password-input",{
            template:`
                <div class="password-input">
                    <input :type="type" v-model="password">
                    <img :src="src" @click="showPassword">
                </div>
            `,
            data() {
                return {
                    type :"password",
                    src :"../static/image/不可见.png"
                }
            },
            methods: {
                showPassword(){
                    if ( this.type == "password" ){
                        this.type = "text";
                        this.src = "../static/image/可见.png";
                    }else {
                        this.type = "password";
                        this.src = "../static/image/不可见.png";
                    }
                }
            },
        })

        new Vue({
            el:"#app",
        })
    </script>
</body>
</html>

5. 验证

不可见状态

点击可见后

例子:自定义分页组件

1. 先找一个分页的实例

CSS 分页实例 | 菜鸟教程

CSS 文件

ul.pagination {
    display: inline-block;
    padding: 0;
    margin: 0;
}

ul.pagination li {display: inline;}

ul.pagination li a {
    color: black;
    float: left;
    padding: 8px 16px;
    text-decoration: none;
    transition: background-color .3s;
    border: 1px solid #ddd;
}

ul.pagination li a.active {
    background-color: #4CAF50;
    color: white;
    border: 1px solid #4CAF50;
}

ul.pagination li a:hover:not(.active) {background-color: #ddd;}

显示正常

2. 获取数据

这里获取数据是为了方便调整分页的数量

记得引入 axios.min.js 

created 表示在页面创建完成后调用方法

总记录条数8条,这次请求的数量是5条记录,那么还有3条记录需要在第二页显示

3. 计算分页数

4. 动态创建元素

因为分页的数量在 父组件那里,需要获取父组件的 pageCount

5. 组件传值

什么是父子组件

1. 父传子

将父组件的 分页对象 page 传给子组件

        父组件设置自定义属性,通过自定义属性传值

        子组件通过 props 接收父组件传过来的参数

6. 高亮显示

2. 子传父

子组件的当前页面发生变化,比如,点击第二页的按钮时,需要通知父组件处理

子组件通过$emit()来通知父亲

父组件通过自定义的事件接收子组件传的参数

点击切换

源码

<!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="../static/js/vue.js"></script>
    <script src="../static/js/axios.min.js"></script>
    <link rel="stylesheet" href="../static/css/pages.css">  <!-- 自定义的CSS文件 --> 
</head>
<body>
    
    <div id="app">
        <pages-component :page="page" @change-page="changePage"></pages-component>
    </div>

    <script>
        Vue.component("pages-component",{
            props:{
                page: {
                    type: Object,
                },
            },
            template:`
                <ul class="pagination">
                    <li><a href="#">«</a></li>
                    <li v-for="item in page.pageCount">
                        <a href="#" :class="item==page.pageCurre ? 'active' : '' " @click="changePage(item)">{{ item }}</a>
                    </li>
                    <li><a href="#">»</a></li>
                </ul>
            `,
            methods:{
                changePage(index){
                    this.$emit("change-page",index)
                }
            }
        })
        new Vue({
            el:"#app",
            data:{
                page:{
                    pageCurre:1,
                    pageSize:5,
                    pageCount:0,
                }
            },
            created() {
                this.getAdmins();
            },
            methods: {
                getAdmins(){
                    axios.post(        //改成你自己的请求路径
                        "http://localhost:8080/mybatis_war_exploded/Admin/GetAdmins",
                        this.page,
                    ).then((res) => {
                        console.log(res.data);
                        this.page.pageCount = Math.ceil(res.data.count / this.page.pageSize)  // 总页数除以每页显示的条数,ceil 向上取整
                    })
                },
                changePage(index){
                    this.page.pageCurre = index;
                    this.getAdmins();
                }
            },
        })
    </script>
</body>
</html>

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值