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>
九、v-for循环时在class名中添加变量
实现如下图的情况:
<template>
<div class="qq_face faceout">
<a v-for="(value, key) in stack.faceData" :key="key" :title="value" :class="setClass(key)" @click="faceImgSel(value)">{{value}}</a>
<!-- 将class值赋给方法,动态生成对象 -->
</div>
</template>
export default {
methods: {
setClass(key) {
let obj = {face: true}
obj[`qqface${key}`] = true
return obj
}
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。