Vue学习笔记
Vue初始化对象
var vm = new Vue({
el:"#box", //绑定的元素
template:"<h1>{{money}}</h1>", //使用的模板
data:function () { //绑定的数据
return{
money:"123"
}
}
})
data和methods里面的属性都是Vue这个实例对象的代理属性,例:vm.money = 123;
而vm本来的自身属性则是vm.template,vm.符号区分开来,就是内置的自带的属性和方法
var vm = new Vue({
// el:"#box", //绑定的元素
data:function () { //绑定的数据
return{
age:12
}
}
}).$mount("#box");
option可以读取vue实例对象上面的静态方法和属性,也就是自定义方法和属性
$log查看数据的一个状态
注意,不要在实例属性或者回调函数中使用箭头函数,因为箭头函数会绑定父级的上下文,会导致里面的this不会指向Vue实例
Vue实例对象的声明周期
渲染方式
文本插值
<div id="box" >
{{money}}
</div>
单次渲染 v-once
<div id="box">
<button @click="changeData">456</button>
<span v-once>{{money}}</span>
</div>
渲染html v-html
<div id="box">
<span v-html="money"></span>
</div>
注意点:v-html是渲染html片段的,里面数据绑定会被忽略
属性绑定 v-bind
vue中的属性绑定和ng的有些不一样,ng的可以在属性上随意添加插值语法,但是在vue中不可以,要利用v-bind绑定属性,传入的也可以是布尔值
<div id="box">
<span v-bind:title="money">{{money}}</span>
<input type="radio" v-bind:checked = "true">
</div>
简写:
<span :title="money">{{money}}</span>
事件处理器
<button v-on:click="warn('Form cannot be submitted yet.', $event)">Submit</button>
传入$event可以操作dom节点
vue提供了一些内置修饰符也可以操作dom节点
- @click.stop阻止事件冒泡
- @click.prevent阻止事件默认行为
- @keydown/@keyup后面可以点键码(@keydown.13),可以点英文(@keydown.enter)
表单控件
表单控件多数利用v-model来实现数据的双向绑定
多个勾选框绑定到同一个数组
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="checkedNames">
<label for="john">John</label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
<label for="mike">Mike</label>
<br>
<span>Checked names: {{ checkedNames }}</span>
new Vue({
el: '...',
data: {
checkedNames: []
}
})
指令的一些注意事项和注意点
v-model和ng-model作用一样,都是实现数据双向绑定的,但是有一个区别就是,ng-model绑定的对象可以不用声明,但是v-model绑定的对象一定要声明
-
v-if有时候要切换多个元素的时候,可以用template
<template v-if="true"> <h1>Title</h1> <p>Paragraph 1</p> <p>Paragraph 2</p> </template>
并且template并不会被显示出来;也可以和if-else,v-else-if配合使用,if-else,v-else-if要紧挨着v-if的元素
computed能做到的事情,methods也能做到,那么两者有什么区别呢?
computed会把计算结果保存在缓存当中,只有计算的值发送变化了才会重新计算,但是methods只要重新渲染就会重新计算,两者的区别在于你是否希望保存到缓存当中并读取它.-
vue为了提高渲染速度,通常会复用已有元素而不是从头开始渲染
<template v-if="loginType === 'username'"> <label>Username</label> <input placeholder="Enter your username"> </template> <template v-else> <label>Email</label> <input placeholder="Enter your email address"> </template>
例如上面的代码,当切换到email的时候,input里面的数值还是会存在,因为复用了这个元素
这种方式有一定的好处和坏处,当你需要分开这两个input的联系的时候,可以在input上添加一个唯一的key,vue就会重新渲染,不会复用前一个input v-show和v-if的区别
v-show和v-if同ng-show和ng-if很类似,v-if是惰性的,只要不需要它的时候,这个元素就不会被渲染,直到首次需要它的时候,而v-show不一样,不管需不需要它,都会被渲染出来,之后css的display隐藏它,但是v-if切换所耗费的性能比较多,v-show耗费的性能比较少,所以如果元素需要不断切换的还是利用v-show比较好,只要出现一次,不用频繁切换的则用v-if-
v-for遍历数据
(item,key) in array,vue里面是item在前面,key在后面,v-for的优先级会比v-if的优先级高
v-for遍历数据可以设置一个template然后遍历,这样浏览器并不会读取这个template模板标签<template v-for="product in productList"> <h3>{{product.title}}</h3> <ul v-for="item in product.list"> <li> <a :href="item.url">{{item.name}}</a> </li> </ul> <div v-if="!product.last" class="hr"></div> </template>
:class的使用
:class和ng-class的使用方法差不多,:class="{'red':true}"
还可以和数组混搭
:class="[{'red':true},'bule']" 这样有bule一个类,red会判断是否添加当使用js吧图片的src利用v-bind绑定到图片上的时候,要利用require,否则会拿不到图片
v-model.lazy方法就是当失去焦点时才刷新数据的绑定,有利于性能的提升
计算属性computed
虽然插值语法也是可以解析js的代码的,但是一些复杂的计算都写在插值语法上会导致模板不清晰和逻辑复杂,稍微复杂的计算都尽量写在计算属性当中,改变计算前的数据,计算后的数据也会实时跟着改变的
<div id="box">
<span>{{message}}</span>
<span>{{reversedMessage}}</span>
</div>
var vm = new Vue({
el:"#box", //绑定的元素
data:function () { //绑定的数据
return{
message:"<h1>123456789</h1>"
}
},
computed:{
reversedMessage:function () {
return this.message.split('').reverse().join('');
}
}
});
computed:{
reversedMessage:{
get:function () {
return this.message.split('').reverse().join('');
},
set:function () {
this.message+=1;
}
}
}
computed完整的写法有两个,一个是get获取数值,一个是set设置数值
Vue手动监听属性变化
vue也有一个类似angular的$watch属性,可以监听数据的变换
vm.$watch("red",function () {
alert("发生变化了");
});
但这种方法是一种浅监听,如果遇到对象类型里的某个属性变化就会监听不到了
这时候要利用vue的一个深监听
vm.$watch("people",function () {
alert("发生变化了");
},{deep:true});
发送网络请求
vue并没有内置http请求的东西,所以要发送http需要导入vue-resource,导入之后就可以使用$http请求了
利用get请求数据
methods:{
get:function () {
this.$http.get("a.txt").then(function (res) {
res.status //是状态码,成功一般200
res.data //res.data才是结果
alert("成功了");
},function () {
alert("失败了");
})
}
}
利用get发送数据
methods:{
get:function () {
this.$http.get("get.php",{
a:1,
b:2
}).then(function (res) {
alert(res.data);
},function () {
alert("失败了");
})
}
}
利用post上传数据
post:function () {
this.$http.post("post.php",{
a:1,
b:2
},{
emulateJSON:true
}).then(function (res) {
alert(res.data);
},function () {
alert("失败了");
})
}
一般在created里面执行数据的请求
created:function () {
this.$http.get("static/08-Ajax-get.php").then((data) =>{
this.data = data;
},(err)=> {
console.log(err);
})
}
最好利用es6的箭头函数,保证this是外部的this
Vue生命周期(钩子函数)
网上找到一张非常棒的图
Vue组件
Vue的组件其实就等于新建了一个对象,一样享有template,data,methods等方法
生成组件的几种方式
var Aaa = Vue.extend({
template:"<h1>i am h1</h1>"
});
Vue.component("aaa",Aaa);
通过Vue对象生成组件
Vue.component("my-header",{
template:"<p>this is my header</p>"
});
生成组件然后绑定
var myHeader = {
template:"<p>this is my header</p>"
};
new Vue({
el:"#box", //绑定的元素
data:function () { //绑定的数据
return{
money:"123"
}
},
components:{
"my-header": myHeader
}
})
作用域
组件之间的作用域都是独立的,意味着子组件不能获取到父组件上面的数据
Vue.component("my-child",{
props:['message'],
template:"<div>{{message}}</div>"
});
props:{
slides:{
type:Array,
default:[] //如果没传入,默认为一个空数组
},
interval:{
type:Number,
default:1000 //如果没传入,默认为1000毫秒
}
}
<my-child :message="colorArr"></my-child>
这种方式就可以从父组件上面获取数据,先声明props然后用:message来接收,props还有另外一种方式
Vue.component("my-child",{
props:{
'message':String,
'myMsg':Number
},
template:"<div>{{message}}</div>"
});
这种方式会限定传进来数据的格式,如果格式不对,就传不进来了
同样,父组件也是不能获取到子组件上面的数据的
先是利用子组件$emit事件吧数据传递出去
<child @emit-msg="get"></child>//触发emit-msg的传递方法,get是要父组件调用的方法的名称
在子组件中
this.$emit("emit-msg",this.msg);//第一个参数是传递方法的名称,第二个是数据
在父组件中
get:function (m) {
this.msg = m; //获取到的m就是从子组件上面传递过来的数据
}
注意点:如果要在父组件上面获取的方法里面传入参数,例如这样
<v-selection :selections="buyTypes" @on-change="onParamChange('buyType',$event)"></v-selection>
如果有另外传入的参数,那么本来从子组件里面传过来的参数就会获取不到,所以要加一个$event参数,就可以获取得到原本传过来的参数了
去github搜索awesome-vue里面可以搜到许多组件!!!!!!!!!!!!!!
渲染的方式
<my-header></my-header>
但是在一些标签内,例如table,ul,等标签内可能会导致这样的渲染方式失效,也有另外的方法
<table>
<tr is="my-row"></tr>
</table>
绑模板的方式
第一种直接写在template里面
-
第二种写在script里面type="x-template" id=名称
<script type="x-template" id="aaa">
<h1 @click='myAlert()'>{{msg}}</h1>
</script>
然后template里面写入id名称就可以了template:"#aaa"
-
第三种写在一个template标签里面,和第二种有些类似
<template id="aaa"> <h1 @click='myAlert()'>{{msg}}</h1> </template>
在绑定
有些时候,模板标签里面可能也会有东西,为了不要让模板的内容完全覆盖标签里面的东西要利用到slot这个标签
渲染模板里面
<div id="box" >
<aaa>
这里这里这里
</aaa>
</div>
如何才能保留"这里这里这里"同时又能渲染模板呢
这是aaa的模板
<template id="aaa">
<div>
<slot></slot> //slot里面就是aaa标签里面原有的东西
<h1>我是aaa的模板</h1>
<slot></slot> //这里可以放置多个,可以渲染多次
</div>
</template>
当出现多个模板的时候,可以分配那个slot展示的是哪一块
<aaa>
<ul slot="ul-slot">
<li>uuuuu</li>
<li>uuuuu</li>
<li>uuuuu</li>
<li>uuuuu</li>
</ul>
<ol slot="ol-slot">
<li>oooo</li>
<li>oooo</li>
<li>oooo</li>
<li>oooo</li>
<li>oooo</li>
</ol>
</aaa>
<div>
<slot name="ol-slot"></slot>
<h1>我是aaa的模板</h1>
<slot name="ul-slot"></slot>
</div>
动态组件
<component :is="tem"></component>
用一个component标签,可以是:is或者is,is就填入不变的字符串,:is就可以填入vue实例的变量,达到动态切换的效果
自定义过滤器
Vue.filter("todo",function (input) {
return input<10?"0"+input:input;
});
<p>{{age | todo}}</p>
自定义指令
自定义指令扩展了html语法
Vue.directive("red",function (el) {
el.style.background = "red";//el就是绑定的元素
});
使用方式
<p v-red></p>
Vue-router
引入组件
import VueRouter from "vue-router"
Vue.use(VueRouter)
routes:[
{
path:"/",
component:IndexPage
},
{
path:"/detail",
component:DetailPage,
redirect:"/detail/analysis",
//这样一进入detail就会去到analysis页面,不会出现空白的页面
children:[
{
path:"analysis", //这里不写'/',写了'/'会默认是跟目录的
component:DetailAnalysis
},
{
path:"count",
component:DetailCount
},
{
path:"forecast",
component:DetailForecast
},
{
path:"publish",
component:DetailPublish
}
]
}
]
<router-link>是用来跳转路由的指令
<router-link v-for="item in products" :to="item.path" tag="li" active-class="active">{{item.name}}</router-link>
//v-for遍历几个需要跳转的入口,to就是跳转到哪个路由上,tag就是这个标签会以什么html标签渲染,不写的话默认是a标签,acive-class就是选中的样式,不设定的话会默认有个router-link-active类的
获取当前路由地址this.$route.path 注意这里是没有r的!!!!!!!!!!!!!
this.$router.push({path:"/detail"})可以使路由跳转
浏览器插件
Vue-devtools
在vue中引入jquery插件
https://segmentfault.com/a/1190000007020623
登录框的时候可以用computed监听输入框的规则
computed:{
userError(){
let errorText, status;
if(this.usernameModel.length<6 ){
status = false;
errorText = "不能小于6位"
}else{
status = true;
errorText = "";
}
if(!this.userFlag){
errorText = "";
this.userFlag = true;
}
return {
status,
errorText
}
},
passwordError(){
let errorText, status;
if(this.passwordModel.length<6 ){
status = false;
errorText = "密码不能小于6位"
}else{
status = true;
errorText = "";
}
if(!this.passwordFlag){ //因为没有在页面渲染,所以也不用声明
errorText = "";
this.passwordFlag = true;
}
return {
status,
errorText
}
}
}