1.Vue基础语法
1-1.学习方法
Vue 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
任何一门框架的学习,最好的资料都是官网;能把VUE官网理解,使用Vue.js是游刃有余的。
VUE官网:https://cn.vuejs.org/v2/guide/;
初学者建议看基础视频教程,从头到尾代码敲一遍,掌握基础知识点,再完整阅读官网,进行深化理解。
基础知识准备:JS语法、ES6、Webpack、npm。
1-2.使用Vue.js实现Hello World
Vue 不支持 IE8 及以下版本,因为 Vue 使用了 IE8 无法模拟的 ECMAScript 5 特性。但它支持所有兼容 ECMAScript 5 的浏览器。
1.首先到官网https://cn.vuejs.org/v2/guide/installation.html 找到多版本安装教程,选择【开发版本】;
2.在编辑器创建一个 .js 的文档(如:Vue.js),把【开发版本】的代码复制到 .js 文档并保存;
3.创建一个 index.html ,编写”hello world” 的实例;
4.以 script 标签 src 的形式引入;
5.el :是element 的意思;
6.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Vue 入门</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="root">{{msg}}</div>
<script>
// var dom = document.getElementById('app');//原生js写法
// dom.innerHTML = 'hello world'
// setTimeout(function(){
// dom.innerHTML = 'bye world'
// }, 2000) //意思是2秒后hello world 变为bye world
new Vue({
el:"#root",
data:{
msg:"hello world"
}
})
setTimeout(function(){
app.$data.msg = 'bye world'
}, 2000) //意思是2秒后hello world 变为bye world
</script>
</body>
1-3.挂载点、模板、实例之间的关系
挂载点:指的是Vue实例里的el属性对应的dom节点 id。
模板:在挂载点内部的所有内容,视频中div里面的内容。也可以在Vue实例中用 template 属性替换。
实例:定义挂载点,把定义的数据与模版结合起来生成要展示的内容,再把这个内容放在挂载点中;Vue实例只会对相应的 el 属性产生作用。
凡是以 $ 开头的,指的都是Vue的实例属性,或者实例方法
<body>
<div id="root"></div>
<script>
new Vue({
el:"#root",
template:'<h1>hello {{msg}}</h1>',
data:{
msg:"hello world"
}
})
</script>
</body>
1-4.Vue 实例中的数据,事件和方法
重要的指令:
插值表达式 : {{变量}}
v-text=”变量”:输出一个文本,会进行转义
v-html=”变量”:输出HTML格式,不会进行转义
v-html与v-text的区别在于,前者将html标签里的内容渲染出来,而后者连同标签一同显示
v-on:click=”函数名” 绑定事件, 可以简写为@click=”函数名” 事件执行方法写在 methods:{} 里面。
v-if 控制显示
v-for 循环渲染
v-model可用表单元素
vue不是面向dom编程,而是数据编程
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Vue 入门</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="root">
<div v-on:click="handleClick">{{content}}</div>
</div>
<script>
new Vue({
el:"#root",
data:{
content:"hello"
},
methods:{
handleClick:function(){
this.content="world"
}
}
})
</script>
</body>
</html>
1-5.Vue中的属性绑定和双向绑定
1、属性绑定
//可以缩写成:
2、双向数据绑定:
content展示什么是由数据决定的
数据决定页面的显示,但是页面无法决定你数据里面的内容 v-model
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>属性绑定和双向数据绑定</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="root">
<div :title="'liaozhou '+ title">hello world</div>
<input v-model="content"/>
<div>{{content}}</div>
</div>
<script>
new Vue({
el:"#root",
data:{
title:"this is hello world",
content:"this is content"
}
})
</script>
</body>
</html>
1-6.Vue中的计算属性和侦听器
computed:根据其他数据计算出来的新的结果,其他数据变化的时候进行计算,其他数据没有变化的时候直接读取缓存中的值
watch:侦听器指的是监测某一个数据或者计算属性是否发生变化,,一旦这个数据发生了变化,就可以在watch里面做业务逻辑
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>计算属性和侦听器</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="root">
姓:<input v-model="firstName"/>
名:<input v-model="lastName"/>
<div>{{fullName}}</div>
<div>{{count}}</div>
</div>
<script>
new Vue({
el:"#root",
data: {
firstName:'',
lastName:'',
count:0
},
computed:{
fullName:function(){
return this.firstName +'' + this.lastName
}
},
watch:{
fullName:function(){
this.count ++
}
}
})
</script>
</body>
</html>
1-7.v-if,v-shou与v-for指令
v-if控制DOM的存在与否
v-show控件DOM的显示与否
v-for控制一组数据,来循环显示数据 (v-for=“item of list”:循环展示一组数据)
v-if 当值为false时,直接将该标签元素从DOM元素中移除,是摧毁与重建过程;
v-show 当值为false时,改变css属性为display:none,只是视觉上的隐藏;如果显示隐藏的频率较高的话,用v-show更好,性能高一些
用index序号来保证每一个key值是不一样
key:每一项的key值都不能相同, 一般可以用 v-for=”(item,index) in list” :key=”index”
但是如果需要频繁排序的话,key值不适合用index,(为什么不能使用 index,自己去研究) 会有问题。
v-for=’(item,index) of list’ item 是变量
this.$emit(“delete”,this.index) 子元素和父元素之间通信
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>v-if,v-shou,v-for指令</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="root">
<div v-if="show">hello world</div>
<button @click="handleClick">toggle</button>
<ul>
<li v-for="(item,index) of list" :key="index">{{item}}</li>
</ul>
</div>
<script>
new Vue({
el:"#root",
data:{
show:true,
list:[1,2,3]
},
methods:{
handleClick:function(){
this.show=!this.show;
}
}
})
</script>
</body>
</html>
1-8.Vue中的样式绑定
1-8-1.class 的对象绑定,利用style 和class 来实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue中的样式绑定</title>
<script src="./vue.js"></script>
<style>
.activated {
color:red;
}
</style>
</head>
<body>
<div id="app">
<div @click="handleDivClick"
:class="{activated: isActivated}"
>
hello world
</div>
</div>
<script>
var vm = new Vue ({
el: "#app",
data:{
isActivated:false
},
methods:{
handleDivClick:function(){
this.isActivated= !this.isActivated
}
}
})
</script>
</body>
</html>
1-8-2.class 的数组绑定,可绑定多个变量,变量定义样式,利用style 和class 来实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue中的样式绑定</title>
<script src="./vue.js"></script>
<style>
.activated {
color:red;
}
</style>
</head>
<body>
<div id="app">
<div @click="handleDivClick"
:class="[activated,activatedOne]"
>
hello world
</div>
</div>
<script>
var vm = new Vue ({
el: "#app",
data:{
activated:"",
activatedOne:"activated-one"
},
methods:{
handleDivClick:function(){
//三元表达式
this.activated=this.activated==="activated"?"":"activated"
}
}
})
</script>
</body>
</html>
1-8-3.style 的数据绑定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue中的样式绑定</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="app">
<div :style="styleObj" @click="handleDivClick">
hello world
</div>
</div>
<script>
var vm = new Vue({
el: "#app",
data:{
styleObj:{
color:"black"
}
},
methods: {
handleDivClick:function(){
this.styleObj.color=this.styleObj.color ===
"black"?"red":"black";
}
}
})
</script>
</body>
</html>
1-8-4.style 的数组绑定
2.Vue中的组件
2-1.todolist功能开发
- input双向绑定
- 循环列表
- 绑定提交事件:把value插入数组内 this.list.push(this.dataValue)
- 提交后,input为空this.dataValue=””
- 向列表中添加数据用 push( ) 如:this.list.pust(this.inputValue)
- 写JQ是操作DOM ;vue是在操作数据、
- 点击提交,将input的内容放进数组中
- 数组有内容,列标签会自动循环,将数据输出
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="vue.js"></script>
</head>
<body>
<div id = "root">
<div>
<input v-model="inputValue" />
<button @click="handlerSubmit">提交</button>
</div>
<ul>
<li v-for="(item,index) of list" :key="index">{{item}}</li>
</ul>
</div>
<script>
new Vue({
el:"#root",
data: {
inputValue:'',
list:[]
},
methods: {
handlerSubmit: function() {
this.list.push(this.inputValue)
this.inputValue=''
}
}
})
</script>
</body>
</html>
2-2.todolist 组件拆分
2-2-1.全局组件:在页面任何地方都能使用
//定义全局组件<br /> Vue.component("todo-item", {<br />props:['content'],<br /> template: "<label>我是全局组件</label>"<br /> });<br /> new Vue({<br /> el: "#root",<br /> });<br /> //使用全局组件<br /> <div id="root"><br /> <todo-item></todo-item><br /> </div>
Vue.component(‘’) Vue提供的创建组件的方法;
template 创建组件的模板
直接在html中有个
组件拆分之后的传参问题:外部(html页面)可以通过自定义属性的形式传参,组件要定义props[]接收属性
//父组件向子组件传递数据:通过props属性接收传来的参数;props可以是数组。
Vue.component(“todo-item-2”, {
props: [“content”, “index”],//接收从外部传进来的属性content、index
template: “
});
2-2-2.局部组件:要在外层Vue实例里进行注册
//定义局部组件<br /> var todoItem = {<br /> template: "<label>我是局部组件</label>"<br /> }
new Vue({<br /> el: "#root1",<br /> components: { //局部组件:要在挂载点(它的外层Vue实例,即此处的root1)进行注册<br /> "todo-item-1": todoItem<br /> }<br /> });
//使用局部组件<br /><div id="root1"><br /> <todo-item-1></todo-item-1><!--局部组件:只能在挂载点底下使用--><br /> <todo-item></todo-item><!--全局组件:在页面任何地方都能使用--><br /> </div>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="vue.js"></script>
</head>
<body>
<div id = "root">
<div>
<input v-model="inputValue" />
<button @click="handlerSubmit">提交</button>
</div>
<ul>
<todo-item
v-for="(item,index) of list"
:key="index"
:content="item"
>
</todo-item>
</ul>
</div>
<script>
Vue.component('todo-item',{
props:['content'],
template:'<li>{{content}}</li>'
})//这是全局组件
// var TodoItem = {
// template:'<li>item</li>'
// }//这是局部组件
new Vue({
el:"#root",
// components:{
// 'todo-item':TodoItem
// },
data: {
inputValue:'',
list:[]
},
methods: {
handlerSubmit: function() {
this.list.push(this.inputValue)
this.inputValue=''
}
}
})
</script>
</body>
</html>
2-3.组件与实例的关系
- Vue中的每个组件都是vue的实例,每个Vue实例就是由多个组件组成的;在Vue项目中,是由千千万万个vue实例组成的
- 如果vue的实例没有模板,找到挂载点(root),把挂载点的div标签下的所有内容当做实例的模板来使用。如果不定义模板,他会使用dom标签的的内容作为实例的模板。
- 组件由template(模板),props(接受数据),methods(方法);组件中也可以加计算属性;;data;compute,
<script>
Vue.component('todo-item',{
props:['content'],
template:'<li @click="handleClick">{{content}}</li>',
methods:{
handleClick:function(){
alert('clicked')
}
}
})//这是全局组件
// var TodoItem = {
// template:'<li>item</li>'
// }//这是局部组件
new Vue({
el:"#root",
// components:{
// 'todo-item':TodoItem
// },
data: {
inputValue:'',
list:[]
},
methods: {
handlerSubmit: function() {
this.list.push(this.inputValue)
this.inputValue=''
}
}
})
</script>
2-4.实现 todolist 的删除功能
父组件通过属性的形式向子组件传递数据
子组件向父组件传递值是通过发布订阅模式的形式传递的,当子组件发布一个事件,父组件订阅了这个事件,这时父组件就接受到了子组件传递的数据;
2-4-1.发布订阅模式
$emit(‘delete’,this.index )
$emit(‘funA’),emit是动词,意思是发行,发表,在这里可以理解为发布携带的事件funA。子主件使用$emit(‘funA’)发布的事件可以被父组件 v:on (即@funA=’funB’)侦听,随即触发父组件绑定的事件funB。
父子组件数据传递:想删除子组件中的数据:
1,子组件的handleClick方法,该组件会用 this.$emit 方法通知给父组件,触发一个叫 delete 的自定义事件,通知的值为 this.index。这里的 this.index 是前面从父组件中递过来的。
2,父组件用 @delete(v-on:delete)=”handleDelete” 来监听子组件的事件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>todoList</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="box">
<input type="text" v-model="txtValue">
<input type="button" @click='handleClick' value="提交">
<ul>
<todo-item
v-for="(item,index) of list"
:key="index"
:content="item"
:index="index"
@delete="handleDelete">
</todo-item>
</ul>
</div>
<script>
//创建一个全局组件
Vue.component('todo-item', {
props: ['content', 'index'],
template: '<li @click="handleClick">{{content}}</li>',
methods: {
handleClick: function () {
this.$emit('delete', this.index)
}
}
})
new Vue({
el: "#box",
data: {
txtValue: '',
list: []
},
methods: {
handleClick: function () {
this.list.push(this.txtValue),
this.txtValue = ''
},
handleDelete: function (index) {
this.list.splice(index, 1)
}
}
})
</script>
</body>
</html>
如果用普通的由子传父的方式,很麻烦。如图功能有没有简单的方法实现呢。
props:[‘item’,’index’],
template:’
methods:{
deleteItem:function(){
this.$root.list.splice(this.index,1)//子组件这样写就好了,通过$root访问到父组件,然后直接操作父组件的数据,就不用采用老师讲的发布订阅模式了,但是老师讲的这个知识点还是必须掌握的,老师也说了这是vue的重点
2-5.Vue-cli的简介与使用
Vue介绍:
数据驱动的组件,为现代化的Web界面而生
Vuejs不是一个框架,它只是一个提供MVVM风格的双向数据绑定的库,专注于UI层面。
Vue安装:
1)独立版本:
①下载并用