Vue.js基礎總結
一、Vue使用介紹
Vue不支援IE8,因為使用了ES5的很多特性。可以直接通過script標籤來引入vue.js,有開發版本和生產版本,開發版本一般我們在開發專案的時候引入,當最後開發完成上線的時候引入生產版本,開發版本沒有壓縮的,並且有很多提示,而生產版本全部刪掉了。開發版本可以使用vue-devtools檢查程式碼,生產版本不可以使用vue-devtools。
二、vue-router實踐練習
1、傳參及獲取傳參
通過$route獲取相應引數
<div id="app">
<div>
<router-link to="/user/jack?age=20">jack</router-link>
<!--另一種傳參方式-->
<!--<router-link :to="name:'user',params:{name:'jack'},query:{age:20}">jack</router-link>-->
<router-link to="/user/midy?age=35">midy</router-link> //通過to傳遞引數
</div>
<div>
<router-view></router-view>
</div>
</div>
<script src="https://cdn.bootcss.com/vue/2.5.13/vue.js"></script>
<script src="https://cdn.bootcss.com/vue-router/3.0.1/vue-router.js"></script>
<script>
var routes = [
{
path:'/user/:name', //動態獲取引數
component:{
template:`
<div>
<h1>我叫: {{$route.params.name}}</h1> // 符號'/'後面的用params獲取
<h1>我今年: {{$route.query.age}} 歲。</h1> // 符號'?'後面的用query獲取
</div>
`
}
}
];
var router = new VueRouter({
routes: routes
})
new Vue({
el:"#app",
router: router,
})
</script>
2、子路由
路由中設定children,其也是一個陣列
<div id="app">
<div>
<router-link to="/user/jack">jack</router-link>
<router-link to="/user/midy">midy</router-link>
</div>
<div>
<router-view></router-view>
</div>
</div>
<script src="https://cdn.bootcss.com/vue/2.5.13/vue.js"></script>
<script src="https://cdn.bootcss.com/vue-router/3.0.1/vue-router.js"></script>
<script>
var routes = [
{
path:'/user/:name',
component:{
template:`
<div>
<h1>我叫: {{$route.params.name}}</h1>
//方法一:動態繫結路由,to值為動態字串拼接,比如:" /user/jack/more "
<router-link :to="'/user/'+ $route.params.name +'/more'">顯示更多
//方法二:動態繫結路由,to值寫死,加上append屬性,表示在當前路由上追加一個'more'
<!--<router-link to="more" append>顯示更多 -->
</router-link>
<router-view></router-view>
</div>
`
},
//定義子路由
children:[
{
path:'more',
component:{
template:`
<div>
<p>我是 {{$route.params.name}},以下是我的更多資訊。</p>
<p>哈哈哈哈哈哈~~~~</p>
</div>
`
}
}
]
}
];
var router = new VueRouter({
routes: routes
})
new Vue({
el:"#app",
router: router,
})
</script>
3、手動訪問和傳參
this.router.push()方法
<div id="app">
<div>
<router-link to="/home">主頁</router-link>
<router-link to="/user/jack">jack</router-link>
<router-link to="/user/midy">midy</router-link>
<button @click="surf">路由自動訪問</button>
</div>
<div>
<router-view></router-view>
</div>
</div>
<script src="https://cdn.bootcss.com/vue/2.5.13/vue.js"></script>
<script src="https://cdn.bootcss.com/vue-router/3.0.1/vue-router.js"></script>
<script>
var routes = [
{
path:'/home',
component:{
template: `
<div><h1>我是首頁!</h1></div>
`
}
},
{
path:'/user/:name',
name:'user', //定義name屬性,供下面的" this.router.push "使用
component:{
template:`
<div>
<h1>我叫: {{$route.params.name}}</h1>
<router-link :to="'/user/'+ $route.params.name +'/more'">顯示更多
</router-link>
<router-view></router-view>
</div>
`
},
children:[
{
path:'more',
component:{
template:`
<div>
<p>我是 {{$route.params.name}},以下是我的更多資訊。</p>
<p>哈哈哈哈哈哈~~~~</p>
</div>
`
}
}
]
}
];
var router = new VueRouter({
routes: routes
})
new Vue({
el:"#app",
router: router,
methods:{
surf () {
//setTimeout函式體內最好不使用箭頭函式,因為this指向容易混淆
setTimeout(function(){
this.router.push('/home');
setTimeout(function(){
//動態傳參,其中name代表的是路由的'name'屬性值,params是傳遞引數
this.router.push({name:'user',params:{name:'jack'}})
},2000)
},2000)
}
}
})
</script>
4、命名檢視
給router-view定義name屬性
<div id="app">
<div>
<router-link to="/user">使用者管理</router-link>
<router-link to="/post">帖子管理</router-link>
</div>
<div>
//分別為router-view 定義name屬性,在下面定義顯示內容
<router-view name="sidebar"></router-view>
<router-view name="content"></router-view>
</div>
</div>
<script src="https://cdn.bootcss.com/vue/2.5.13/vue.js"></script>
<script src="https://cdn.bootcss.com/vue-router/3.0.1/vue-router.js"></script>
<script>
var routes = [
{
path:'/user',
//注意這裡的components,分別定義兩個router-view顯示內容
components: {
//sidebar的router-view
sidebar:{
template:`
<ul>
<li>使用者1</li>
<li>使用者2</li>
</ul>
`
},
//content的router-view
content:{
template:`
<div>使用者內容區域</div>
`
}
}
},
{
path:'/post',
//注意這裡的components,分別定義兩個view顯示內容
components:{
sidebar:{
template:`
<ul>
<li>帖子1</li>
<li>帖子2</li>
</ul>
`
},
content:{
template:`
<div>帖子內容區域</div>
`
}
}
}
];
var router = new VueRouter({
routes: routes
})
new Vue({
el:"#app",
router: router,
})
</script>
5、導航鉤子
實現的功能:如果使用者在未登入狀態下訪問"/post"或"/post/more"頁面,則會跳轉到"/login"頁面.
//方法一:通過判斷路由的方式
<div id="app">
<div>
<router-link to="/">主頁</router-link>
<router-link to="/login">登入</router-link>
<router-link to="/post">帖子管理</router-link>
<router-view></router-view>
</div>
</div>
<script src="https://cdn.bootcss.com/vue/2.5.13/vue.js"></script>
<script src="https://cdn.bootcss.com/vue-router/3.0.1/vue-router.js"></script>
<script>
var routes = [
{
path:'/',
component: {
template:`
<div>
<h1>首頁</h1>
</div>
`
}
},
{
path:"/login",
component:{
template:`
<div><h2>登入</h2></div>
`
}
},
{
path:'/post',
component:{
template:`
<div>
<h1>帖子1</h1>
<router-link to="more" append>檢視更多</router-link>
<router-view></router-view>
</div>
`
},
children:[
{
path:'more',
component:{
template:`
<h3>我是更多資訊!</h3>
`
}
}
]
}
];
var router = new VueRouter({
routes: routes
})
router.beforeEach(function(to,from,next){
console.log(to)
var logged_in = false;
//some() 方法用於檢測陣列中的元素是否滿足指定條件,如果有一個元素滿足條件,則表示式返回true , 剩餘的元素不會再執行檢測.
//to.matched返回的是陣列。
if(!logged_in && to.matched.some(function(val){return val.path == '/post'})){
this.router.push("/login")
}
else{
next()
}
})
new Vue({
el:"#app",
router: router,
})
</script>
//方法二:在路由中設定meta屬性
<div id="app">
<div>
<router-link to="/">主頁</router-link>
<router-link to="/login">登入</router-link>
<router-link to="/post">帖子管理</router-link>
<router-view></router-view>
</div>
</div>
<script src="https://cdn.bootcss.com/vue/2.5.13/vue.js"></script>
<script src="https://cdn.bootcss.com/vue-router/3.0.1/vue-router.js"></script>
<script>
var routes = [
{
path:'/',
component: {
template:`
<div>
<h1>首頁</h1>
</div>
`
}
},
{
path:"/login",
component:{
template:`
<div><h2>登入</h2></div>
`
}
},
{
path:'/post',
//設定meta屬性,指定"是否需要登入"
meta:{
login_required: true
},
component:{
template:`
<div>
<h1>帖子1</h1>
<router-link to="more" append>檢視更多</router-link>
<router-view></router-view>
</div>
`
},
children:[
{
path:'more',
component:{
template:`
<h3>我是更多資訊!</h3>
`
}
}
]
}
];
var router = new VueRouter({
routes: routes
})
router.beforeEach(function(to,from,next){
console.log(to)
var logged_in = false;
//some() 方法用於檢測陣列中的元素是否滿足指定條件,如果有一個元素滿足條件,則表示式返回true , 剩餘的元素不會再執行檢測.
//通過獲取meta值判此頁面是否需要登入後才可訪問
if(!logged_in && to.matched.some(function(item){return item.meta.login_required })){
this.router.push("/login")
}
else{
next()
}
})
new Vue({
el:"#app",
router: router,
})
</script>
三、易錯知識點——元件
1、父元件向子元件傳遞資訊時:
在html中定義或者繫結屬性的時候要符合kebab-case規則
<div id="dr2">
<!-- kebab-case in html -->
<child2 my-message2="Hello, this is kebab-case message!"></child2>
</div>
在js中定義的屬性名稱如果是"camelCase"規則,則在html定義或者繫結value的時候要用"kebab-case"規則。
Vue.component("child2", {
//在js中用駝峰命名法
props: ["myMessage2"],
template: "<div>myMessage2: {{myMessage2}}</div>"
});
注意:下圖中的<child></child>才是字串模板,是通過template生成的,在這裡的props需要使用kebab-case形式,在js中使用camelCase形式。
2、prop驗證屬性
注意:下圖所說的"諸如data,computed 或methods等例項屬性還無法使用",指的是子元件自身定義的data,computed,methods屬性。而非父元件的相應屬性。
3、props中default屬性
注意:使用default屬性時,在父元件繫結的資料不需要再data函式中賦值。
在元件中的props中,針對String,Number型別中的default,直接對應值。其他型別的default是函式。(如果使用default屬性,就不能加上required:true屬性)如下:
//son元件的props屬性
props:{
msg:{
type:String,
default: "abc"
},
num:{
type:Number,
default:10
},
myObj:{
type:Object,
//default為函式
default: function (){
return {name:"joy"}
}
}
}
//parent元件傳遞的值
<son :msg="msgFather"></son>
<script>
export default {
name: "Parent",
data() {
//此處不需要定義msgFather的值
return {};
},
components: {
son
}
};
</script>
4、作用域插槽
插槽的資料是子傳父的!!!
注:在vue 2.5.0之前,"slot-scope"必須使用到template身上。如下:
//2.5.0之前寫法——父元件
<template>
<div class="parent">
<h1>我是父親!</h1>
<son>
//將slot和slot-scope屬性放在template上
<template slot="slot1" slot-scope="key">
<h2 >{{ key.text}}</h2>
</template>
//slot-scope屬性值可以使任意的,此處為"key"
<template slot="slot2" slot-scope="key">
<h2>{{key.text}}</h2>
</template>
</son>
</div>
</template>
//2.5.0以後版本寫——父元件
<template>
<div class="parent">
<h1>我是父親!</h1>
<son>
//slot-scope屬性值可以使任意的,此處為"key"
<h2 slot="slot1" slot-scope="key">{{ key.text}}</h2>
<h2 slot="slot2" slot-scope="key">{{key.text}}</h2>
</son>
</div>
</template>
//對應的子元件
<template>
<div class="son">
<slot name="slot1" text="slot111111"></slot>
<slot name="slot2" text="slot222222"></slot>
</div>
</template>
5、動態元件
<template>
<div class="big">
//通過comonent標籤的is屬性繫結當前的view檢視
<component :is="currentView"> </component>
</div>
</template>
<script>
import small1 from "./small1"
export default {
name: "big",
data(){
return{
//注意此處的small元件需要加引號
currentView: 'small1'
}
},
components:{
small1
}
}
</script>
四、易錯知識點——自定義指令
1、全域性定義指令:directive!!!
全域性指令需要在main.js中去定義,如下:
//mian.js,全域性定義中用directive。
Vue.directive('focus',{
inserted:function(el){
el.focus();
}
})
//hello.vue
<template>
<div>
//使用指令方式:v-*
<input type="text" v-focus>
</div>
</template
2、區域性定義指令:directives!!!
<template>
<div class="big">
<input type="text" v-focus>
</div>
</template>
<script>
export default {
name: "hello",
//注:區域性定義指令需要用directives,與全域性定義不同。
directives:{
focus:{
inserted (el){
el.focus();
}
}
}
}
</script>
五、易錯知識點——路由
1、路由使用物件形式
//通過urlData.*獲得相應值
<router-link :to="urlData.hello">helloworld</router-link>
<router-link :to="urlData.parent">parent</router-link>
<router-view/>
data(){
return{
urlData:{
hello:'/',
parent:'/parent'
}
}
}
2、路由傳遞引數(常用此方法!!!)
首先,在router/index.js檔案中:
export default new Router({
routes: [
{
//冒號後面跟著引數
path:'/parent/:father',
name:'parent',
component: parent
}
]
})
然後在parent.vue元件
<template>
<div class="parent">
//這裡通過$route.params.*獲取傳遞過來的路由引數
<h1>我是父親:{{$route.params.father}}</h1>
</div>
</template>
<script>
export default {
//設定parent.vue元件的name屬性,傳遞引數是需要用到name屬性值
name: "parent",
}
</script>
最後,找到parent對應的路由設定元件,配置如下
//router-link的name屬性對應的是parent.vue元件的name值.params是傳遞過去的路由引數
<router-link :to="{name:'parent',params:{father:1}}">parent</router-link>
注意:這樣的傳遞引數方式,最後的路由形式為:'localhost:8080/parent/father/1'。這種事很常見的路由傳遞引數。
3、路由巢狀:children
在router/index.js檔案中:
export default new Router({
routes: [
{
path:"/",
name:"HelloWorld",
component:HelloWorld
},
{
path:'/parent',
name:'parent',
//重定向,預設進來就顯示father元件的內容,在parent元件路由中配置
redirect:"/parent/father",
component: parent,
children:[
{
//這裡的path不加'/',直接寫名字即可,它會自動補全前面的路徑
path:'father',
name:'father',
component:Father
},
{
path:'mother',
name:'mother',
component:Mother
}
]
}
]
})
在parent元件中:
//這裡的to屬性值要寫完整的路徑
<router-link to="/parent/father">father</router-link>
<router-link to="/parent/mother">mother</router-link>
<router-view></router-view>
4、路由高亮
(1)、被選中的路由會帶有"router-link-exact-active 、router-link-active"樣式,所以可以給啟用狀態的路由設定樣式。
//新增啟用樣式
.router-link-active{color:red;}
注意:此時會有一個問題,對於首頁路由"/",會在同級路由被選中的時候依然會帶有router-ink-active類名,這時候需要做在首頁路由做修改:
//在router-link上新增exact屬性
<router-link to="/" exact>home</router-link>
(2)router-link-active這個啟用類名比較長,對此,我們可以在router/index.js中進行全域性配置:
export default new Router({
//全域性設定linkActiveClass為acitve,這樣啟用狀態的class就會變為active,相應的樣式就可以改為.active{color:red;}
linkActiveClass:"active",
routes: [
{
path:'/',
name:HelloWorld,
component:HelloWorld
},
{
path:'/parent/:father',
name:'parent',
component: parent
}
]
})
六、易錯知識點——methods
(1)、箭頭函式不可用
注意: 在methods屬性中定義的方法不能使用箭頭函式,因為此時的this指向的是window,而不是Vue例項。
(2)、
//此處直接呼叫事件,並沒有'()'
<button @click="showSome">click me </button>
methods:{
showSome :function (event){
//得到的就是滑鼠事件
console.log(event)
}
}
結果:
(3)、
//此處直接呼叫事件,並加上'()',但是並沒有引數傳遞![圖片描述][4]
<button @click="showSome()">click me </button>
methods:{
showSome :function (event){
//這樣得到event就是'undefined'
console.log(event)
}
}
結果:
(4)、
//此處直接調事件,如果想獲得滑鼠事件,傳遞的引數必須是$event否則就不要傳遞引數了
<button @click="showSome($event)">click me </button>
methods:{
showSome :function (event){
//這樣得到event就是'滑鼠事件'
console.log(event)
}
}
結果:
!!! (5)、methods 和 computed 不同使用方式:
computed可以向methods一樣傳遞引數:解決辦法是使用閉包
//key是傳遞的引數
computed:{
getTitle(key):function(){
return function(){
return key + "abc"
}
}
}
七、易錯知識點——select預設選中
1、vue中設定select預設選中:v-model
<template>
<div class="hello">
//select上通過v-model繫結預設選中項
<select name="" id="" v-model="city">
<option value="" v-for="item in cityList" :value="item.value" v-text="item.city"></option>
</select>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
cityList:[
{value:"001",city:"南京市"},
{value:"002",city:"深圳市"},
{value:"004",city:"杭州市"},
{value:"005",city:"北京市"},
{value:"003",city:"上海市"},
],
//通過city值設定預設選中城市
city:"003"
}
}
}
</script>
結果如圖所示:
八、易錯知識點——v-model
1、一般form表單會使用v-model比較多,實現資料的雙向繫結
<input v-model="sth" />
<input v-bind:value="sth" v-on:input="sth = $event.target.value" />
要理解這行程式碼,首先你要知道 input 元素本身有個 oninput 事件,這是 HTML5 新增加的,類似 onchange ,每當輸入框內容發生變化,就會觸發 oninput ,把最新的value傳遞給 sth。進而實現了資料雙向繫結。
總結:
在給元素新增v-model屬性時,預設會把value作為元素的屬性,然後把input 事件作為實時傳遞value的觸發事件。
//子元件
Vue.component('currency-input', {
template: `
<span>
<input
@input="$emit('input', $event.target.value)">
</span>
`
})
//父元件中呼叫子元件
<currency-input v-model="price"></currentcy-input>
<!--上行程式碼是下行的語法糖-->
<currency-input :value="price" @input="price = arguments[0]"></currency-input>