【Vue】vue基础语法——自定义指令、过滤、组件和动画(内附详细案例代码)——day04

大家好,从今天开始,会每天分享vue学习的知识点,一起加油~

 Vue选项(会继续更新...)

  • el 模板
  • data数据
  • methods方法
  • directives指令
  • filters过滤
  • watch监听
  • computed计算
  • props属性
  • created 创建完毕
  • template 模板
  • components组件

自定义指令(directives)

作用:操作dom,实例化第三方基于dom的插件

  • 当被插入时候inserted
  • 只绑定一次 bind
  • 更新时候运行 update

课堂案例

<body>
    <div id="app">
        <h1>自定义指令</h1>
        <input type="text" v-focus="flag">
        <button @click.prevent.stop="flag=!flag">改变</button>
    </div>

    <script src="../js/vue.js"></script>
    <script>
        new Vue({
            el: "#app",
            data() {
                return {
                    flag: true
                }
            },
            directives: {
                //自己定义v-focus 指令
                "focus": {
                    //当被插入时候inserted
                    //只绑定一次 bind
                    //更新时候运行 updatee

                    update(el, binding) {
                        //el 指令对应的节点
                        //binding.value 指令的值
                        console.log(el, binding);
                        if (binding.value) {
                            //让指令对应的节点获取焦点
                            el.focus()
                        }
                    }
                }
            }
            //01操作dom
            //02执行第三方基于dom操作的插件
        })
    </script>
</body>

代码运行结果 

过滤(管道)filters

vue过滤器就是用来过滤模型数据,在显示之前进行数据处理和筛选。

语法:{{ data | filter1(参数) | filter2(参数) }}

课堂小案例

<body>
    <div id="app">
        <h1>过滤或管道 </h1>
        <p>{{100}}--{{100.00}}</p>
        <p>{{3.1415926}}--{{3.14}}</p>
        <p>{{3.1415926|fix}}</p>
        <p>{{3.15926927|fix(5)}}</p>
        <p>{{1000|fix(5)}}</p>
        <hr>
        <p>{{'2022-09-20'}}-->{{'2天前'}}</p>
        <p>{{'2021-09-20'|date}}</p>
        <p>{{'2020-09-20'|date}}</p>
        <p>{{'2021-12-30'|date}}</p>
    </div>
    <script src="../js/vue.js"></script>
    <script>
        new Vue({
            el: "#app",
            filters: {
                //val是| 左边的值
                fix(val, len = 2) {
                    //返回要显示的内容
                    return Number(val).toFixed(len)
                },
                date(val) {
                    //获取1970.1.1到当前的毫秒数
                    var time1 = new Date(val).getTime()
                    var time2 = new Date().getTime()
                    //获取毫秒差
                    var dis = time2 - time1
                    //转换为天数
                    var day = Math.round(dis/1000/60/60/24)
                    //返回
                    return day+"天前"
                }
            }
        })
    </script>
</body>

运行结果

 

组件components

01组件概念

组件的组织:通常一个应用会以一棵嵌套的组件树的形式来组织

组件就是定义好的一功能模块

建议:多用props,少在组件中使用data(降低组件的耦合性)

 02组件作用:

  1. 组件是vue的一个重要的特点
  2. 实现多个写作开发
  3. 通过组件划分降低开发的难度
  4. 实现复用,降低重复劳动

03定义与使用

1.定义

注意:template有且只有一个根节点

const steper = {
`
<span></span>
`
}

2.在父组件中注册

components:{steper:steper}

3.在组件的模板中使用

<steper></steper>

 04传参

父传子

父:<model :visible="visible"></model>

子  props:{visible:{type:Boolean,default:false}}

子使用

注意:vue是单向数据流,父组件传递给子组件的props是只读(不能修改)this.value

子传父

子 this.$emit("update:visible",false)

父 监听事件,修改值

<model @update:visible="visible=$event"></model>

05 课堂案例

注意:(以下代码是组件.html 的 代码)

<body>
    <div id="app">
        <h1>组件传参</h1>
        <p>父传子</p>
        <step v-model="r"></step> <br>
        <step :value="r" @input="r=$event" :min="100" :max="500" :step="10"></step><br>
        <input type="range" min="100" max="500" v-model.lazy.number="r">
        <div :style="{'border':'2px solid #ccc','borderRadius':r+'px',width:r+'px',height:r+'px'}"></div>
    </div>


    <script src="../js/vue.js"></script>
    <script src="./components/step.js"></script>
    <script>

        new Vue({
            el: "#app",
            //02 注册组件
            components: { step },
            data() {
                return {
                    r: 100,
                }
            }
        })
//父传子props
//value min max step

//子传父 事件emit
//input事件

    </script>
</body>

 以下代码是文件夹compontents 的 step.js 的代码

//01 定义组件
var step = {
    template: `
    <span>
       <input type="text" v-model.lazy.number="count"> 
       <button @click="count+=step" :disabled="count>=max">+</button>
       <button @click="count-=step" :disabled="count<=min">-</button>
    </span>`,
    props: {
        //props 接收父组件传递过来的参数
        value: {
            // 参数名称value
            type: Number,
            default: 1, //默认值是1 如果不传value的值是1
        },
        //接收父组件传递过来参数最大值,最小值,步进值
        min: {
            type: Number,
            default: 1,
        },
        max: {
            type: Number,
            default: 999,
        },
        step: {
            type: Number,
            default: 1,
        },
    },
    data() {
        return {
            count: this.value, //count的默认值是父组件传过来的参数value
        };
    },
    watch: {
        count: {
            //子传父,通过emit 发送事件
            handler() {
                //限定最大值,最小值
                if (this.count >= this.max) {
                    this.count = this.max;
                }
                if (this.count <= this.min) {
                    this.count = this.min;
                }
                this.$emit("input", this.count);
            },
            deep: true,
        },
        value: {
            handler() {
                //监听value值得变化更新count(可选)
                this.count = this.value;
            },
        },
    },
};
//为什么不直接使用this.value 和input框绑定
//答:父组件传到子组件的参数必须是只读
//当count 的数据发生变化的时候通知父组件更新数据

运行结果

 

插槽 

组件的嵌套内容

//父组件
<model>
<input>
<button>确定</button>
</model>
//子组件在模板中使用
template:`
<div>
<slot></slot>
</div>
`

 课堂案例

01 组件.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="../js/vue.js"></script>
        <script src="./model/index.js"></script>
        <link rel="stylesheet" href="./model/index.css" />
        <style>
            * {
                margin: 0;
                padding: 0;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <h1>组件的插槽</h1>
            <button @click="visible=true">显示弹框</button>
            <!-- 使用组件 -->
            <!-- 父组件监听update:visble事件 修改visible的值为事件的参数$event(false) -->
            <!-- <model :visible.sync="visible"> -->
            <model :visible="visible" @update:visible="visible=$event">

                <div>
                    俺们是弹框的内容插槽
                    <p>其他内容也可以</p>
                </div>
            </model>
        </div>
        <script>
            //思路与目标
            //1.把model 单独成为一个js文件
            //2.model的css(弹框样式)
            //3.控制弹框显示与隐藏(父传子,关闭:子传父)
            new Vue({
                el: "#app",
                components: {
                    model,
                },
                data() {
                    return {
                        visible:false,//控制组件是否显示
                    };
                },
            });
        </script>
    </body>
</html>

02 index.js 文件 

//01定义组件
var model = {
    template: `
<div class="model" v-if="visible">
    <div class="model-content">
        <h3 class="model-title">我是弹框标题
        <button class="close" @click="$emit('update:visible',false)">x</button></h3>
        <div class="model-body">
            <slot></slot>
        </div>
    </div>
</div>
`,
    props: {
        visible: {
            type: Boolean,
            default: false,
        },
    },
};

 代码运行

 

具名插槽

当一个组件中有很多地方要使用插槽时,就用具名插槽来区分

子组件 <slot name="插槽内容"></slot>

父组件      <组件名><template v-slot:插槽名字></template></组件名>

 简写<template #插槽名字></template>

 案例代码

<!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="../js/vue.js"></script>
    </head>
    <body>
        <div id="app">
            <h1>具名插槽(起名字的多个插槽)</h1>
            <p>$100🔪</p>
            <p>¥100⚪</p>
            <hr />
            <price>
                <template v-slot:pre>¥</template>
                <template v-slot:next>元</template>
            </price>
            <hr>
            <price>
                <template #next>🔪</template>
                <template #pre>$</template>
            </price>
        </div>
        <script>
            const price = {
                template: `
            <span>
               <slot name="pre"></slot> 
               100
               <slot name="next"></slot> 
            </span>
            
            `,
            };
            new Vue({
                el: "#app",
                components: {
                    price,
                },
                data() {
                    return {};
                },
            });
        </script>
    </body>
</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="../js/vue.js"></script>
    </head>
    <body>
        <div id="app">
            <h1>插槽的作用域(父组件自定义渲染子组件局部内容)</h1>
            <p>scope就是作用域包含的数据</p>
            <lis :list="list">
                <template v-slot:default="scope">
                    💖<span>{{scope.item}}</span> <button>x</button>
                </template>
            </lis>
            <lis :list="list">
                <template v-slot="scope"> 
                    <!-- 默认插槽可以省略default -->
                    😊<span>{{scope.item}}</span> <button>x</button>
                </template>
            </lis>
            <lis :list="list">
                <template slot-scope="scope">
                    💎<span>{{scope.item}}</span> <button>x</button>
                </template>
            </lis>
        </div>
        <script>
            /* 目标:定义一个列表自己list  */
            const lis = {
                template: `
            <div>
                <div v-for="item in list" :key="item">
                     <slot :item="item"></slot> 
                </div>
            </div>
            
            `,
                props: {
                    list: { type: Array },
                },
            };
            new Vue({
                el: "#app",
                components: {
                    lis,
                },
                data() {
                    return {
                        list: ["vue", "react", "angular"],
                    };
                },
            });
        </script>
    </body>
</html>

运行结果

动画

两个状态的过渡

 transition 单个动画元素

  • v-enter-active进入整个状态
  • v-enter 进入开始
  • v-enter-to 进入结束
  • v-leave-active离开整个状态
  • v-leave 离开开始
  • v-leave-to 离开结束

方法1 

方法2

 方法3

 今天的分享就结束了~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值