Vue深入-6【Vue中计算属性、过滤器、自定义属性】

(1).计算属性

1.通过双向绑定与计算属性实现复选框自动选择

双向绑定计算属性,从而实现点击三个checkbox最后一个被选中

<div id="app">
    <input
        type="checkbox"
        v-for="item in items"
        :key="item.id"
        v-model="item.completed"
     />
     <input type="checkbox" v-model="allComputed"/>   
</div>
<script>
    new Vue({
        el:'#app',
        data(){
            return{
                items:[
                    {
                        id:1,
                        completed:true
                    },
                    {
                        id:2,
                        completed:false
                    },
                    {
                        id:3,
                        completed:true
                    },
                ]
            }
        },
        computed:{
            allComputed(){
                return this.items.every(item=>{
                    return item.completed === true
                })
            }
        }
    })
</script>

 

2.计算属性得对象写法

点一个剩余得都会被选中

<div id="app">
    <input
        type="checkbox"
        v-for="item in items"
        :key="item.id"
        v-model="item.completed"
     />
     <input type="checkbox" v-model="allComputed"/>   
</div>
<script>
    new Vue({
        el:'#app',
        data(){
            return{
                items:[
                    {
                        id:1,
                        completed:true
                    },
                    {
                        id:2,
                        completed:false
                    },
                    {
                        id:3,
                        completed:true
                    },
                ]
            }
        },
        computed:{
            allComputed:{
               get(){
                   return this.items.every((item)=>{
                       return item.completed === true
                   })
               },
               set(newValue){
                   this.items.forEach(item => item.completed = newValue)
               }
            }
        }
    })
</script>

(2).watch与computed的不同

1.watch能做到得计算属性做不到得

官方推荐请求这类得接口写在watch中

watch:{
    question(newQuestion,oldQuestion){
        axios.get('https://yesno.wtf/api')
            .then(function(res){
                console.log(res.data.answer)
            })
    }
}

2.设置防抖函数  lodash库

<script>
    data(){
        return{
            question:''
        }
    },
    created(){
        this.debouceGetAnswer = _.debounce(this.getAnswer,500)
    },
    watch:{
        question:function(newQuestion,oldQuestion){
            this.debouceGetAnswer();
        }
    },
    methods:{
        getAnswer(){
            axios.get('https://yesno.wtf/api').then(function(res){
                console.log(res.data.answer)
            })
        }
    }
</script>

3.lodash设置中间状态

输入后会先显示输入中...再出结果

<script>
    data(){
        return{
            question:'',
            answer:'输入问题'
        }
    },
    created(){
        this.debouceGetAnswer = _.debounce(this.getAnswer,500)
    },
    watch:{
        question:function(newQuestion,oldQuestion){
            this.getAnswer();
        }
    },
    methods:{
        getAnswer(){
            this.answer="搜索中.."
            axios.get('https://yesno.wtf/api').then(function(res){
               this.answer=res.data.answer;
            })
        }
    }
</script>


(3).filter函数过滤器

1.基本使用方式

moment日期库

通过|将原始值传入到value中,return又可以把值再返回出去

<div id="app">
    {{timestamp | format('YYYY-MM-DD')}}
<div>
<script>
    Vue.filter('format',function(value,formatter){
        console.log(value);//值
        console.log(formatter);//参数
        return moment(value).format(formatter);
    })
    new Vue({
        el:'#app',
        data(){
            return{
                timestamp:1233211233211
            }
        }
    })
</script>

2.多次传递可以有多个,多次传递,先把currency处理了再通过test处理

<div id="app">
    {{number | currency | test}}
</div>
<script>
    Vue.filter('currency',function(value){
        return `$${value}`
    })
    Vue.filter('test',function(value){
        return value
    })
</script>

(4).自定义指令实例

1.指令的基本用法

给与动态类名实现点击切换

app.vue
<template>
    <div>
        <NavBar/>
    </div>
</template>
<script>
import NavBar from './components/NavBar';
export default{
    components:{
        NavBar
    }
}

navbar.vue
<template>
    <div class="nav-bar">
        <div
         :class="['nav-item',{'nav-active':index === currentIndex}]"
         @click="changeIndex(index)"
         v-for="(item,index) in items"
         :key="index"
         >
             {{item}}-{{index}}
         </div>
    </div>
    
</template>
<script>
    export default{
        data(){
            return{
                currentIndex:1,
                items:['项目1','项目2','项目3','项目4']
            }
        },
        methods:{
            changeIndex(index){
                this.currentIndex = index;
            }
        }
    }
</script>
<style>
    .nav-bar{
        width:300px;
        height:50px;
        border:1px solid #000;
        margin: 0 auto;
    }
    .nav-item{
        float:left;
        width:25%;
        height:100%;
        line-height:50px;
        text-align:center;
    }
</style>

2.变为自定义指令

<template>
    <div class="nav-bar" v-nav-active>
        <div
         :class="['nav-item',{'nav-active':index === currentIndex}]"
         @click="changeIndex(index)"
         v-for="(item,index) in items"
         :key="index"
         >
             {{item}}-{{index}}
         </div>
    </div>
    
</template>
<script>
    import NavActive from '../directives/navActive'
    export default{
        data(){
            return{
                currentIndex:1,
                items:['项目1','项目2','项目3','项目4']
            }
        },
        methods:{
            changeIndex(index){
                this.currentIndex = index;
            }
        }
    }
</script>

navActive.js
在div上一绑定就会执行bind的函数
当操作这个div的时候一旦有更新就会执行update函数
可以接收参数
上边下边都要访问不然会报错
1.基本形式
export default{
    bind(){
        console.log('bind');
    },
    update(){
        console.log('update')
    }
}
2.传参
export default{
    bind(el,binding){
        console.log('bind');
        console.log(el);//dom元素
        console.log(binding);//一些乱七八糟的参数
    },
    update(el,binding){
        console.log('update');
        console.log(el);
        console.log(binding)
    }
}


3.自定义可以通过.value获取传递过来的值

这样传值不行

<div class="nav-bar" v-nav-active="{{message}}">//不可以
<div class="nav-bar" v-nav-active="message">//变量是可以的
<div class="nav-bar" v-nav-active="‘reverseMessage’">//传递字符串

4.实现自定义组件切换样式

<template>
    <div class="nav-bar" v-nav-active="{
        activeClass:'nav-active',
        currentIndex:currentIndex,
        className:'nav-item'
    }">
    <div 
        class="nav-item"
        @click="changeIndex(index)"
        v-for="(item,index) in items"
        :key="index"
    >
        {{item}}-{{index}}
    </div>  
    </div>  
</template>
<script>
    import NavActive from '../directives/navActive'
    export default{
        data(){
            return{
                currentIndex:1,
                items:['项目1','项目2','项目3','项目4']
            }
        },
        methods:{
            changeIndex(index){
                this.currentIndex = index;
            }
        }
    }
</script>
navActive.js
这样会导致之前的类去除不掉,所有被点击的都会被加上类
export default{
    bind(el,binding){
        const element = el,
              options = binding.value,
              children = element.getElementsByClassName(options.className);
        const {activeClass,currentIndex} = options;
        children[currentIndex].className+= `${activeClass}`      
    },
    update(el,binding){
        console.log('update');
        console.log(el);
        console.log(binding)
    }
}


 

通过update解决(update中的binding中有新的值和旧的值)

navActive.js
这样写没问题
export default{
    bind(el,binding){
        const element = el,
              options = binding.value,
              children = element.getElementsByClassName(options.className);
        const {activeClass,currentIndex} = options;
        children[currentIndex].className+= `${activeClass}`      
    },
    update(el,binding){
        console.log('update');
        const element = el,
              options = binding.value,
              oldOptions = binding.oldValue
              children = element.getElementsByClassName(options.className);
        const {activeClass,currentIndex} = options;
        const {currentIndex:oldIndex,className} = oldOptions;
        children[currentIndex].className += `${activeClass}`
        children[oldIndex].className = className  
    }
}

5.自定义指令的拓展(Vue.directive做内部指令)

相当是.arg接收了:后面的参数

通过[]把传递的参数变成了变量

<div id="xx">
    <h3>abc</h3>
    <p v-pin:[direction]="200">
        cde
    </p>
</div>
<script>
    Vue.directive('pin',{
        bind(el,binding,vnode){
            el.style.position = 'fixed';
            var s = binding.arg = 'left' ? 'left' : 'top';
            el.style[s] = binding.value +'px'
        }
    })
    new Vue({
        el:'#xx',
        data(){
            return {
                direction:'left'
            }
        }
    })
</script>

里面的参数还会有很多可以查阅手册

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值