[Vue.js] 基础 -- Vue常用特性

Vue常用特性

常用特性概览
  • 表单操作

  • 自定义指令

  • 计算属性

  • 过滤器

  • 侦听器

  • 生命周期

 

表单操作
  • 基于Vue的表单操作
    • Input 单行文本
    • textarea 多行文本
    • select 下拉多选
    • radio 单选框
    • checkbox 多选框

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style type="text/css">

        form div {
            height: 40px;
            line-height: 40px;
        }
        form div:nth-child(4) {
            height: auto;
        }
        form div span:first-child {
            display: inline-block;
            width: 100px;
        }
    </style>
</head>
<body>
<div id="app">
    <form action="http://itcast.cn">
        <div>
            <span>姓名:</span>
            <span>
          <input type="text" v-model='uname'>
        </span>
        </div>
        <div>
            <span>性别:</span>
            <span>
          <input type="radio" id="male" value="1" v-model='gender'>
          <label for="male"></label>
          <input type="radio" id="female" value="2" v-model='gender'>
          <label for="female"></label>
        </span>
        </div>
        <div>
            <span>爱好:</span>
            <input type="checkbox" id="ball" value="1" v-model='hobby'>
            <label for="ball">篮球</label>
            <input type="checkbox" id="sing" value="2" v-model='hobby'>
            <label for="sing">唱歌</label>
            <input type="checkbox" id="code" value="3" v-model='hobby'>
            <label for="code">写代码</label>
        </div>
        <div>
            <span>职业:</span>
            <select v-model='occupation' multiple>
                <option value="0">请选择职业...</option>
                <option value="1">教师</option>
                <option value="2">软件工程师</option>
                <option value="3">律师</option>
            </select>
        </div>
        <div>
            <span>个人简介:</span>
            <textarea v-model='desc'></textarea>
        </div>
        <div>
            <input type="submit" value="提交" @click.prevent='handle'>
        </div>
    </form>
</div>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
    /*
      表单基本操作
    */
    var vm = new Vue({
        el: '#app',
        data: {
            uname: 'lisi',
            gender: 2,
            hobby: ['2','3'],
            // occupation: 3
            occupation: ['2','3'],
            desc: 'nihao'
        },
        methods: {
            handle: function(){
                // console.log(this.uname)
                // console.log(this.gender)
                // console.log(this.hobby.toString())
                // console.log(this.occupation)
                console.log(this.desc)

            }
        }
    });
</script>
</body>
</html>

 

表单域修饰符
  • number : 转化为数值
  • trim : 去掉开始和结尾的空格
  • lazy: 将input事件切换为change事件
<input v-model.nunber="age" type="number">
<input v-model.trim ="age" type="trim ">
<input v-model.lazy="age" type="lazy">
自定义指令

为什么需要自定义指令?

​ 内置指令不满足需求

语法规则(获取元素焦点)

vue.directive ('focus'{
	inserted: function (el){
        //获取元素的焦点
        el.focus ();
	}
})

用法

<input type='text' v-focus>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<div id="app">
    <input type="text" v-focus>
    <input type="text">
</div>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
    /*
      自定义指令
    */
    Vue.directive('focus', {
        inserted: function(el){
            // el表示指令所绑定的元素
            el.focus();//定位到元素
        }
    });
    var vm = new Vue({
        el: '#app',
        data: {

        },
        methods: {
            handle: function(){

            }
        }
    });
</script>
</body>
</html>

 

带参数的自定义指令(改变元素背景色)

vue.directive ('color'{
	inserted: function (el,binding){
        el.style.backgroundColor = binding.value.color;
	}
})

用法

<input type='text' v-color='{color:"orange"}'>

 

局部指令

directives : {
	focus: {
		//指令的定义
		inserted: function (el){
			el.focus ()
		}
	}
}

 

计算属性

为何需要计算属性?
表达式的计算逻辑可能会比较复杂,使用计算属性可以使模板内容更加简洁

computed: {
	reversedMessage: function(){
		return this.msg.split('').reverse().join('');
	}
}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<div id="app">
    <div>{{msg}}</div>
    <div>{{reverseString}}</div>
</div>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
    /*
      计算属性
    */
    var vm = new Vue({
        el: '#app',
        data: {
            msg: 'qwer'
        },
        computed: {
            reverseString: function(){
                return this.msg.split('').reverse().join('');
            }
        }
    });
</script>
</body>
</html>

 

计算属性和方法的区别

  • 计算属性 : 缓存
  • 方法 : 不缓存

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<div id="app">
    <div>{{reverseString}}</div>
    <div>{{reverseString}}</div>
    <div>{{reverseMessage()}}</div>
    <div>{{reverseMessage()}}</div>
</div>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
    /*
      计算属性与方法的区别:计算属性是基于依赖进行缓存的,而方法不缓存
    */
    var vm = new Vue({
        el: '#app',
        data: {
            msg: 'qwer',
            num: 100
        },
        methods: {
            reverseMessage: function(){
                console.log('methods')
                return this.msg.split('').reverse().join('');
            }
        },
        computed: {
            reverseString: function(){
                console.log('computed')
                // return this.msg.split('').reverse().join('');
                var total = 0;
                for(var i=0;i<=this.num;i++){
                    total += i;
                }
                return total;
            }
        }
    });
</script>
</body>
</html>

 

侦听器

应用场景

数据变化时执行异步或开销比较大的操作

 

用法

watch: {
	firstName: function (val){
		//val表示变化之后的值
		this.fullName = val + this.lastName ;
    },
	lastName: function (val) {
		this.fullName = this.firstName + val;
	}
}
  • 通过v-model实现数据绑定

  • 需要提供提示信息

  • 需要侦听器监听输入信息的变化

  • 需要修改触发的事件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<div id="app">
    <div>
        <span>用户名:</span>
        <span>
        <input type="text" v-model.lazy='uname'>
      </span>
        <span>{{tip}}</span>
    </div>
</div>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
    /*
      侦听器
      1、采用侦听器监听用户名的变化
      2、调用后台接口进行验证
      3、根据验证的结果调整提示信息
    */
    var vm = new Vue({
        el: '#app',
        data: {
            uname: '',
            tip: ''
        },
        methods: {
            checkName: function(uname) {
                // 调用接口,但是可以使用定时任务的方式模拟接口调用
                var that = this;
                setTimeout(function(){
                    // 模拟接口调用
                    if(uname == '111') {
                        that.tip = '用户名已经存在,请更换一个';
                    }else{
                        that.tip = '用户名可以使用';
                    }
                }, 2000);
            }
        },
        watch: {
            uname: function(val){
                // 调用后台接口验证用户名的合法性
                this.checkName(val);
                // 修改提示信息
                this.tip = '正在验证...';
            }
        }
    });

</script>
</body>
</html>

 

过滤器

作用

格式化数据,比如将字符串格式化为首字母大写,将日期格式化为指定的格式

自定义过滤器

Vue.filter('过滤器名称',function(value)){
	//过滤器业务逻辑           
}

使用

<div>{ {msg l upper} }</div>
<div>{ {msg / upper | lower} }</ div>
<div v-bind:id="id | formatId"></div>

局部过滤器

filters:{
	capitalize: function() }
}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<div id="app">
    <input type="text" v-model='msg'>
    <div>{{msg | upper}}</div>
    <div>{{msg | upper | lower}}</div>
    <div :abc='msg | upper'>测试数据</div>
</div>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
    /*
      过滤器
      1、可以用与插值表达式和属性绑定
      2、支持级联操作
    */
    // Vue.filter('upper', function(val) {
    //   return val.charAt(0).toUpperCase() + val.slice(1);
    // });
    Vue.filter('lower', function(val) {
        return val.charAt(0).toLowerCase() + val.slice(1);
    });
    var vm = new Vue({
        el: '#app',
        data: {
            msg: ''
        },
        filters: {
            upper: function(val) {
                return val.charAt(0).toUpperCase() + val.slice(1);
            }
        }
    });
</script>
</body>
</html>

 

带参数的过滤器

Vue.filter( 'format', function (value, arg1){
	//value就是过滤器传递过来的参数
})

使用

<div>{{date | format( 'yyyy-MM-dd ')}}</div>


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<div id="app">
    <div>{{date | format('yyyy-MM-dd hh:mm:ss')}}</div>
</div>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
    /*
      过滤器案例:格式化日期
      
    */
    // Vue.filter('format', function(value, arg) {
    //   if(arg == 'yyyy-MM-dd') {
    //     var ret = '';
    //     ret += value.getFullYear() + '-' + (value.getMonth() + 1) + '-' + value.getDate();
    //     return ret;
    //   }
    //   return value;
    // })
    Vue.filter('format', function(value, arg) {
        function dateFormat(date, format) {
            if (typeof date === "string") {
                var mts = date.match(/(\/Date\((\d+)\)\/)/);
                if (mts && mts.length >= 3) {
                    date = parseInt(mts[2]);
                }
            }
            date = new Date(date);
            if (!date || date.toUTCString() == "Invalid Date") {
                return "";
            }
            var map = {
                "M": date.getMonth() + 1, //月份
                "d": date.getDate(), //日
                "h": date.getHours(), //小时
                "m": date.getMinutes(), //分
                "s": date.getSeconds(), //秒
                "q": Math.floor((date.getMonth() + 3) / 3), //季度
                "S": date.getMilliseconds() //毫秒
            };

            format = format.replace(/([yMdhmsqS])+/g, function(all, t) {
                var v = map[t];
                if (v !== undefined) {
                    if (all.length > 1) {
                        v = '0' + v;
                        v = v.substr(v.length - 2);
                    }
                    return v;
                } else if (t === 'y') {
                    return (date.getFullYear() + '').substr(4 - all.length);
                }
                return all;
            });
            return format;
        }
        return dateFormat(value, arg);
    })
    var vm = new Vue({
        el: '#app',
        data: {
            date: new Date()
        }
    });
</script>
</body>
</html>

 

生命周期

主要阶段

  • 挂载(初始化相关属性)

    • beforeCreate
    • created
    • beforeMount
    • mounted
  • 更新(元素或组件的变更操作)

    • beforeUpdateupdated
  • 销毁(销毁相关属性)

    • beforeDestroy

    • destroyed


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<div id="app">
    <div>{{msg}}</div>
    <button @click='update'>更新</button>
    <button @click='destroy'>销毁</button>
</div>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
    /*
      Vue实例的生命周期
      
    */
    var vm = new Vue({
        el: '#app',
        data: {
            msg: '生命周期'
        },
        methods: {
            update: function(){
                this.msg = 'hello';
            },
            destroy: function(){
                this.$destroy();
            }
        },
        //挂载阶段
        beforeCreate: function(){
            console.log('beforeCreate');
        },
        created: function(){
            console.log('created');
        },
        beforeMount: function(){
            console.log('beforeMount');
        },
        mounted: function(){
            console.log('mounted');
        },
        //更新阶段
        beforeUpdate: function(){
            console.log('beforeUpdate');
        },
        updated: function(){
            console.log('updated');
        },
        //销毁阶段
        beforeDestroy: function(){
            console.log('beforeDestroy');
        },
        destroyed: function(){
            console.log('destroyed');
        }
    });
</script>
</body>
</html>

 

Vue实例的产生过程

生命周期钩子解释
beforeCreate在实例初始化之后,数据观测和事件配置之前被调用
created在实例创建完成后被立即调用
beforeMount在挂载开始之前被调用
mounted el被新创建的vm.$el替换,并挂载到实例上去之后调用该钩子
beforeUpdate数据更新时调用,发生在虚拟DOM打补丁之前
updated由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子
beforeDestroy实例销毁之前调用
destroyed实例销毁后调用

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值