基础演示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue</title>
<script src="js/vue-2.4.0.js"></script>
</head>
<body>
<div id="d1">
<!-- {{}}单向绑定:该元素的值改变,属性值不改变;只是从属性中获得一个值-->
{{location.city}}{{location.area}}
{{month}}月
{{day}}日天气{{weather}}
<hr>
<!-- v-bind单向绑定:该元素的值改变,属性值不改变;只是从属性中获得一个值-->
<input type="text" v-bind:value="day">
<!-- v-model双向绑定:该元素的值改变,属性值也改变;-->
<input type="text" v-model="day">
<hr>
<input type="button" v-on:mouseover="add" value="增加" >
<input type="button" @click="decrease" value="减少">
</div>
</body>
<script type="text/javascript">
// vue自带对象:vue;
var vue = new Vue({
// el:"#元素id"--绑定元素,vue对象中的属性和方法可以渲染和运行的元素范围
"el":"#d1",
// data:当前vue实例的属性键值对
"data":{
month:"3",
day:"2",
weather:"晴朗",
location:{city:"上海",area:"宝山"}
},
"methods":{
add:function () {
//当前vue实例的属性引用:this.属性名
this.day++;
},
decrease:function () {
this.day--;
}
}
});
var sex = "男";
var person= {
stuname:"zoya",
age:23,
sex:"女",
show:function () {
//方法中调用实例对象的属性必须加this,不像java中默认银行一个this,JavaScript默认寻找的是同名全局变量而非本类属性。
console.log(this+"==="+this.age+sex);
}
};
person.show();
// [object Object]===23男
</script>
</html>
生命周期
初始化
1.初始化前 beforeCreated:一切数据还未准备
初始化:准备模型数据
1.初始化完成 created:模型中已有数据,页面元素中没有数据
渲染
2.挂载(渲染)前 beforeMount:模型中已有数据,但模板还没有内容(模板即el绑定的div元素)
渲染:将模型数据渲染到el
2.挂载(渲染)完成 mounted: 该方法执行完毕模板才渲染完成并显示
更新
3.内容改变前 beforeUpdate:开始重新渲染,执行此方法时模型中数据已经改变
3.内容改变前 updated:重新渲染完成,执行此方法时模型中数据已经改变
销毁
4.销毁前beforedestory:
销毁:擦除模型和元素之间的绑定关系,修改内容等行为不再执行任何功能
4.销毁后destroyed:
vue标签指令
插值表达式
绑定 v-bind
单向绑定,引用vue实例的属性(可以作用于任意标签)
标签属性:v-bind:value=“属性名”
{{}}
body位置直接写 {{属性名}}
v-text=“属性名”
将属性在标签中展示(若属性值中存在HTML代码,不解析,原样展示)
v-html=“属性名”
若属性值中存在HTML代码,解析后展示
双向绑定 v-model
仅作用于以下表单标签 :input select textarea checkbox radio components(vue自定义组件)
例:checkbox + 数组的双向绑定:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>calculator</title>
<script src="js/vue-2.4.0.js"></script>
</head>
<body>
<div id="d1">
<fieldset >
<legend>请选择:</legend>
<input type="checkbox" value="a" v-model="vas"/>a
<input type="checkbox" value="b" v-model="vas"/>b
<input type="checkbox" value="c" v-model="vas"/>c
<input type="checkbox" value="d" v-model="vas"/>d
</fieldset>
你选择了:{{vas}}
</div>
</body>
<script type="text/javascript">
var vue = new Vue({
"el":"#d1",
"data":{
vas:[]
}
});
</script>
</html>
如图框是fieldset标签,下设legend标签:fieldset标题
修饰符
事件修饰 prevent stop
.prevent 阻止默认行为
@keyup.enter.prevent=“a” enter键弹起时不执行默认提交行为,只执行a方法
.stop 防止 冒泡
事件冒泡:鼠标移入内部div,必然也会移入外部父div,如果二者都有移入事件,移入内部div也会触发外部的移入事件,这叫做事件冒泡
按键修饰 按键名/按键编号
@keyup.enter 指定触发的按键,由按enter触发
@keydown.alt.shift 指定由按住shift+alt触发
双向绑定修饰符 lazy
@v-model.lazy=“属性名” 延迟双向更新,延迟到确认内容变化(比如失去焦点)再更改
vue页面标签
遍历 v-for item in items
v-for…in… 标签用于遍历的vue属性
item 自定义变量名
items vue对象的属性名
是否渲染 v-if v-else-if v-else
是否显示 v-show
(一定会渲染,但可能隐藏,相当于操作display属性)
vue实例的属性
监听 watch和计算属性computed
<body>
<div id="d1">
<input type="text" v-model="name"/><br />
<!-- 监听属性-->
<input type="text" v-model="age"/>{{flag}}<br />
<input type="text" v-model="sex"/><br />
<input type="button" value="获得信息"/>:{{add}}
<br /><br /><br />
<input type="text" v-model="people.firstname"/><br />
<input type="text" v-model="people.lastname"/><br />
<input type="button" value="非深度监听对象" @click="t1"/>
<!-- 非深度监听对象:必须引用整个对象对其作出改变才会触发handler -->
{{flag2}}
<br /><br /><br />
<input type="text" v-model="people2.firstname"/><br />
<input type="text" v-model="people2.lastname"/><br />
<!-- 深度监听对象:层层监控,所有下级属性都会被监控,一旦改变就触发handler -->
{{flag3}}
</div>
</body>
<script type="text/javascript">
var vue = new Vue({
"el":"#d1",
"data":{
name:"",
age:0,
sex:"",
flag:"",
people:{firstname:"fir",lastname:"las"},
flag2:"",
people2:{firstname:"first",lastname:"last"},
flag3:""
},
"methods":{
t1(){
this.people={firstname:123,lastname:"las"};
}
},
// 计算属性:有返回值的方法可以当做属性被引用,直接引用方法名{{add}},获得返回结果
"computed":{
add(){
return this.name+this.sex+this.age;
}
},
// 监听:无需显式引用,类似生命周期方法,自动监听并处触发
"watch":{
// 监听属性
age(val){
if(isNaN(this.age)){
this.flag="必须填写数字!";
}else{
this.flag="";
}
},
// 监听对象
people:{
handler:function (people){
if(isNaN(people.firstname) && isNaN(people.lastname) ){
this.flag2="";
}else{
this.flag2="不能填写数字!";
}
}
},
// 深度监听对象
people2:{
handler:function (people2){
if(isNaN(people2.firstname) && isNaN(people2.lastname) ){
this.flag3="";
}else{
this.flag3="不能填写数字!";
}
},
// 深度监听
deep:true,
// 立即生效(绑定模型及生效,不用等到有改变,默认是false,改变时生效)
immediate:true
}
}
});
</script>
vue自定义组件
全局组件
无论是否使用,都会在一开始就渲染,并一直存在
每个组件的模型数据是独立的
可以使用于任意一个模板元素中;
可以使用多次
Vue.component
局部组件
渲染其所在的元素才会渲染这个组件
每个组件的模型数据是独立的
只能使用于当前模板元素中;
可以使用多次
vue实例中components属性
组件属性
template:’ ’
props:[] props:{}
props:[“组件属性名1”,“组件属性名2”]
组件属性名用于在使用组件时绑定父组件的属性 <组件 v-bind:组件属性名=“父组件属性名”></组件>
props:{“组件属性名1”:{type:String,required:true},“组件属性名2”:{c:3,d:4}}
对象写法可以为组件属性限制类型,接收到不符合类型的参数时vue会抛出warn(但参数仍正常传递并运行),可以通过异常处理进行捕捉和强行停止
props:{
uname:{
type:Number},
pwd:{
type:Number}
}
methods:{}
其中定义的方法可以使用 this.$emit("自定义事件名") 触发自定义事件,在使用组件时绑定父组件的方法
<组件 @自定义事件名=“父组件事件名”></组件>
data(){}
data(){ return{ 子组件属性名:属性值,子组件属性名:this.prop名 }}
computed:{}
父子组件通信(属性值传递)
<body>
<div id="d1">
<counter v-bind:fathergiveend="end" v-bind:fathergivename="name" v-bind:count="count"></counter>
<counter1 v-bind:fathergivename="name" v-bind:count="count"></counter1>
<counter2 v-bind:fathergivename="name" v-bind:count="count" v-bind:fathergiveend="end" @fucount="fucounter"></counter2>
<!-- 父组件值不会被子组件直接改变,只能被父组件自己改变,所以要想同步,必须在父组件操作,子组件引用方法-->
父组件值{{count}}{{end}}
<!-- 父组件向子组件传递对象 -->
<my-table v-bind:us="users"></my-table>
</div>
</body>
<script type="text/javascript">
var vue = new Vue({
"el":"#d1",
"data":{
age:0,
name:"张三",
end:"谢谢你",
count:0,
users:[
{name:"a",age:12},
{name:"b",age:22},
{name:"c",age:15}
]
},
"methods":{
fucounter(){
this.count++;
}
},
"components":{
counter:{
template:'<button @click="count++">{{fathergivename}}你点了我{{count}}次,<input v-model="fathergiveend"/></button>',
// 静态值:使用data()方法的return定义
data(){
return{
count:0,
you:"谁?"
}
},
props:["count","fathergivename","fathergiveend"]
},
counter1:{
template:'<button @click="count++">{{fathergivename}}你点了我{{count}}次,<input v-model="fathergiveend"/></button>',
// 子组件从父组件取值:
// 1.在子组件中使用props属性,罗列变量的名称,在template中引用;
// 2.在页面中使用组件时使用 v-bind:属性名=“父组件属性名” 绑定父组件的属性
props:["count","fathergivename","fathergiveend"]
},
counter2:{
// 从子组件直接操作拿到的count值,改为调用一个方法(在这个方法中调用父组件方法从而操作父组件的值)
template:'<button @click="zicount">{{fathergivename}}你点了我{{count}}次,<input v-model="fathergiveend"/></button>',
methods:{
// 触发一个事件,自定义事件名fucount,用于在使用组件时绑定父组件的方法来操作父组件的属性值
zicount(){
this.$emit("fucount");
}
},
props:["count","fathergivename","fathergiveend"]
},
myTable:{
template:'<ul><li v-for="u in us">{{u.name}}=={{u.age}}</li></ul>',
props:["us"]
}
}
});
</script>
vue异常处理
Vue.config.warnHandler=function(vm,msg,trace){
alert(vm);
}
vue路由
无法渲染为链接a标签的原因:vue-router.min.js必须紧接着vue.js引用!!
<!DOCTYPE html>
<html>
<head>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
<script src="js/vue-router.min.js" type="text/javascript" charset="utf-8"></script>
<script src="js/leader.js" type="text/javascript" charset="utf-8"></script>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<div id="app">
<leadertem></leadertem>
<router-link to="/login">登录</router-link>
<router-link to="/regi">注册</router-link>
<hr />
<router-view class="router-view"></router-view>
</div>
</body>
<script>
var vue = new Vue({
el:"#app",
components:{
leadertem,
logintem,
registertem
},
router:router
});
</script>
</html>
leader.js:
const leadertem = {
template: '<div><button>首页</button><button>登录</button><button>注册</button></div>'
}
const logintem = {
template: '\<div>\<h2>登录页</h2> \用户名:<input type="text"><br/>\密码:<input type="password"><br/>\</div>'
}
const registertem = {
template: '\<div>\<h2>注册页</h2> \用户名:<input type="text"><br/>\密码:<input type="password"><br/>\确认密码:<input type="password"><br/>\</div>'
}
const router = new VueRouter({
routes: [{
path: '/login',
component: logintem
},
{
path: '/regi',
component: registertem
}
]
})