{{message}}:插值表达式
示例:<p v-clock>---{{message}}+++</p>
注解:其前面和后面都可以放任意字符数字等不会替换标签原有内容,和v-text不同的是v-text会把标签中的其他所有原有的内容清空,插值表达式会有闪烁问题可以用v-clock解决闪烁问题。
v-clock:
如上,解决插值表达式闪烁问题。
V-text:
示例:<p v-text=”message”></p>
注解:会把所有的标签原有内容替换,内容都会作为文本输出,默认没有闪烁问题。
v-html:
示例:<p html=”message”><h1>你好!</h1></p>
注解:会把所在标签中的内容当做html内容解析,如h1会被解析为html标签,不会当内容解析。
v-bind:
示例:<input type=”button” value=”按钮” v-bind:title=”message + 123”/>
注解:绑定了某个标签属性,之后这个属性中的变量值会被当做js表达式被解析,如上,message会被解析为你设置的内容然后+123字符串。可以简化为冒号,只能实现数据的单向绑定。
v-model:
示例: <p>{{ message }}<p/>
<input type=”text” v-model=”message” />
注解:可以实现表单元素和model中数据的双向绑定,注意,v-model只能运用在表单元素中,如input(radio,text,adderss,email...) select,checkbox,textarea
v-on:
示例:<input type=”button” value=”按钮” v-on:click=”show”/>
***
Var vm = new Vue({
el : ‘’,
data : {},
methods:{
show:function(){
alert(‘你好。’)
}
}
})
注解:绑定的都是事件,如show会被当做变量解析,但是必须在实例中声明。可以被简化为@,但是最好不要简化;使用事件绑定机制,为元素指定处理函数的时候,如果加了小括号就可以给函数传参。
事件修饰符:
.stop 阻止冒泡
.prevent 阻止默认事件
.capture 添加事件侦听器时使用事件捕获模式
.self 只当事件在该元素本身(比如不是子元素)触发时触发回调,也即只会阻止自己身上冒泡行为的触发,并不真正的冒泡行为
.once 事件只触发一次
示例: <div class=”inner” @click.self.once=”divHanlder”>
<input type=”button” value=”点击” @click=”btnHanlder”/>
</div>
事件修饰符可以叠加。
v-for:
示例:
1.循环数组对象
<p v-for=”(item ,index) in array :key=”item.id”>
id:{{item.id}}---name:{{item.name}}
<p/>
data:{
array:[
{ id:1,name:’吴竞’},
{ id:2,name:’jing’},
{ id:3,name:’小王八蛋’}
]
}
2.遍历对象
<p v-for=”(val ,key,index) in user” >键:{{ key }}---值:{{ val }}---索引:{{ index }} <p/>
data:{
user:{
id:1,
name:’吴竞’,
sex:’女’
}
}
3.迭代数字
<p v-for=”count in 10”>这是数字:{{ count }}</p>
注解:in后面可以放普通数组,对象数组,对象,数字(从1开始);
2.2.0+版本里,当在组件中使用v-for时必须加key;
key使用时必须用v-bind绑定;key的值只能是数字或字符串;写key肯定没问题。
v-if与v-show:
示例:<input type=”button” value=”显示/删除” @click=”flag=!flag”>
<h1 v-if=”flag”>这是用v-if控制的元素</h1>
<h1 v-show=”flag”>这是用v-show控制的元素</h1>
注解:v-if特点为 每次都会重新创建或删除元素;
v-show特点为 每次不会重新进行dom的删除和创建操作,只是切换元素的display:noney样式;
v-if有较高的切换性能消耗;
v-show有较高的初始渲染消耗;
如果元素设计频繁的切换,最好不要用v-if,而是使用v-show;
如果元素可能永远都不会被显示出来被用户看到,推按使用v-if;
小贴士:
1. Vm实例会监听自己身上data中所有数据的改变,只要数据一发生改变就会自动把新的数据同步到页面中去,也即只需要关心数据,不要考虑如何重新渲染dom页面。
2. 在vm实例中,如果想要获取data中的数据,或者想要调用methods中的方法,必须通过 this.数据属性名 或 this.方法名 来进行访问,这里的this就表示我们new出来的vm实例对象。
3. 嵌套函数示例:
var _this=this
setInterval(function(){
用到this设计到一个问题,内部this要和外部this同步。
}
)
还可以这样:
setInterval( () => {
这个this直接就是和外部同步的,注意this的问题。
}
)
4.el指定控制的区域不要在body中。
axios简单使用:
安装axios:npm i axios
或引包:<script src=”http://cdn.bootcss.com/axios/0.16.0/axios.min.js”></script>
配置步骤:
- 引入import Axios from ‘axios’;
- 给Vue原型挂载一个属性 Vue.prototype.$axios=Axios;这样所有的实例对象都可以用。
- 在app.vue等组件中写代码
<script>
export default{
data(){
return {
}
},
created(){//也可以不用钩子函数,只是可以一打开页面就运行请求。
ths.$axios.get(‘http://get的url’).then(result=>{//.then是为了获得回调数据
console.log(result)
}).catch(err=>{
console.log(err)
})
}
this.$axios.post(‘http://post的url’ ,
//{ content:’你好我好大家好’ },记住这样提交表单数据会报错,不要用对象,应该用字符串形式。
//如果发的是对象形式如上,也可以设置请求头{headers:{‘content-type’:’application/x-www-form-urlencoded’}}但是不推荐!,用字符串最好,请求头会自动变化。
‘ content=你好我好大家好’
).then(result=>{
console.log(result)
}).catch(err=>{
console.log(err)
})
}
</script>
合并请求:
axios.all ( [ 请求1 , 请求2 ] )
分发响应 axios.spread(fn)
fn:对应参数(res)和请求的顺序一致
应用场景:
必须保证两次请求都成功,比如,分头获取省市的数据。
执行特点:只要有一次失败就算失败,都成功才算成功。
示例:
created(){
//将两个请求一起发送,只要有一个失败就算失败,都成功才成功,原子性。
function getMsg( res1 , res2 ){
console.log(res1);
console.log(res2);
}
//发送请求
this.$axios.all( [
this.$axios.get( ‘http://xxx’ ),
this.$axios.post(‘http://xxxxxx’ , ’ content=123 ’ )
] )
//分发响应
.then ( this.$axios.spread ( getMsg ) )
.catch(err=>{
console.log(err);
})
}
小提示:
- this.$axios.get(url,options)
- this.$axios.post(url,data,options)
- options:{ params:{id:1}//查询字符串,headers:{‘countent-type’:’xxx’},baseURL:’XXX’//针对当前这一次请求的相关设置}
- 全局默认设置:Axios。default.baseURL=’XXX’;
- post请求的时候,如果数据是字符串默认头就是键值对,否则是对象就是applicaton json
- get添加配置对象在第二个位置,post添加配置对象在第三个位置。
- 在以上代码中,如果url前面有重复的可以简化。在main.js中写入Axios.defaults.baseURL=’http://重复部分’;然后把get或post请求中的重复的部分删除也可以正常发起请求。
vue-resource(数据请求,这个vue团队已经不再维护,推荐使用axios)
get请求示例:(jsonp请求与get请求类似,可能多的是要把字符串转成json对象)
导入vue-resource
<div id=”app”>
<input type=”button” value=”get请求” @click=”getInfo”/>
</div>
<script>
var vm=new Vue({
el:’#app’,
data:{},
methods:{
getInfo(){
//通过.then获得成功的回调函数,
this.$http.get(‘http://get请求url’).then(function(result){
//通过result.body拿到服务器返回的成功的数据。
console.log(result.body)
})
}
}
})
</script>
post请求示例:
methods:{
postInfo(){
// 手动发起的post请求,默认没有表单格式,所以有的服务器处理不了
//通过post方法的第三个参数{emulateJSON:true}设置提交的内容类型为普通表单数据格式。
this.$http.post(‘http://post请求url’ , {内容} , {emulateJSON:true} ).then(result=>{
console.log(result.body)
})
}
}
vue实例的生命周期(钩子函数)
创建期的生命周期函数
beforeCreated(){} :在这个生命周期函数创建时data和methods还没有初始化
created(){} :(重要)此时data和methods都已经初始化好了,要调用methods中的方法或操作data中的数据最早的时期就是created中,但是没有装载到dom中,所以在页面是不可见的。
beforeMount(){} :此函数执行时,模板已经在内存中编译好了,但是尚未挂载到内存中去,此时页面还是旧的。
mounted(){} :此时将内存中编译好的模板,真实的替换到页面的浏览器中去;如果要通过某些插件操作dom中的节点,最早要在mounted中进行;vue实例已经初始化完毕,此时组件已经脱离创建阶段,进入到运行阶段。
运行期的生命周期函数
beforeUpdate(){
} :(有数据更新才会触发)当执行时,页面中显示的数据还是旧的,此时data数据是最新的,页面尚未和最新的数据保持同步。
updated(){} :执行时,页面和内存中的data数据已经保持同步,都是最新的。
销毁期的生命周期函数
beforeDestroy(){} :进入销毁阶段,实例身上所有的data所有的methods以及过滤器、指令都处于可用状态,没有真正执行销毁过程。
destroyed(){} :组件已经完全销毁,所有的data方法methods、指令、过滤器等都不可用。
组件定义方式:(也即xxx.vue定义方式)
- (全局注册)通过Vue.component把组件模板对象,注册为一个全局的Vue组件,同时为这个组件起一个名称,可以让我们通过标签的形式在页面中直接引入这个组件。
说明:Vue.component( ‘ my-component ’ , 组件);//此一定要放在new Vue({……})之前,注册后也指定了组件的html标签,即为<my-component></my-component>
import com from ‘组件路径’;
Vue.component(‘my-component’,com);//之后就可以在html文档中用<my-component></my-component>调用。
- (局部注册)在vue实例中通过components属性注册一个模板对象。
示例:
import child form ‘url路径’;
var vm=new Vue({
el:’#app’
components:{
‘my-component’:child
},
})
Vuex:
他就是一个配置全局数据共享的容器,方便的实现,从同级或子从父,父从子中取值的问题。
配置vuex步骤:
- 运行cnpm install vuex –S
- 导入包在main.js中import Vuex from ‘vuex’;
- 注册vuex到vue中Vue.use(Vuex)
- New Vuex.Store()实例,得到一个数据仓储对象
var store=new Vuex.Store({
state:{},//存储的都是数据
mutations:{},//内部写方法负责对数据的操作
getters:{}//内部写方法,只负责对外提供数据,不负责修改数据。
})
5. 将vuex创建的store挂载到vm实例上,只要挂载到vm实例上,任何组件都能用store来存储数据。
const vm=new Vue({
el:’#app’,
render:c=>c(App),
store:store
})
注意:
1.state中的数据不能直接修改,想修改必须通过mutations(符合vuex理念,不是说通过别的不能改)
2.如果组件想从state中获取数据,需要 this.$store.state.XXX
3.如果组件想.修改数据,必须使用mutations提供的方法,需要通过this.$store.commit(‘方法名’,唯一的参数)这里参数可以是对象
4.如果store中的数据对外提供的时候需要一层包装,推荐使用getters,如果使用getters则要用this.$store.getters.xxx来获取数据。
5.每个方法中的形参必须要写一个state这是固定的,还可以写另一个唯一的参数。
组件之间的传值:(可以通过vuex,而不必通过这种看似复杂的方法)
父组件向子组件传值:
注解:子组件中默认无法访问父组件中的data上的数据和methods中的方法
示例:
<div id=”app”>
<!—父组件可以在引用子组件的时候,通过属性绑定的方式,把需要传递给子组件的数据传递给子组件内部,供子组件使用,子组件得到的父组件数据是只读的(可改但会有警告,不推荐)-->
<com1 v-bind:parentMsg=”msg”></com1>//绑定父组件的数据
</div>
<script>
var vm = new Vue({
el:’#app’,
data:{ msg:’这是父组件中的数据’},
components:{
//子组件默认无法访问父组件中的数据和方法
com1:{
//子组件中的data数据是可读可写的,它不是通过父组件传递过来的,而是子组件自身的。
data(){
return{
title:’123’,
content:’abc’
}
},
template:’<h1 @click=”change”>这是子组件---{{ parentMsg }}</h1>’,
props:[ ‘ parentMsg ’ ],//把父组件中传过来的属性先在props数组中定义才能在子组件使用。
methods:{
change(){
this.parentMsg=’子组件直接修改父组件数据’//可以改但是会有vue警告,千万别这么做。
}
}
}
}
})
</script>
父组件向子组件传递方法//同时//子组件向父组件传值:
思路:定义一个方法让子组件调用,同时子组件把参数传递到方法中带到父组件中。
示例:
<com2 @func=” show ” ></com2>//这是子组件标签
//父组件中会有一个show方法,然后在子组件中定义个方法去调用
<template id=”tmpl”>
<div>
<input type=”button” value=”触发父组件方法” @click=”myclick”>
</div>
</templare>
var com2 ={
template:’#tmpl’,
methods:{
myclick(){
tihs.$emit(‘func’)//子组件向父组件传值可以通过加参数如:this.$emit(‘func’,abc,aaa)
}
}
}
var vm =new Vue({
el:’#app’,
data:{},
methods:{
show(data,data2){//子组件没有传递参数就不用写
console.log(‘调用的父组件方法并传递参数’+data+data2)
}
}
})
vue获取dom元素和组件
示例:
<div id=”app”>
<input type=”button” value=”获取dom元素” @click=”getElement”>
<h1 id=”myh1” ref=”myh1” >dom元素中的h标签</h1>
</div>
……
methods:{
getElement(){
console.log(this.$refs.myh1.innerText)
}
}
注意:在dom元素中用于获取dom的属性为ref没有s,可以在dom中的多个标签中写ref以获取,vue中的$refs是有s的,他就已经获取了dom中含有ref的dom元素。同样可以获取组件,并可以调用组件的方法。
路由:
使用方式:
- 下载npm i vue-router -S
- 在main.js中引入 import VueRouter from ‘vue-router’;
- 安装插件 Vue.use(插件) Vue.use(VueRouter);
- 创建路由对象并配置路由规则let router = new VueRouter ({routes:[{path:’/’,component:组件名}]})
- 将路由对象传递给Vue实例,options中。 router:router
- 留坑<router-view><router-view>
示例:
import Vue from ‘vue’;
import VueRouter from ‘vue-router’;
import Home from ‘./components/home.vue’;
import App from ‘./components/app.vue’;
Vue.use(VueRouter);//挂载属性
let router=new VueRouter({//创建路由对象并配置路由规则
routes:[ //这个注意是routes并且他是一个数组,可以配置多个规则。
//一个个对象
{path : ‘ / ’ ,component : Home},
]
});
var vm =new Vue({
el:’#app’,
render:c=>c(App),
router:router//可以简写为router也即键值都是router可以简写。
})
然后在home组件的template中留坑,然后访问xxx#/home即可访问。
路由的router-link相关
示例:
路由规则这样:routes:[{name:’music’ , path:’/music’ ,component:Music}]
在要用到的组件中:<router-link :to=”{name:’music’}”>音乐<router-link>//极力推荐,好维护
或者:<router-link :to=’/music’>音乐</router-link>//不好维护,路径变了就要改。
注意:
如果不用router-link非要用a标签,就要多写个#号如<a href=”#/music”>音乐</a>
router-link挂参
vue-router中,有两大对象呗挂载到实例this上
$route(只读、具备信息的对象)
$router(具备功能函数)
query(查询字符串):路径?id=1&xxx=xxx 这种形式
- 去哪里<router-link :to={name:’detail’,query:{id:1}}>xxx</router-link>
- 路由规则(查询字符串path不用改){name : ’ detail ’ , path : ’ /detail ’ , component : 组件}
- 去了干嘛,获取路由参数(要注意是query还是params和对应id名)this.$route.query.id
params(path方式):路径/id/xxx 这种方式挂参
- 去哪里<router-link :to=”{name:’detail’ , params:{ id:3 } }”>xxx</router-link>
- 导航(params方式需要在路由规则上加上 /:xxx )别忘了冒号。
{name:’detail’,path : ’ /detail / : id ’ , component:组件}
3、去了干嘛,获取路由参数(要注意是query还是params和对应的name名,query和params不能混用)this.$route.params.id可以通过这种方式取得携带的参数。
重定向和404
刚到一个网页默认就是/
重定向 :(重定向的目的之一是,让输入url时自动跳到主页面)
比如有一个组件为home:import Home from ‘./home.vue’;
其路由匹配规则为:{name:’home’ , path:’/home’ ,component:Home}
重定向方法1 {path:’/’ ,redirect:’/home’}//可维护性较低
重定向方法2 {path:’/’,redirect:{name:’home’}}//最为推荐
404:(在路由规则的最后一个规则,写一个很强大的匹配,也就是没有匹配的路径就跳转到这,用*通配符)
{path:’*’ , component:notFoundVue}
多视图(多个router-view)
示例:
在app.vue中
<template>
<div>
<router-view name=”header”></router-view>
<router-view ></router-view>//什么都不写就是默认的default
<router-view name=”footer”></router-view>
</div>
</template>
……
在main.js中
let router=new VueRouter({
routes:[
{path:’/’,components : //注意!!!如果对应多个router-view则component要加s!!!
header:header,//对应的header组件,是头部的router-view
default:footer,//对应的默认的没写name的router-view
footer:footer//对应的footer组件,是底部的router-view
}
]
})
注解:一次行为=多个坑+一个路由+多个组件
嵌套路由:
routes:[
{path:’/’,redirect:{name:’music’}},
{name : ’ music ’ , path : ’ /music ’ , component : Music , children : [
//这里写path比较灵活,写/xxx就是绝对路径,不写/就是相对路径匹配的结果就是/music/oumei
{name:’music_oumei’,path : ‘oumei’ , component : Oumei},
{name : ‘music_guochan’ , path : ‘guochan’ , component : Guochan}
]}
]
编程导航:
小结:
this.$router.go( 1|-1 ) //括号中可以填1或-1等,表示根据浏览器记录前进或后退。(把他写在某个时间并定义个方法用)
this.$router.push( { name : ‘music’ } | ‘/music’ ) //直接跳转到某个页面显示
示例:
<template>
<div>
<button @click=”goMovie”>跳电影</button>
<div>
</template>
<script>
export default{
data(){
return {}
},
methods:{
goMovie(){
this.$router.push({ name : ‘movie’})//这个name对应路由规则中的name
}
}
}
</script>
meta:vp
过滤器(拦截器):
示例:给请求添油加醋的三种方式。
1、//拦截器(在main.js中)
Axios . interceptors . request . use ( function ( config ) {
//console.log(config)
//个性化的修改
config.headers.options(这个options可以自己随意选)=”xxx”;
//config.headers={
accept:’interceptors’……
}
return config;//返回设置,不return config请求就会被完全拦截,一般都是在这之前做请求的个性化修改。
})
2、//默认的设置请求的方式(类似拦截)
Axios . defaults . options=’ xxx’;//options可以自己随意换比如:Axios.defaults.headers={ accept:’defaults’ }
3、//直接在请求上改
this.$axios.get(‘http://xxx’ , {
headers:{
acctpt:’get’
}
})
小结:
以上优先级排名:1拦截器 > 3单个请求的设置 >2 默认设置
过滤,在每一次请求与响应中、添油加醋
axios.interceptors.request.use(fn) 在请求之前
function(config){config.headers={xxx}} config相当于options对象
可以设置请求的拦截,也可以设置响应的拦截,吧request设置为response
应用场景:
token:
其他小知识点:
- 在导入组件时有时会见到@如: import model from "@/common/model";其中的@ 等价于 /src 这个目录,避免写麻烦又易错的相对路径。
- name: 'app' 相当于一个全局 ID;可以不写;写了可以提供更好的调试信息(官方文档有)。
<script>
export default {
name: 'app'
}
</script>