腾讯课堂“前端名师带你学习vue2.0前端框架【爱创课堂】”学习笔记
在Vue中:
Vue通过MVVM模式实现了项目代码的可维护性、可拓展性、安全性。而jQuery这样的框架没有实现对业务逻辑的分层,可维护性、可拓展性、安全性较差。而Backbone这样的框架虽然对业务逻辑进行了拆分(模型,视图,控制器),可以更好的管理项目,但是开发效率极低。
原生JS
<div id="app">div>
<script type="text/javascript">
//获取元素
var app=document.getElementById('app')
//设置内容
app.innerHTML='看电视呢'
//设置某一时刻更新
setTimeout(function(){
app.innerHTML='和大家是否'
},2000)
script>
jQuery
<div id="app">div>
<script type="text/javascript" src="jquery.js">script>
<script type="text/javascript">
$('#app').html('看电视呢')
setTimeout(function(){
$('#app').html('和大家是否')
},2000)
script>
Vue
<div id="app">{{msg}}div>
<script type="text/javascript" src="vue.js">script>
<script type="text/javascript">
//Model,设置数据
var data={
msg:'看电视呢'
}
//ViewModel,双向绑定数据
var app = new Vue({
el: "#app",//绑定视图
data:data//绑定数据
})
//直接获取数据进行操作
setTimeout(function(){
data.msg='和大家是否'
},2000)
script>
el属性实现将视图绑定给vue实例化对象,其属性值可以是常用的css选择器,如id选择器、类选择器、标签选择器、自定义标签选择器等。注:其中自定义标签选择器是为组件使用的,否则为报警告!如果一个vue实例化对象对应多个选择器,渲染第一个,后边的会被忽略掉,所以一定是一个选择器对应一个vue实例化对象(在一个项目中,尽量只有一个vue实例化对象)!
<div id="app">{{msg}}div>
<div class="ickt">{{msg}}div>
<h1>{{msg}}h1>
<ickt>{{msg}}ickt>
<div class="ickt">{{msg}}div>
<script type="text/javascript" src="vue.js">script>
<script type="text/javascript">
//Model,设置数据
var data={
msg:'看电视呢'
}
//ViewModel,双向绑定
var app = new Vue({
// el: "#app",
el:'.ickt',
// el:'h1',
// el:'ickt',
data:data
})
//直接获取数据进行操作
setTimeout(function(){
data.msg='和大家是否'
},2000)
script>
data属性实现将模型中的数据绑定给vm(vue实例化对象),两种方法绑定:1.将数据直接存在_data中;2.将数据对象单独定义,并将数据中的每一个属性及其值绑定给vue实例化对象,不区分类型始终保持同步,(而传统对象的‘绑定’:值类型复制两份,互不影响;引用类型引用,即是同一份数据)
数据丢失:
解决数据丢失的方法:
对于视图数据丢失,见实例中的解决方案;
对于模型数据丢失,在绑定之前先定义出属性(可不赋值)即可解决数据丢失。
<script type="text/javascript" src="vue.js">script>
<script type="text/javascript">
//Model,设置数据
var data={
msg:'看电视呢',
arr:[1,2,3],
obj:{
title:'Vue'
}
}
//ViewModel,双向绑定数据
var app = new Vue({
el: "#app"
data:data//将传统的data数据对象的属性及其值绑定给vue
})
//分别修改数据对象和vue实例化对象即为修改同一份属性值,不区分类型,始终保持同步
data.msg='hello'
data.obj.title='world'
app.arr=['red','blue']
console.log(app.msg)//=>hello
console.log(app.obj.title)//=>world
console.log(data.arr)//=>['red','blue']
//为vue实例化对象添加一个新(直接)属性
app.mycolor='red'
console.log(data.mycolor)//=>undefined
//为数据对象添加一个新(直接)属性
data.color='blue'
console.log(app.color)//=>undefined
//添加一个新(间接)属性
app.obj.num=300
app.arr[3]='yellow'
console.log(data.obj.num)//=>300
console.log(data.arr)//=>['red','blue',empty,'yellow']
script>
<script type="text/javascript">
//传统对象
var data ={
color:'red',//值类型属性
obj:{ //引用类型属性
num:100,
arr:[1,2,3]
}
}
//‘绑定’对象
var test={}
test.color=data.color
test.obj=data.obj
data.color='green'//分别修改两个数据对象的值类型属性互不影响
data.obj.num=200//分别修改两个数据对象的引用类型属性即为修改同一份属性值,始终保持同步
console.log(test)//=>test.color:'red',test.obj.num:200
script>
数据的绑定是单向的,数据流只能从模型流向视图,而要从视图流向模型需要事件监听,注:不同的对象一定不要重名
<script type="text/javascript" src="vue.js">script>
<script type="text/javascript">
//Model,设置数据
var data={
msg:'看电视呢'
}
//ViewModel,双向绑定
var app = new Vue({
el: "#app",
data:data//传统的data数据对象的属性及其值绑定给vue
})
//修改视图中的数据,模型中的数据不改变
var view=document.getElementById('app')
setTimeout(function(){
view.innerHTML='和大家是否'
},2000)
console.log(app.msg)//=>看电视呢
console.log(data.msg)//=>看电视呢
//var app=document.getElementById('app')//此处的app会和vue实例化对象重名,导致vue实例化对象被覆盖
//setTimeout(function(){
// app.innerHTML='和大家否'
//},2000)
//console.log(app.msg)//=>undefined
script>
插值的作用是将vm中的数据渲染到页面中,语法:{{插值内容}}。插值语法提供了一个js环境,因此可以在插值语法内使用js表达式。
而目前的vue2.0不支持属性插值,要使用属性插值时需用v-bind指令,可以让属性值变成一个js环境,这样就能够使用vm中的数据变量。
语法糖是指对某个功能的简化,例如v-bind指令的语法糖是“ : ”。
<div id="app">
<h1 :style="{color: color}" :title="msg">{{msg.toUpperCase()}}h1>
<h2>面积:{{width*height}}h2>
div>
<script type="text/javascript" src="vue.js">script>
<script type="text/javascript">
var data={
msg:'Hello world',
color:'red',
width:100,
height:200
}
var app = new Vue({
el: "#app",
data:data
})
script>
渲染页面的时候,有两次可以更改数据的时间点:
若要在data绑定的数据获取之后,页面渲染过程中,修改数据,只能通过插值表达式或者插值过滤器来修改,如上代码‘ {{msg.toUpperCase()}} ’。数据是在模板中修改,只能在模板中应用。
若要在数据获取之前将其改变,就可以使用动态数据绑定的语法。数据是在获取之前修改,可以应用到任何地方。
相对于动态数据绑定来说,通过data绑定的数据是静态绑定的,两者语法相似。都会将数据直接添加给vue实例化对象
动态绑定是通过computed,和data一样,其属性值也是对象,包括两个对象成员:
value函数中获取vue中的数据有两种方式:
通过作用域this访问实例化对象,是面向对象的。
参数是vue实例化对象;作用域是vue实例化对象;返回值是获取的数据
<div id="app">
<h2>面积:{{size}}h2>
<h2>面积:{{size}}h2>
<h2>面积:{{width*height}}h2>
div>
<script type="text/javascript" src="vue.js">script>
<script type="text/javascript">
var data={
msg:'Hello world',
width:100,
height:200
}
var app = new Vue({
el: "#app",
data:data,
// 动态数据绑定
computed:{
//size表示属性名称,会添加给vue实例化对象
size:function(vm){
console.log(this,arguments)//虽然页面调用两次size,但此代码只执行一次,因为参数没有改变
return vm.width*vm.height
//return this.width*this.height
}
}
})
script>
数据由模型到视图(数据绑定和插值)
数据由视图到模型(事件监听)
vue提供了v-model指令,实现数据的双向绑定的功能。v-model的属性值就是绑定的数据,也是js环境,可以直接使用js表达式
<div id="app">
<h1>{{msg}}h1>
<input type="text" v-model="msg">
div>
<script type="text/javascript" src="vue.js">script>
<script type="text/javascript">
var app = new Vue({
//绑定视图
el: "#app",
//绑定数据
data:{
msg:'hello'
}
})
script>
在项目中时常会操作元素的类,因此我们要绑定类,有以下三种方式来绑定类:
v-bind:class=”字符串”
字符串中类之间要用空格隔开
由于**v-bind**指令的语法糖是“ :”,所以以上均可缩写为 ":class"。以上的括号或引号内,字符串加单引号,除了一些关键字(如true,null),变量不加
<style type="text/css">
.red{color: red;}
.green{color: green;}
.blue{color: blue;}
.bg-red{background: red;}
.bg-pink{background: pink}
.circle{border-radius: 30%;}
.fz-50{font-size: 50px}
h1{
height: 80px;
width: 300px;
}
style>
<div id="app">
<h1 :class="[cls,'bg-pink circle','fz-50']">hello worldh1>
<h1 :class="{
red:true,
'fz-50':true,
'bg-pink circle':100
}">hello worldh1>
<h1 :class="cls+' bg-pink'+' fz-50'">hello worldh1>
div>
<script type="text/javascript" src="vue.js">script>
<script type="text/javascript">
var app = new Vue({
el: "#app",
data:{
cls:'blue'
}
})
script>
跟类一样,会经常操作DOM的样式,有以下三种方式绑定样式:
<div id="app">
<h1 :style="[
{
color: 'orange',
background:bg
},
{
borderBottom:'2px solid red'
}
]">hello worldh1>
<h1 :style="{
borderBottom:bt,
color:'orange',
background:bg
}">hello worldh1>
<h1 :style="'border-bottom:2px solid red;background: pink;'+color">hello worldh1>
div>
<script type="text/javascript" src="vue.js">script>
<script type="text/javascript">
var vm = new Vue({
el: "#app",
data:{
bg:'pink',
bt:'2px dashed red',
color:'color:orange'
}
})
script>
可以控制标签元素是否创建。true表示创建标签;false表示删除标签元素(是真正的创建和删除,可不是设置display样式的显示或隐藏),创建v-else中的元素。
显示或隐藏标签元素,是设置的样式,而不是创建或删除元素,其原理是将样式切换到display:none
以上vue提供的指令都只能控制一个标签元素,想控制多个标签元素,vue建议我们使用H5中的模板标签template。
template的特点:是一个模板标签,跟普通的DOM元素一样,可以添加属性、样式等,唯一的区别是不会渲染到页面中(那还要添加样式干什么???)。
<style type="text/css">
.type{color: orange}
style>
<div id="app">
<template v-if="type">
<span class="type">{{type}}span>
<span class="type">|span>
template>
<template v-else>
<span>其他span>
<span>-span>
template>
<span>{{title}}span>
div>
<script type="text/javascript" src="vue.js">script>
<script type="text/javascript">
var vm = new Vue({
el: "#app",
data:{
type:'财经',
title:'开始的方式开发和首付款'
}
})
script>
循环创建DOM元素,有两种语法结构:
<div id="app">
<ul>
<template v-for="(item,index) in list">
<li :style="{background:index%2?'white':'grey'}">{{index}}-{{item}}li>
<br>
template>
ul>
div>
<script type="text/javascript" src="vue.js">script>
<script type="text/javascript">
var vm = new Vue({
el: "#app",
data:{
list:[
'JS',
'Vue',
'CSS'
]
}
})
script>
传值分为两种:子组件向父组件传值(事件传值);父组件向子组件传值(属性传值props)。
子组件向父组件传值
"changeTitle">
{{appTitle}}
...
//子组件中定义触发事件的方法
methods:{
changeTitle:function(){
this.$emit("titleChanged",this.title)//事件,参数
}
}
...
//父组件中绑定接收事件的方法
"updateTitle($event)">
...
methods:{
updateTitle(title){
this.title=title
}
}
...
父组件向子组件传值
...
//父组件中将子组件的props属性绑定上值
"users">
...
...
//子组件中定义props属性
props:['usersProps']
...
路由跳转的时候传递参数给下一个页面
...
//路首先进行由设置,:id为传递参数
{
path: '/menu/:id',
name: 'Menu',
component: Menu
}
...
...
//上一个页面中路由链接将要传递的参数写在path后边
"/menu/川渝风味">川渝风味
...
...
//下一个页面接收上一个页面传递的参数
data(){
return{
param:''
}
},
created(){
this.param=this.$route.params.id;
console.log(this.param)
}
...
Vue提供以下的函数,分别在页面渲染的不同时期执行
beforeCreate:function () {
alert('组件实例化之前')
},
created:function () {
alert('组件实例化完成,但页面还未显示')
},
beforeMount:function () {
alert('组件挂载前,页面仍未显示,但虚拟DOM已经配置')
},
mounted:function () {
alert('组件挂载完成,此方法执行后页面显示')
},
beforeUpdate:function () {
alert('组件更新前,页面仍未更新,但虚拟DOM已经配置')
},
updated:function () {
alert('组件更新,此方法执行后页面更新')
}
相比于a标签,每次点击都会刷新页面。路由做了优化,直接跳转不会请求刷新页面,使得性能更好。
如果要使用vue-resource的话首先得使用npm install vue-resource –save安装,然后在main.js中引入
import Resource from 'vue-resource'
Vue.use(Resource)
created:function () {
this.$http.get("http://jsonplaceholder.typicode.com/users").then((data)=>{//data为访问接口拿到的数据
this.users=data.body;
})
}