onereal

Vue.js教程

https://www.runoob.com/try/try.php?filename=vue2-hw

在线编辑器

一、Vue 最火的前端框架  Angular.js  React.js最流行,可以用于手机app开发,三大框架; 关注视图层;

    1)提升开发效率;js=>Jquery=>前端模板引擎=>框架帮助减少不必要的DOM操作,通过双向数据绑定;

    2)框架和库的区别:

        框架提供完整的解决方案;项目开发后不易切换

        库只是单一的小功能,插件;容易切换;

    3)Vue结构

    <div id='app'>

        <p>{{ msg}}</p>

      </div>

    <script>

                    vm = new Vue(){

            el:'#app'

            data:{

                        msg:"123"

                    }

                }

       </script> 

二、1)、Vue指令;

        [v-cloak]可以解决插值闪烁的问题;可以前后添加字符串,

        [v-text]默认无闪烁问题;会覆盖元素中原有的内容

        [v-text]可以渲染html数据,会覆盖元素中原有的内容

        v-bind 用于绑定属性的指令;可以js运算 v-bind:title=

        v-bind可以简写为:要绑定的属性;

        

        v-on:用来绑定事件:  v-on:click="show"

                                 v-on:mouseover= 浏览器操作都可以定义;

            可以缩写: @clcik=show

    2)、文字走马灯:    

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>

<script src="https://cdn.bootcss.com/vue/2.4.0/vue.js"></script>

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>

</head>

<body>

<div id="app">

<input type="button" value = "run" @click = "run">

<input type="button" value = "stop" @click = "stop">

  <h2>{{ msg }}</h2>

</div>


<script>

var vm = new Vue({

  el: '#app',

  data: {

    msg: '勤劳勇敢的中国人,加油!!',

intervalId:null

  },

methods:{

run(){

<!-- var _this = this

setInterval(function(){

//console.log(this.msg)

var start= _this.msg.substring(0,1)  //获取首字符

var end = _this.msg.substring(1)  //获取1到结尾的字符

_this.msg = end + start

},400)//原始写法

 -->


if(this.intervalId !=null) return;

this.intervalId =setInterval(()=>{   //箭头函数简写法,外部指向和内部指向一致

var start= this.msg.substring(0,1)  //获取首字符

var end = this.msg.substring(1)  //获取1到结尾的字符

this.msg = end + start

},400)

},

stop(){

clearInterval(this.intervalId)

this.intervalId = null;//停止后赋值开关状态

}

}

})

</script>

</body>

</html>


三、事件修饰符

    1、.stop  阻止后续所有元素冒泡;

    2、.prevent 阻止默认事件行为

    3、 .capture 捕获触发事件机制(从外到里执行事件)

    4、 .self 只有点击当前元素自身才触发事件

    4、 .once 只触发一次事件


四、v-model 双向数据绑定

        1、v-model 可以实现表单的双向绑定

<body>

<div id="app">

<h4>{{msg}}</h4>

<!-- <input type = "text" v-bind:value= "msg" style="width:100%;"> v-bind 只能单向绑定 M->V -->

 <input type = "text" v-model:value= "msg" style="width:100%;"> <!--v-model 可以实现表单的双向绑定 M->V -->

    </div>

<script>

    var vm = new Vue({

      el: '#app',

      data: {

        msg: '勤劳勇敢的中国人,加油!!',

      },

    methods:{

    }

    });

</script>

</body>

       --------------------------------

    2、简易计算器案例

五、Vue中使用样式:

    1、数组中绑定,直接传值;

<style>

        .thin{

            font-weight: 200;

        }

        .italic{

            font-style:italic;

        }

        .red{

           color: red;

        }

        .active{

            letter-spacing: 0.5em;

        }

</style>

<body>

           <h1  :class="['thin','ltalic','active']">

</body>

    2、数组中使用三元表达式

            <h1  :class="['thin','ltalic',flag?'active':'']">

<script>

var vm = new Vue({

  el: '#app',

  data: {

   flag:true     //false

  },

    methods:{

    }

    });

</script>

3、在数组中使用三元表达式,可读性更强;

          <h1  :class="['thin','ltalic',{'active':flag}]">

 4、直接使用对象

      <h1  :class= stylobj"{red:true,this:true,italic:false,active:false}">

     或:

 <h1  :class= "stylobj" ></h1>

     <script>

var vm = new Vue({

  el: '#app',

  data: {

   stylobj:{

                red:true,

                this:true,

                italic:false,

                active:false}

            }    

      },

    methods:{

    }

    });

</script>



5、通过属性绑定为元素绑定为元素绑定style行内样式

      <h1  :style="{color:'red'},'font-weight':200}">


或者

 <h1  :class= "stylobj" ></h1>

     <script>

var vm = new Vue({

  el: '#app',

  data: {

   stylobj:{   color:'red','font-weight':200          }    

      },

    methods:{

    }

    });

</script>


六、v-for循环指令 :for循环

(一)普通数组:

   1、方式1:

<body>

    <div id="app">

        <p v-for = "item in list">{{item}}</p>

<input type="button" value = "stop" @click = "cl">

    </div>

<script>

    var vm =new Vue({

            el:'#app',

            data: {

                list: [1,2,3,4,5,6]

        },

            methods: {

cl(){alert('hehe')

}

}

        });

</script>


2、方式2

<script src="https://cdn.bootcss.com/vue/2.4.0/vue.js"></script>

</head>

<body>

    <div id="app">

        <p v-for = "(item,i) in list">索引值:{{i}}<

===>每一项:{{item}}</p>

<input type="button" value = "stop" @click = "cl">

    </div>


<script>

    var vm =new Vue({

            el:'#app',

            data: {

                list: [1,2,3,4,5,6]

        },

            methods: {

cl(){alert('hehe')

}

}

        });

</script>

</body>

(二)、循环对象数组:

<body>

    <div id="app">

       <!-- <p v-for = "user in list">Id:{{user.id}}

…………姓名:{{user.name}}</p>-->

 <p v-for = "(user,i) in list">Id:{{user.id}}

…………姓名:{{user.name}}---index:{{i}}</p>

<input type="button" value = "stop" @click = "cl">

    </div>


<script>

    var vm =new Vue({

            el:'#app',

            data: {

                list: [

{id:01,name:'张三'},

{id:02,name:'lisi'},

{id:03,name:'王五'},

{id:04,name:'赵六'},

{id:05,name:'陈七'}

]

        },

            methods: {

cl(){alert('hehe')

}

}

        });

</script>

</body>

(三)、循环对象

<body>

    <div id="app">

    <p v-for = "(val,key,i) in user">Index:{{i}}---Value:{{val}}

…………Key:{{key}}---</p>

<input type="button" value = "stop" @click = "cl">

    </div>


<script>

    var vm =new Vue({

            el:'#app',

            data: {

                user:{

id:1,

name: 'tom moby',

gender:'男'

}

        },

            methods: {

cl(){alert('hehe')

}

}

        });

</script>

</body>

(四)、数字迭代

<body>

    <div id="app">

    <p v-for = "item  in 10">第{{item}}项  <!--从1开始-->

</p>

(五)、v-for循环中key属性的使用

<body>

    <div id="app">

<div>

 <label>Id:

<input type="text" v-model="id">

</label>

<label>Name:

<input type="text" v-model="name">

</label>

<input type="button" value= "添加" @click="add">

</div>

    <p v-for = "item  in list" :key="item.id">

<input type="checkbox" >{{item.id}}----{{item.name}}

 </p>

    </div>

<script>

    var vm =new Vue({

            el:'#app',

            data: {

id:'',

name:'',

                list:[

{id:1,name:'张飞'},

{id:2,name:'关羽'},

{id:3,name:'鲁肃'},

{id:4,name:'周瑜'},

{id:5,name:'张辽'}   

      ]

        },

            methods: {

add(){

//this.list.push({id:this.id, name: this.name})

this.list.unshift({id:this.id, name: this.name})

}

}

        });

</script>

</body>


——————————

v-for循环的时候,key属性只能使用number提取string

key在使用的时候,必须使用v-bind属性绑定的形式,指定key的值

在组件中,使用v-for循环的时候,或者特殊情况中,如果v-for有问题,必须在使用v-for时,指定唯一的字符串/数字 类型 :key 值


七、v-if

(一):

<body>

<div id="app">

<!-- <input type="button" value="toggle" @click="toggle"> -->

 <input type="button" value="toggle" @click="flag=!flag">  <!--  简写-->

  <p v-if="flag">this is controlled by v-if<p>

  <p v-show="flag">this is controlled by v-SHOW</p>

</div>


<script>

new Vue({

  el: '#app',

  data: {

    flag: true

  },

methods:{

toggle(){

this.flag =!this.flag

}

}

});

</script>

</body>

    v-if 特点:删除或创建元素,较高的性能消耗

    v-show 特点:不删除或创建元素;只是切换了dispaly:none dispaly:show  较高的初始性能消耗;切换频繁宜用这个。

   (二)、案例:品牌添加删除

<body>

<div id="app">

<div class= "panel panel-primary">

<div class= "panel-heading">

<h3 class="panel-title">添加品牌</h3>

</div>

<div class= "panel-body form-inline">

<label>

Id:

<input type="text" class="form-control" v-model="id">

</label>

<label>

Name:

<input type="text" class="form-control" v-model="name">

</label>

<input type="button" value="添加" class="btn btn-primary" @click="add" >

</div>

</div>

<table class="table table-bordered table-hover table-striped" >


  <thead>

<tr>

  <th>ID</th>

  <th>Name</th>

  <th>Ctime</th>

  <th>Opertation</th>  

</tr>

  </thead>

  <tbody>

<tr v-for = "item in list" :key="item.id">

  <td>{{ item.id }}</td>

  <td v-text="item.name"> </td>

  <td>{{ item.ctime }}</td>

  <td>

<a href="" @click.prevent="del(item.id)" >删除</a>

  </td>

</tr>

  </tbody>

</table>

</div>


<script>

new Vue({

  el: '#app',

  data: {

  id:'',

  name:'',

    list:[

{id:1,name:'奔驰',ctime:new Date()},

{id:2,name:'宝马',ctime:new Date()},

{id:3,name:'卡迪拉克',ctime:new Date()}

]

  },

methods:{

add(){

var car= {id: this.id,name:this.name,ctime: new Date()}

this.list.push(car)

this.id = ''

this.name= ''

},

del(id){

/* this.list.some((item,i)=>{   //方法1

if(item.id == id){

this.list.splice(i,1)

return true;

}  

}) */

    var index =this.list.findIndex(item=>{//方法2

if(item.id == id){

return true;

}  

}) 

   this.list.splice(index,1)

}

}

});

</script>

</body>


(二)过滤器

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>Vue 品牌列表(runoob.com)</title>

<script src="https://cdn.bootcss.com/vue/2.4.0/vue.js"></script>

<link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet">

</head>

<body>

<div id="app">

<div class= "panel panel-primary">

<div class= "panel-heading">

<h3 class="panel-title">添加品牌</h3>

</div>

<div class= "panel-body form-inline">

<label>

Id:

<input type="text" class="form-control" v-model="id">

</label>

<label>

Name:

<input type="text" class="form-control" v-model="name">

</label>

<input type="button" value="添加" class="btn btn-primary" @click="add" >

<label>

搜索:

<input type="text" class="form-control" v-model="keywords">

</label>

</div>

</div>

<table class="table table-bordered table-hover table-striped" >


  <thead>

<tr>

  <th>ID</th>

  <th>Name</th>

  <th>Ctime</th>

  <th>Opertation</th>  

</tr>

  </thead>

  <tbody>

<!-- <tr v-for = "item in list" :key="item.id">     仅能列表-->

<tr v-for = "item in search(keywords)" :key="item.id">

  <td>{{ item.id }}</td>

  <td v-text="item.name"> </td>

  <td>{{ item.ctime | dateFormat('')}}</td>    <!-- dateFormat('yyyy-mm-dd')-->

  <td>

<a href="" @click.prevent="del(item.id)" >删除</a>

  </td>

</tr>

  </tbody>

</table>

</div>


<script>

Vue.filter('dateFormat',function(dateStr,pattern=""){  //第二参数决定时间格式

var dt=new Date(dateStr)

var y = dt.getFullYear()

var m = dt.getMonth() + 1

var d = dt.getDate()

if(pattern && pattern.toLowerCase() === 'yyyy-mm-dd'){

return `${y}-${m}-${d}`     //`  ~的同位键  非' 构成魔法字符串

}else{

var hh = dt.getHours()

var mm = dt.getMinutes()

var ss = dt.getSeconds()

return `${y}-${m}-${d} ${hh}:${mm}:${ss}`  

}

})   //全局过滤器 :所有实例都可以共享




new Vue({

  el: '#app',

  data: {

  id:'',

  name:'',

  keywords:'',

  

    list:[

{id:1,name:'奔驰',ctime:new Date()},

{id:2,name:'宝马',ctime:new Date()},

{id:3,name:'卡迪拉克',ctime:new Date()},

]

  },

methods:{

add(){

var car= {id: this.id,name:this.name,ctime: new Date()}

this.list.push(car)

this.id = ''

this.name= ''

},

del(id){

/* this.list.some((item,i)=>{   //方法1

if(item.id == id){

this.list.splice(i,1)

return true;

}  

}) */

    var index =this.list.findIndex(item=>{//方法2

if(item.id == id){

return true;

}  

}) 

   this.list.splice(index,1)

},

search(keywords){

/*var newList = []

this.list.forEach(item=>{

if(item.name.indexOf(keywords) != -1){

newList.push(item)

}

})  

return newList


*/

returnthis.list.filter(item =>{

if(item.name.includes(keywords)){

return item

}

})

}

},

//私有过滤器  过滤器:名称 处理函数   通道符调用时先局部后全局

filters:{

dateFormat: function(dateStr,pattern=""){ 

var dt=new Date(dateStr)

var y = dt.getFullYear()

var m = dt.getMonth() + 1

var d = dt.getDate()

if(pattern && pattern.toLowerCase() === 'yyyy-mm-dd'){

return `${y}-${m}-${d}`     //`  ~的同位键  非' 构成魔法字符串

}else{

var hh = dt.getHours()

var mm = dt.getMinutes()

var ss = dt.getSeconds()

return `${y}-${m}-${d} ${hh}:${mm}:${ss}~`  

}

}

}

});

</script>

</body>

</html>

(三)padStart(2,'0')    //用0补足数位到2位   padEnd

      .toString().padStart(2,'0')


(四)绑定键盘事件

<input type="text" class="form-control" v-model="name" @keyup.enter="add" >

内置监听键  .enter

                    .tab

                    .delete

                    .esc

                    .space

                    .up .down .left .right

 其他按键,可以用码值, 如f2==> 113

<input type="text" class="form-control" v-model="name" @keyup.e113="add" >

 自定义全局装饰符,还可以自定义 码值和键对应

Vue.config.keyCodes.f4 = 115

(五).focus

document.getElementById('search').focus();  原生方法不建议使用

  自定义指令 

Vue.directive()  //参数1:指令名称,无需v-,调用必需v-;参数2:对象,有一些指令相关的钩子函数:bind inserted update  componentUpdated unbind


<input type="text" class="form-control" v-model="keywords" v-focus  v-color>

<script>

Vue.directive('color',{

    inserted:function(el){

        el.focus()

        //和js行为相关的操作一般在inserted中执行

}

})


Vue.directive('color',{

        bind:function(el){

el.style.color = 'red'

},


})


        //和样式相关的操作一般在bind中执行



</script>

-----------------------------

   自定义指令,颜色传参

<input type="text" class="form-control" v-model="keywords" v-focus v-color ="'blue'">

Vue.directive('color',{

bind:function(el,binding){

    el.style.color = binding.value

    },

})

----------------------------------------------------

   

(六)私有指令   v-fontsize  v-fontweight调用

directives: {   //自定义私有指令

'fontweight':{

bind: function (el,binding){  //binding接受参数

el.style.fontWeight = binding.value

}

},

'fontsize': function(el,binding) {   //简写方式

el.style.fontSize = parseInt(binding.value) + 'px'

}

}


七、vue实例的生命周期:

        生命周期钩子=生命周期函数=生命周期事件

   //创建一个vue实例对象

     var vm=new Vue({  

     el:'#app',

data:    {

        msg: 'ok',

        },

methodes: {

    

    },

beforeCreate() {   //第一个生命周期函数


},

created() {   //第二个生命周期函数


},

//下为第三个生命周期函数

beforeMount() {   //模板已经在内存中编译完成,尚未把模板渲染到页面中


},

//下为第四个生命周期函数

    mounted() {   //把编译好的模板放到页面中,用户可以看到最终页面


    }, //是实例创建期间最后一个生命周期函数,执行完后。实例已经完全创建好了。如无其他函数,这个实例则静静存储在内存中

   如要操作dom节点,应该在mounted中操作。执行完mounted,创建阶段已经结束,进入到运行阶段beforeUpdate() update()


    beforeUpdate(){


    },  //执行时,页面中显示的内容还是旧的,data数据是最新的,页面尚未和最新的数据同步

   updated(){   


    },   //此事件执行时,date和页面中的数据已经同步了

    beforeDestroy(){


    }, //执行此函数时未真正销毁

    destroyed){


    }, //执行此函数时真正销毁 


    }) 

(八)、vue-resouce ,axios第三方包实现get、 post、 json请求

<!DOCTYPE html>

<meta http-equiv="Access-Control-Allow-Origin" content="*" />

<html lang="en">

<head>

<meta charset="utf-8">

<title>Vue 品牌列表(runoob.com)</title>

<script src="https://cdn.bootcss.com/vue/2.4.0/vue.js"></script>

<script src="https://cdn.bootcss.com/vue-resource/1.3.4/vue-resource.js"></script>

<link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet">

</head>

<body>

<div id="app">

<div class= "panel panel-primary">

<div class= "panel-heading">

<h3 class="panel-title">添加品牌</h3>

</div>

<div class= "panel-body form-inline">

<label>

Id:

<input type="text" class="form-control" v-model="id">

</label>

<label>

Name:

<input type="text" class="form-control" v-model="name" >

</label>

<input type="button" value="添加" class="btn btn-primary" @click="add" >

<label>

搜索:

<input type="text" class="form-control" v-model="keywords">

</label>

</div>

</div>

<table class="table table-bordered table-hover table-striped" >


  <thead>

<tr>

  <th>ID</th>

  <th>Name</th>

  <th>Ctime</th>

  <th>Opertation</th>  

</tr>

  </thead>

  <tbody>

<!-- <tr v-for = "item in list" :key="item.id">     仅能列表-->

<tr v-for = "item in search(keywords)" :key="item.id">

  <td>{{ item.id }}</td>

  <td v-text="item.name"> </td>

  <td>{{ item.ctime | dateFormat('')}}</td>    <!-- dateFormat('yyyy-mm-dd')-->

  <td>

<a href="" @click.prevent="del(item.id)" >删除</a>

  </td>

</tr>

  </tbody>

</table>

</div>


<script>

Vue.http.options.root = 'https://192.168.1.4';


Vue.filter('dateFormat',function(dateStr,pattern=""){  //第二参数决定时间格式

var dt=new Date(dateStr)

var y = dt.getFullYear()

var m = dt.getMonth() + 1

var d = dt.getDate()

if(pattern && pattern.toLowerCase() === 'yyyy-mm-dd'){

return `${y}-${m}-${d}`     //`  ~的同位键  非' 构成魔法字符串

}else{

var hh = dt.getHours()

var mm = dt.getMinutes()

var ss = dt.getSeconds()

return `${y}-${m}-${d} ${hh}:${mm}:${ss}`  

}

})   //全局过滤器 :所有实例都可以共享




new Vue({

  el: '#app',

  data: {

  id:'',

  name:'',

  keywords:'',

  

    list:[

{id:1,name:'奔驰',ctime:new Date()},

{id:2,name:'宝马',ctime:new Date()},

{id:3,name:'卡迪拉克',ctime:new Date()},

]

  },

  

  created(){   //页面加载调用数据

this.getAllList()

  

},

  

  

methods:{

add1(){

var car= {id: this.id,name:this.name,ctime: new Date()}

this.list.push(car)

this.id = ''

this.name= ''

},

add(){

this.$http.post('api/carsvuecrud/api.php?action=create',{name:this.name},{emulateJSON:true})

.then(result =>{                                             //参数3 {emulate 可以配置启用全局后省略 Vue.http.options.emulateJSON =true;

var result = result.body

if (result.status === 0){

this.getAllList()

//this.list =result.message

}else{

alert('获取数据失败')

}

})

},

getAllList(){   //获取服务器数据库中品牌的列表

this.$http.get('api/carsvuecrud/api.php?action=read')

.then(result =>{

var result = result.body

if (result.status === 0){

this.list =result.message

}else{

alert('获取数据失败')

}

})

},

del(id){

this.$http.get('api/carsvuecrud/api.php?action=delete&id=' + id)  //启用全局根地址后可以简写

//this.$http.get('https://192.168.1.4/api/carsvuecrud/api.php?action=delete&id=' + id)

//不成功this.$http.post('https://192.168.1.4/api/carsvuecrud/api.php?action=delete' , {id:this.id},{emulateJSON:true})

.then(result =>{

var result = result.body

if (result.status === 0){

this.getAllList()

alert('删除成功')

}else{

alert('删除失败')

}

})

   this.list.splice(index,1)

},

search(keywords){

/*var newList = []

this.list.forEach(item=>{

if(item.name.indexOf(keywords) != -1){

newList.push(item)

}

})  

return newList


*/

returnthis.list.filter(item =>{

if(item.name.includes(keywords)){

return item

}

})

}

},

//私有过滤器  过滤器:名称 处理函数   通道符调用时先局部后全局

filters:{

dateFormat: function(dateStr,pattern=""){ 

var dt=new Date(dateStr)

var y = dt.getFullYear()

var m = (dt.getMonth() + 1).toString().padStart(2,'0')

var d = dt.getDate().toString().padStart(2,'0')

if(pattern && pattern.toLowerCase() === 'yyyy-mm-dd'){

return `${y}-${m}-${d}`     //`  ~的同位键  非' 构成魔法字符串

}else{

var hh = dt.getHours().toString().padStart(2,'0')

var mm = dt.getMinutes().toString().padStart(2,'0')

var ss = dt.getSeconds().toString().padStart(2,'0')

return `${y}-${m}-${d} ${hh}:${mm}:${ss}`  

}

}

}

});

</script>

</body>

</html>

(九)、Vue动画




评论