前言

文档笔记来源:kuangshenstudy,清华大学出版社,结合视频资源食用更佳,相关资源源码在文末,有需要自取。

一、概述

Vue是什么?

Vue.js是基于JavaScript的一套MVVC的前端框架。集合了众多优秀的主流框架设计思想,轻量、数据驱动(默认单向数据绑定,但也支持双向数据绑定)、学习成本低。 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

MVVM是什么?

MVVM层实现了前后端更好的分离(前端需要的数据只需要请求后端的接口即可)。
MVVM是Model-View-ViewModel的简写。它本质上就是MVC 的改进版。vm指定的是ViewModel,是视图模型。

ViewModel是MVVM模式的核心,是连接View和Model的桥梁。它有两个方向:

  1. 将模型转化成试图,将后端传递的数据转化成用户看到的界面。
  2. 将试图转化成模型,即将所看到的页面转化成后端的数据。
    在Vue.js框架中这两个方向都实现了,就是Vue.js中数据的双向绑定。

MVVM模式的实现者

Model:模型层, 在这里表示JavaScript对象
View:视图层, 在这里表示DOM(HTML操作的元素)
ViewModel:连接视图和数据的中间件, Vue.js就是MVVM中的View Model层的实现者

为什么要使用MVVM

MVVM模式和MVC模式一样,主要目的是分离视图(View)和模型(Model),有几大好处

低耦合:视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的View上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
可复用:可以把一些视图逻辑放在一个ViewModel里面,让很多View重用这段视图逻辑。
独立开发:开发人员可以专注于业务逻辑和数据的开发(ViewMode),设计人员可以专注于页面设计。
可测试:界面素来是比较难以测试的,而现在测试可以针对ViewModel来写。

二、Here we go!

1、第一个Vue程序(基于idea安装vus插件开发)

1.1引用vue.js 使用cdn导入

<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

或者

<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>

不推荐新手直接使用 vue-cli

1.2创建一个空项目,创建一个文件夹,new一个HTML文件

Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统:

(模板块,后期可直接复制模板)

<div id="app">{{ message }}
</div>
var app = new Vue({el: '#app',data: {message: 'Hello Vue!'}
})

万物始于hello word 创建第一个 vue.js

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title></head><body><!--view层,模板-->
<div id="app"><!--    数据绑定-->{{message}}
</div>
<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">// 创建一个Vue实例var vm = new Vue({el:"#app",/*Model:数据*/data:{message:"hello vue~"}});
</script></body>
</html>

说明:

  • el:“#app” -----> 绑定元素的ID
  • data:{message:“hello vue~”} ----> 数据对象中有一个名为message的属性,并设置了初始值 hello,vue ~
  • {{message}} -----> 实现数据绑定功能

    测试:

为了能够更直观的体验Vue带来的数据绑定功能, 我们需要在浏览器测试一番, 操作流程如下:
  1、在浏览器上运行第一个Vue应用程序, 进入开发者工具
  2、在控制台输入vm.message=‘HelloWorld’, 然后回车, 你会发现浏览器中显示的内容会直接变成HelloWorld,不需要刷新页面
  此时就可以在控制台直接输入vm.message来修改值, 中间是可以省略data的, 在这个操作中, 我并没有主动操作DOM, 就让页面的内容发生了变化, 这就是借助了Vue的数据绑定功能实现的; MV VM模式中要求View Model层就是使用观察者模式来实现数据的监听与绑定, 以做到数据与视图的快速响应。
  

2、熟悉ES 6的语法

2.1为什么要使用ES 6

ES6是一次重大的版本升级,与此同时,由于ES6秉承着最大化兼容已有代码的设计理念,过去编写的 JS 代码还能正常运行。事实上,许多浏览器已经支持部分ES6特性,并继续努力实现其余特性。这意味着,在一些已经实现部分特性的浏览器中,开发者符合标准的 JavaScript 代码已经可以正常运行,可以更加方便地实现很多复杂的操作,提高开发人员的工作效率。
以下是ES6排名前十位的最佳特性列表(排名不分先后)

  • Default Parameters (默认参数)
  • Template Literals (模板文本)
  • Multi - line Strings (多行字符串)
  • Destructuring Assignment (解构赋值)
  • Enhanced Object Literals (增强的对象文本)
  • Arrow Functions (箭头函数)
  • Promises
  • Block - Scoped Constructs Let and Const (块作用域构造 Let and Const )
  • Classes(类)
  • Modules(模块)

2.2块作用域构造let和const

块级声明用于声明在指定块的作用域之外无法访问的变量。这里的块级作用域是指函数内部或
者字符{}内的区域。
在ES6中, let 是一种新的变量声明方式。在函数作用域或全局作用域中,通过关键字 var 声明
的变量,无论在哪里声明,都会被当成在当前作用域顶部声明的变量。

 function calculateTotalAmount ( vip )(
//只能使用 var 方式定义变量var amount =0;if ( vip ){//在此定义会被覆盖var amount=1;//在此定义会被覆盖var amount=100;//在此定义会被覆盖var amount=1000;return amount;} //打印内容console.log(calculateTotal/^mount (true));

以上结果将返回1000,这是一个bug,在ES 6中,用let限制块级作用域,而var限制函数作用域。

funetion calculateTotalAmount(vip){
//使用 var 方式定义变量 var amount =0;if(vip){
//使用1et定义的局部变量let amount =1;//第1个 let let amount =100;//第2个 let let amount =1000;//第3个 let }return amount ;}console.log(calculateTotalAmount(true));

程序结果将会是0,因为块作用域中有了 let ,如果 amount=1 ,那么这个表达式将返回1。本例是一个演示,这里有一堆常量,它们互不影响,因为它们属于不同的块级作用域。
JavaScript 中的 var 只能声明一个变量,这个变量可以保存任何数据类型的值。ES6之前并没有定义声明常量的方式,ES6标准中引入了新的关键字 const 来定义常量。
使用 const 定义常量后,常量将无法改变, const 常量的用法说明如下。

1、const常量,只能一次赋值

const PI=3.14159;
PI=3.14;//报错 Assignment to constant variable.

2、对象常量

对象的属性可以修改,对象的引用不能修改

const obj={name:"kerr"};
obj.name="tom";

3、冻结对象

防止修改对象的属性

const obj=Object.freeze({name:"kerr"});
obj.name="tom";//报错,提示冻结对象不能再重新定义赋值

2.3模板字面量

2.3.1 Multi - line Strings (多行字符串)

ES 6的多行字符串是一个实用的功能,在ES 5中我们只能使用以下方法来表示多行字符串:

var roadPoem =, 江南好,风景旧曾谙。'
+,日出江花红胜火,1
+,春来江水绿如蓝。,
+,能不忆江南?'
+'忆江南-江南好1;

然而在ES 6中,仅仅用反引号就可以解决

var roadPoem = `江南好,风景旧曾谙。
日出江花红胜火,
春来江水绿如蓝。
能不忆江南?

2.3.2字符串占位符

使用模板和插入值是在字符串里输出变量的方式,在ES 5中开发者可以组合一个字符串

//在ES 6之前只能使用组合字符串的方式
var name = * your name is * + first + * ' +last + *.*;
var url=* http://localhost:3000/api/messages/* +id;

在ES 6 中,占位符是使用语法${NAME}的,将包含的NAME变量或者表达式放在反引号中

var name=`your name is ${first} ${last}. `;
var url=`http://localhost:3000/api/messages/${id}`;

2.4默认参数和rest参数

JavaScript定义默认参数的方式如下:

//JavaScript原先定义方式
var link=function (height,color,url){
var height =height || 50;
var color=color  | | * red*;
var url=url || 'http://baidu.com';
}

在ES 6中,可以直接把默认值放在函数申明中:

var link = function (height=50,color=* red*,url=`http://baidu.com *)

ES 6引入rest参数,用于获取函数的实参,不过rest参数不适合参数个数不确定的函数

ES 5中获取函数的实参:

function data(){
console.log(arguments);
}
data('pg','xj','jz');

在ES 6中,使用rest参数获取函数的实参:

function data(...args){
console.log(args);
}
data('苹果','香蕉','橘子');

rest参数必须放在参数最后的位置

function fn(a,b,...args){
console.log(a);
console.log(b);
console.log(args);
}
fn(100,200,300,400,500,600);

2.5解构赋值

house和mouse是key,同时也是hi变量

var data=$('body') . data();//data拥有两个属性house和mouse
house=data.house;
mouse=data.mouse;
//在Note.js中使用ES 5代码
var j sonMiddleware=require('bady-parser').j sonMiddleware;
var body=req.body;//body的两个属性,username和password
username = body.username;
password=body.password;

在ES 6中可以使用以下代码替换ES 5的代码

var { house,mouse)=$(1 body').data;
var (jsonMiddleware}=require('body-pareser');
var (username,password)=req.body;
//这个也同样适合数组
var [col1,col2]=$(' .cplumn*),[line1z line2,line3z,line5]=file.split(ln');

2.6展开运算符

第一个用途:组装数组

let color = ['red', 'yellow'];
let colorful = [...color, 'green', 'blue'];
console.log(colorful); // ["red", "yellow", "green", "blue"]

第二个用途:获取数组除了某几项的其他项

let num = [1, 3, 5, 7, 9];
let [first, second, ...rest] = num;
console.log(rest); // [5, 7, 9]

2.7增强的对象文本

2.7.1通过变量进行对象初始化

const
a=100,b=200,c=300;
obj={abc
};

2.7.2简化定义对象方法

const lib={sum(a,b) { return a+b;},mult(a,b) {return a*b;}
};
console.log(lib.sum(100,200));//300
console.log(lib.mult(100,200));//20000

这里不能使用ES 6箭头函数(=>),因为该方法需要一个名称。如果直接命名每个方法,则可以使用=>箭头函数。例如:

const lib={sum:(a,b)=>a+b,mult:(a,b)=>a*b
};
console.log(lib.sum(100,200));//300
console.log(lib.mult(100,200));//20000

2.7.3动态属性键

通过在方括号[]内置表达式,可以在ES 6中到那个太分配对象键

const
key1='one',
obj={[key1]:100,two:200,three:300
};
//表示obj.one=100,obj.two=200,obj.three=300

2.7.4解构属性中的变量

在ES 6中,通过解构可以创建于等效对象属性同名的变量。

const myObjecct={one:'洗衣机',two:'冰箱',three:'空调'
};
const{one,two,three}=myObject;
//表示    one='洗衣机',   two='冰箱',    three='空调'

2.8箭头函数

CoffecScript 就是因为有丰富的箭头函数,所以让很多开发者所喜爱。在ES6中,也有丰富的箭头出数。比如,以前我们使用闭包, this 总是预期之外地产生改变,而箭头函数的好处在于,现在 this 可以按照你的预期使用了,身处箭头函数里面, this 还是原来的 this 。
有了箭头函数,我们就不必像使用 that = this 或 self = this 、_ this = this 、 bind ( this )那么麻烦了。例如,下面的代码使用ES5就不是很优雅:

 var _this=this ;
$(*.btn *).click ( function (event){
this.ssenData();
})_

在ES6中则不需要使用_ this = this :

$ (*.btn*).click((event)=>{
this.sendData();
})

但并不是完全否定之前的方案,ES6委员会决定,以前的 function 的传递方式也是一个很好的方案,所以它们仍然保留了以前的功能。
下面是另一个例子,通过 call 传递文本给 logUpperCase ()函数,在ES5中:

 var logUpperCase = function (){var this = this ;this.string = this.string.toUpperCase ();return function (){return console.log (_this.string );}}logUpperCase .call({ string:*ES 6 rocks *});//而在Es6中并不需要用 this 浪费时间var logUpperCase = function (){this.string=this.string.toUpperCase ();
return()=>console.log(this.string);
}logUpperCase .call({string: * ES 6 rocks *})();

2.8Promise实现

在ES 6中有标准的Promise实现
下面是使用setTimeout()函数实现异步延迟加载函数;

setTimeout(function){
console.log('yay!*);
},1000);
var wait1000 = new Promise((resolve,reject)=>(
setTimeout(resolve,1000);
}).then(()=>(
console.log(* yay!*);
});

3、熟悉Vue.js的语法

3.1 v-bind

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><div id="app"><span v-bind:title="message">鼠标悬停几秒钟查看此处动态绑定的提示信息!</span><!--1.导入Vue.js--><script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script><script type="text/javascript">// 创建一个Vue实例var vm = new Vue({el:"#app",/*Model:数据*/data:{message:"mest Stduying vue "}});</script>
</div>
</body>
</html>


说明:

  • 看到的 v-bind attribute 被称为指令。指令带有前缀 v-,以表示它们是 Vue 提供的特殊 attribute
  • 它们会在渲染的 DOM 上应用特殊的响应式行为

3.2 v-if、v-else

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title></head>
<!--Vue基本语法-->
<body><!--view层,模板-->
<div id="app">
<span v-bind:title="message">鼠标悬停几秒钟查看此处动态绑定的提示信息!</span><br><!--v-if else--><h1 v-if="type">yes</h1><h2 v-else>No</h2><h1 v-if="type==='A'">A</h1><h1 v-else-if="type==='B'">B</h1><h1 v-else="type==='C'">C</h1></div>
<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">// 创建一个Vue实例var vm = new Vue({el:"#app",data:{message:"你好 vue~",// type:truetype:'A',counter :0,message:"mest Stduying vue "},methods: {//方法必须定义在Vue的method对象中sayHi:function (event) {alert(this.message);}},});
</script></body>
</html>


说明:

  • 在浏览器上运行,打开控制台
  • 在控制台输入vm.type=false然后回车,你会发现浏览器中显示的内容会直接变成NO
    注:使用v-*属性绑定数据是不需要双花括号包裹的

3.3 v-for

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title></head>
<!--Vue基本语法-->
<body><!--view层,模板-->
<div id="app">
<!--v-for--><li v-for="item in items">{{item.message}}</li></div>
<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">// 创建一个Vue实例var vm = new Vue({el:"#app",data:{message:"你好 vue~",// type:truetype:'A',items: [{message:'java-vue'},{message:'前端+后端'},{message:'java+mysql'}],counter :0,message:"mest Stduying vue "},methods: {//方法必须定义在Vue的method对象中sayHi:function (event) {alert(this.message);}},});
</script></body>
</html>

3.4 v-on

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title></head>
<!--Vue基本语法-->
<body><!--view层,模板-->
<div id="app">
<span v-bind:title="message">鼠标悬停几秒钟查看此处动态绑定的提示信息!</span><br>
<!--v-on    -->
<button v-on:click="sayHi">click me</button><button v-on:click="counter +=1">add</button><p>The button above has been clicked {{ counter }} times.</p></div>
<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">// 创建一个Vue实例var vm = new Vue({el:"#app",data:{// type:truetype:'A',counter :0,message:"mest Stduying vue "},methods: {//方法必须定义在Vue的method对象中sayHi:function (event) {alert(this.message);}},});
</script></body>
</html>

3.5 v-html

该指令用于更新元素的innerHtml。内容按普通html插入。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title></head><body><!--view层,模板-->
<div id="app"><!--    数据绑定--><p v-html="message">古诗欣赏:</p>
</div>
<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">// 创建一个Vue实例var vm = new Vue({el:"#app",/*Model:数据*/data:{message:'<h3 style="color:red"> 老去惜花心已懒,爱梅犹绕江村。</h3>'}});
</script></body>
</html>

4、Vue 表单双向绑定

v-model 在内部为不同的输入元素使用不同的 property 并抛出不同的事件:

  • text 和 textarea 元素使用 value property 和 input 事件;
  • checkbox 和 radio 使用 checked property 和 change 事件;
  • select 字段将 value 作为 prop 并将 change 作为事件。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title></head>
<!--双向绑定 v-model-->
<body><!--view层,模板-->
<div id="app">
输入的是:<input type="text" v-model="message">{{message}}<br>
输入的是:<textarea type="text" v-model="message"></textarea>{{message}}</div>
<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">// 创建一个Vue实例var vm = new Vue({el:"#app",data:{message:"123"}});
</script></body>
</html>


说明:
在文本区域插值 ({{text}}) 并不会生效,应用 v-model 来代替

复选框、多选框、下拉框

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title></head><body><!--view层,模板-->
<div id="app"><!--Gender:--><input type="radio" name="sex" value="Men" v-model="mest" >Men<input type="radio" name="sex" value="Female"  v-model="mest">Female<p>choose which:{{mest}}</p>
<br>
<!--    下拉框:-->
<select v-model="selected" ><option value="" disabled name="one">--请选择--</option><option>A</option>
<!--    <option selected>B</option>--><option >B</option><option>C</option>
</select><p>choose which:{{selected}}</p><br>
<!--    复选框:--><input type="checkbox" value="足球" v-model="check"><label>足球</label><input type="checkbox" value="汽车" v-model="check"><label>汽车</label><input type="checkbox" value="音乐" v-model="check"><label>音乐</label><input type="checkbox" value="游戏" v-model="check"><label>游戏</label>
<p>choose which:{{check}}</p></div>
<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">// 创建一个Vue实例var vm = new Vue({el:"#app",// data:{//     mest:''// }// data:{//     selected:''// }data:{mest:'',selected:'',check:['足球']}});
</script></body>
</html>

组件:
组件是可复用的Vue实例, 说白了就是一组可以重复使用的模板, 跟JSTL的自定义标签、Thymeleal的th:fragment等框架有着异曲同工之妙,通常一个应用会以一棵嵌套的组件树的形式来组织

  • Vue.component():注册组件
  • cvzhanshi:自定义组件的名字
  • template:组件的模板

5、Axios异步通信

  • 从浏览器中创建XMLHttpRequests
  • 从node.js创建http请求
  • 支持Promise API[JS中链式编程]
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换JSON数据
  • 客户端支持防御XSRF(跨站请求伪造)

测试Axios

准备data数据

{"name": "qingjiang","url": "https://www.baidu.com/","page": 1,"isNonProfit": true,"address": {"street": "含光门","city": "陕西西安","country": "中国"},"links": [{"name": "bilibili","url": "https://bilibili.com"},{"name": "mest","url": "https://www.baidu.com/"},{"name": "百度","url": "https://www.baidu.com/"}]
}

测试:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><style>[v-cloak]{display: none;}</style>
</head>
<!--解决闪烁问题v-cloak-->
<div id="vue" v-cloak><div>{{info.name}}</div><div>{{info.address}}</div><a v-bind:href="info.url">click me</a></div>
<body>
<!--引入js文件-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script type="text/javascript">var vm = new Vue({el:"#vue",//data()方法 data: 属性data(){return{//请求的返回参数合适,必须和json字符串一致info:{name:null,address:{street:null,city:null,country:null},url:null}}},mounted(){//钩子函数axios.get('../data.json').then(response=>(this.info=response.data));}});
</script>
</body>
</html>

说明:

  • 在这里使用了v-bind将a:href的属性值与Vue实例中的数据进行绑定
  • 使用axios框架的get方法请求AJAX并自动将数据封装进了Vue实例的数据对象中
  • 我们在data中的数据结构必须和Ajax响应回来的数据格式匹配

Vue生命周期图

6、Vue 计算属性、内容分发、自定义事件

6.1 计算属性

计算属性的重点突出在属性两个字上(属性是名词),首先它是个属性其次这个属性有计算的能力(计算是动词),这里的计算就是个函数:简单点说,它就是一个能够将计算结果缓存起来的属性(将行为转化成了静态的属性),仅此而已;可以想象为缓存

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title></head><body><!--view层,模板-->
<div id="app">
<p>NowTime:{{currentTime1()}}</p>
<p>ComTime:{{currentTime2}}</p></div>
<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">// 创建一个Vue实例var vm = new Vue({el:"#app",data:{message:"hello mest"},methods:{currentTime1:function () {return Date.now();//返回一个时间戳}},// 计算属性:methods和computed方法不能重名computed:{currentTime2:function () {this.message;return Date.now();}}});
</script></body>
</html>

注意:methods和computed里的东西不能重名,重名之后,只会调用methods的方法

说明:

  • methods:定义方法, 调用方法使用currentTime1(), 需要带括号
  • computed:定义计算属性, 调用属性使用currentTime2,
    不需要带括号:this.message是为了能够让currentTime2观察到数据变化而变化
  • 如何在方法中的值发生了变化,则缓存就会刷新!可以在控制台使用vm.message=”你好呀",
    改变下数据的值,再次测试观察效果!

6.2 内容分发(插槽)

在Vue.js中我们使用元素作为承载分发内容的出口,可以称其为插槽,可以应用在组合组件的场景中。

需求:需要把下面的内容,让标题和内容通过插槽插入内容

<p>标题</p>
<ul><li>abcd</li><li>abcd</li><li>abcd</li>
</ul>

定义一个代办事情的组件

 Vue.component('todo',{template:'<div>\<div>代办事项</div>\<ul>\<li>cvzhanshi study Java</li>\</ul>\</div>'});

将上面的代码留出一个插槽,即slot

 Vue.component('todo',{template:'<div>\<slot"></slot>\<ul>\<slot"></slot>\</ul>\</div>'});

定义一个名为todo-title的待办标题组件 和 todo-items的待办内容组件

Vue.component('todo-title',{props:['title'],template:'<div>{{title}}</div>'});//这里的index,就是数组的下标,使用for循环遍历的时候,可以循环出来!Vue.component("todo-items",{props:["item","index"],template:"<li>{{index+1}},{{item}}</li>"});

slot通过name和组件绑定

 Vue.component('todo',{ var vm = new Vue({el:"#vue",data:{`在这里插入代码片`todoItems:['test1','test2','test3']}});template:'<div>\<slot name="todo-title"></slot>\<ul>\<slot name="todo-items"></slot>\</ul>\</div>'});

实例化Vue并初始化数据

 var vm = new Vue({el:"#vue",data:{todoItems:['test1','test2','test3']}});

将数据通过插槽插入预留出来的位置

<todo><todo-title slot="todo-title" v-bind:title="title"></todo-title><todo-items slot="todo-items" v-for="item in todoItems" :item="item" ></todo-items></todo>

说明:

  • ​ slot:是绑定组件用的
  • ​ :title --> 是v-bind:title的缩写

完整代码:

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml"><head><meta charset="UTF-8"><title>Title</title></head><body><!--view层,模板--><div id="vue"><todo><todo-title slot="todo-title" v-bind:title="title"></todo-title><!--<todo-items slot="todo-items" v-for="{item,index} in todoItems" v-bind:item="item"></todo-items>--><!--如下为简写--><todo-items slot="todo-items" v-for="item in todoItems" :item="item" ></todo-items></todo></div><!--1.导入Vue.js--><script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script><script type="text/javascript">Vue.component('todo',{template:'<div>\<slot name="todo-title"></slot>\<ul>\<slot name="todo-items"></slot>\</ul>\</div>'});Vue.component('todo-title',{props:['title'],template:'<div>{{title}}</div>'});//这里的index,就是数组的下标,使用for循环遍历的时候,可以循环出来!Vue.component("todo-items",{props:["item"],template:"<li>{{item}}</li>"});var vm = new Vue({el:"#vue",data:{title:"mest study vue",todoItems:['test1','test2','test3']}});</script></body>
</html>

7、小结

核心:数据驱动,组件化

优点:借鉴了AngularJS的模块化开发和React的虚拟Dom,虚拟Dom就是把Demo操作放到内存中执行;

常用的属性:
v-if
v-else-if
v-else
v-for
v-on绑定事件,简写@
v-model数据双向绑定
v-bind给组件绑定参数,简写:

组件化:
组合组件slot插槽
组件内部绑定事件需要使用到this.$emit(“事件名”,参数);
计算属性的特色,缓存计算数据


三、第一个vue-cli项目

3.1 Vue-cli简介

vue-cli官方提供的一个脚手架,用于快速生成一个vue的项目模板
预先定义好的目录结构及基础代码,就好比咱们在创建Maven项目时可以选择创建一个骨架项目,这个估计项目就是脚手架,我们的开发更加的快速

3.2 环境配置

Node.js

下载地址: http://nodejs.cn/download/ 安装的时候一直下一步直到结束

确认是否安装成功: 在cmd中运行node -v命令,查看是否能够输出版本号 在cmd中运行npm -v命令,查看是否能够输出版本号

安装node.js淘宝镜像加速器(cnpm)

-g 就是全局安装
npm install cnpm -g

或使用如下语句解决npm速度慢的问题,但是每次install都需要 npm install
–registry=https://registry.npm.taobao.org

安装vue-cli

cnpm install vue-cli-g
#测试是否安装成功#查看可以基于哪些模板创建vue应用程序,通常我们选择webpack
vue list

3.3 第一个vue-cli应用程序

创建一个基于webpack模板的vue应用程序

  1. 打开DOS系统窗口,进入到D盘

D:\Work\IdeaProjects-Vue\

  1. 创建一个名为myvue项目。

输入vue create mydemo 按下回车,
提示选择配置方式,包括Vue2.x默认配置、Vue3.0默认配置和手动配置,使用方向键选择Vue3.0(第二个),然后只需等待几秒加载。
提示:项目名称不能为大写,否则无法成功创建

  1. 项目创建成功后,在对应盘符可以看见项目文件夹,就可以启动项目。

使用"cd myvue"进入项目文件夹,然后使用脚手架提供的“npm run serve”命令启动。

  1. 如图,出现对应端口号后,可以去本地浏览器访问端口,localhost:8080即可。

    提示:创建或加载过程中可能出现加载失败需要fix的情况,当出现问题时,它会给出提示,我们按照提示来就行。通过 npm audit fix来修复就行。极端情况:重新install,再重复以上操作。

四、webpack使用

WebPack是一款模块加载器兼打包工具, 它能把各种资源, 如JS、JSX、ES 6、SASS、LESS、图片等都作为模块来处理和使用

4.1 使用webpack

安装:

npm install webpack -g
npm install webpack-cli -g

测试安装成功:

webpack -v
webpack-cli -v

配置:

entry:入口文件, 指定Web Pack用哪个文件作为项目的入口
output:输出, 指定WebPack把处理完成的文件放置到指定路径
module:模块, 用于处理各种类型的文件
plugins:插件, 如:热更新、代码重用等
resolve:设置路径指向
watch:监听, 用于设置文件改动后直接打包

4.2 使用webpack

创建项目:

创建一个webpack文件夹,使用idea打开

  1. 创建一个名为modules的目录,用于放置JS模块等资源文件
  2. 在modules下创建模块文件hello.js
//暴露一个方法:sayHi
exports.sayHi = function(){document.write("<div>Hello Webpack</div>");
}
  1. 在modules下创建一个名为main.js的入口文件main.js,用于打包时设置entry属性
//require 导入一个模块,就可以调用这个模块中的方法了
var hello = require("./hello");
hello.sayHi();
  1. 在项目目录下创建webpack.config.js配置文件,使用webpack命令打包
module.exports = {entry:"./modules/main.js",output:{filename:"./js/bundle.js"}
}
  1. 打包:
    说明:打包如果失败,就用管理员权限运行webpack

在项目目录下创建HTML页面,如index.html,导入webpack打包后的JS文件

<!doctype html>
<html lang="en">
<head><meta charset="UTF-8"><title>狂神说Java</title>
</head>
<body>
<script src="dist/js/bundle.js"></script>
</body>
</html>

直接运行index.html

提示:

参数–watch 用于监听变化,如果要打包的东西有变化,就重新打包
webpack --watch

五、vue-router路由

5.1 安装

基于第一个vue-cli进行测试学习; 先查看node modules中是否存在vue-router, vue-router是一个插件包, 所以我们还是需要用n pm/cn pm来进行安装的

npm install vue-router --save-dev

如果在一个模块化工程中使用它,必须要通过Vue.use()明确地安装路由功能

import Vue from 'vue'
import VueRouter from 'vue-router'Vue.use(VueRouter);

5.2 测试路由

  • 删除第一个vue-cli项目中的没用的东西
  • components 目录下存放我们自己编写的组件
  • 定义几个自己的组件 Content.vue 、Main.vue、mest.vue

Content.vue

<template><div><h1>内容页</h1></div>
</template><script>export default {name:"Content"}
</script>

Main.vue

<template><div><h1>首页</h1></div>
</template><script>export default {name:"Main"}
</script>

Mest.vue

<template><div><h1>Mest</h1></div>
</template><script>export default {name:"Mest"}
</script>
  • 安装路由,在src目录下,新建一个文件夹:router,专门存放路由,配置路由index.js
import Vue from'vue';
//导入路由插件
import Router from 'vue-router';
//导入上面定义的组件
import Content from '../components/Content';
import Main from '../components/Main';
import Mest from "../components/Mest";
//安装路由
// Vue.use(Router) ;
createApp(App).use(router).mount('#app')
//配置路由
export default new Router({routes:[{//路由路径path:'/content',//路由名称name:'content',//跳转到组件component:Content},{//路由路径path:'/main',//路由名称name:'main',//跳转到组件component:Main},{//路由路径path:'/mest',//路由名称name:'main',//跳转到组件component:Mest}]
});
  • 在main.js中配置路由
import Vue from 'vue';
import App from './App';import router from './router';//自动扫描里面的路由配置
Vue.config.productionTip = false;/* eslint-disable no-new */
new Vue({el: '#app',router,components: { App },template: '<App/>'
})
  • 在App.vue中使用路由
<template><div id="app"><!--router-link:默认会被渲染成一个<a>标签,to属性为指定链接router-view:用于渲染路由匹配到的组件--><h1>cVzhanshi</h1><router-link to="/main">首页</router-link><router-link to="/content">内容</router-link><router-link to="/mest">mest</router-link><router-view></router-view></div>
</template><script>export default {name: 'App',}
</script>
  • 运行npm run dev,然后浏览器访问localhost:8080

六、电影购票APP开发实战

6.1脚手架搭建

  • 选择好项目存放的目录,使用Vue脚手架创建一个项目,项目名称为:buyfilm。

vue create buyfilm

按照图示选择功能,选择路由器使用history模式


6.2系统构架

本项目使用的都是本地静态资源,主要是前端展示。
其中public文件夹用来存放项目的静态文件。
在src中,放置了所有的源码文件。components用来放置比较小的的、公用的组件。
views用来放置三个主页面文件。
routers用来放置路由,其中index.js文件是主路由。
main.js是项目入口文件的JavaScript逻辑,在webpack打包之后将被注入到index.html页面中。

6.3项目运行效果:

通过运行 :npm run serve 后会展示出本地网址,打开链接就能访问本购票系统。

App主页面展示效果:


6.4设计项目组件

6.4.1设计头部和底部导航组件

1、头部组件(Header)

<template><header id="header"><h1>{{title}}</h1></header>
</template><script>export default {name: "Header",// props是子组件访问父组件数据的唯一接口props:{title:{type:String,default:'风云电影'}}}
</script>
<!--scoped属性实现了私有化的样式-->
<style scoped>#header{width: 100%;height: 50px;color: #ffffff;background: #e54847;border-bottom:1px solid #e54847;position: relative;}#header h1{font-size: 18px;text-align: center;line-height: 50px;font-weight: normal;}#header i{position: absolute;left: 5px;top: 50%;margin-top: -13px;font-size: 26px;}
</style>

2、底部导航组件(TabBar)

<template><div id="footer"><!--router-link>组件支持用户在具有路由功能的应用中单击导航。通过to属性指定目标地址,默认渲染为带有正确连接的<a>标签,可以通过配置tag属性生成别的标签。另外,当目标路由成功激活时,链接元素自动设置一个表示激活的css类名--><ul><router-link tag="li" to="/movie"><i class="fa fa-film"></i><p>电影</p></router-link><router-link tag="li" to="/cinema"><i class="fa fa-youtube-square"></i><p>影院</p></router-link><router-link tag="li" to="/mine"><i class="fa fa-user-circle"></i><p>我的</p></router-link></ul></div>
</template><script>export default {name: "Tabbar"}
</script><style scoped>#footer{width: 100%;height: 50px;background: white;border-top: 2px solid #ebe8e3;position: fixed;left: 0;bottom: 0;}#footer ul{display: flex;text-align: center;height: 50px;align-items: center;}#footer ul li{flex: 1;height: 40px;}#footer li.active{color: #f03d37;}/* router-link-active:路由中自带的样式 选中时的颜色*/#footer li.router-link-active{color: #f03d37;}#footer ul i{font-size: 20px;}#footer ul p{font-size: 12px;line-height: 18px;}
</style>

6.4.2设计电影页面组件

1、城市组件(City)

<template><div class="city_body"><div class="city_list"><div class="city_hot"><h2>热门城市</h2><ul class="clearfix"><li>北京</li><li>上海</li><li>天津</li><li>合肥</li><li>郑州</li></ul></div><div class="city_sort"><div><h2>A</h2><ul><li>阿克苏</li><li>安康</li><li>安庆</li></ul></div><div><h2>B</h2><ul><li>白山</li><li>白城</li><li>宝鸡</li></ul></div><div><h2>C</h2><ul><li>沧州</li><li>长春</li><li>昌吉</li></ul></div><div><h2>D</h2><ul><li>大理</li><li>大连</li><li>大庆</li></ul></div><div><h2>E</h2><ul><li>鄂尔多斯</li><li>恩施</li><li>鄂州</li></ul></div></div></div><div class="city_index"><ul><li>A</li><li>B</li><li>C</li><li>D</li><li>E</li></ul></div></div>
</template>
<script>export default {name: "City"}
</script>
<style scoped>#content .city_body{margin-top: 45px;display: flex;width: 100%;position: absolute;top: 0;bottom: 0;}.city_body .city_list{flex: 1;overflow: auto;background: #fff5f0;}.city_body .city_list::-webkit-scrollbar{background-color: transparent;width: 0;}.city_body .city_hot{margin-top: 20px;}.city_body .city_hot h2{padding-left: 15px;line-height: 30px;font-size: 14px;background: #f0f0f0;font-weight:normal;}.city_body .city_hot ul li{float: left;background: #fff;width: 29%;height: 33px;margin-top: 15px;margin-left: 3%;padding:0 4px;border: 1px solid #e6e6e6;border-radius: 3px;line-height: 33px;text-align: center;box-sizing: border-box;}.city_body .city_sort div{margin-top: 20px;}.city_body .city_sort h2{padding-left: 15px;line-height: 30px;font-size: 14px;background: #f0f0f0;font-weight: normal;}.city_body .city_sort ul{padding-left: 10px;margin-top: 10px;}.city_body .city_sort ul li{line-height: 30px;}.city_body .city_index{width: 20px;display: flex;flex-direction: column;justify-content: center;text-align: center;border-left:1px solid #e6e6e6;}
</style>

2、正在热映(NowPlaying)

<template><div class="movie_body"><ul><li><div class="pic_show"><img src="../../../public/images/001.png" alt=""></div><div class="info_list"><h2>机械师2:复活</h2><p>观众评<span class="grade"> 8.9</span></p><p>主演: 杰森·斯坦森 杰西卡·阿尔芭 汤米·李·琼斯 杨紫琼 山姆·哈兹尔丁</p><p>今天50家影院放映800场</p></div><div class="btn_mall">购票</div></li><li><div class="pic_show"><img src="../../../public/images/002.png" alt=""></div><div class="info_list"><h2>敢死队</h2><p>观众评<span class="grade"> 8.7</span></p><p>主演: 西尔维斯特·史泰龙,杰森·斯坦森,梅尔·吉布森</p><p>今天50家影院放映750场</p></div><div class="btn_mall">购票</div></li><li><div class="pic_show"><img src="../../../public/images/003.png" alt=""></div><div class="info_list"><h2>最后的巫师猎人</h2><p>观众评<span class="grade"> 8.4</span></p><p>主演: 范·迪塞尔,萝斯·莱斯利,伊利亚·伍德,迈克尔·凯恩,丽纳·欧文</p><p>今天50家影院放映600场</p></div><div class="btn_mall">购票</div></li><li><div class="pic_show"><img src="../../../public/images/004.png" alt=""></div><div class="info_list"><h2>饥饿游戏3</h2><p>观众评<span class="grade"> 7.6</span></p><p>主演: 詹妮弗·劳伦斯,乔什·哈切森,利亚姆·海姆斯沃斯</p><p>今天50家影院放映550场</p></div><div class="btn_mall">购票</div></li><li><div class="pic_show"><img src="../../../public/images/005.png" alt=""></div><div class="info_list"><h2>钢铁骑士</h2><p>观众评<span class="grade"> 7.3</span></p><p>主演: 本·温切尔,乔什·布雷纳,玛丽亚·贝罗, 迈克·道尔, 安迪·加西亚</p><p>今天50家影院放映500场</p></div><div class="btn_mall">购票</div></li><li><div class="pic_show"><img src="../../../public/images/006.png" alt=""></div><div class="info_list"><h2>奔跑者</h2><p>观众评<span class="grade"> 6.6</span></p><p>主演: 尼古拉斯·凯奇,康妮·尼尔森,莎拉·保罗森,彼得·方达</p><p>今天50家影院放映500场</p></div><div class="btn_mall">购票</div></li></ul></div>
</template>
<script>export default {name: "NowPlaying"}
</script>
<style scoped>#content .movie_body{flex: 1;overflow: auto;}.movie_body ul{margin: 0 12px;overflow: hidden;}.movie_body ul li{margin-top: 12px;display: flex;align-items: center;border-bottom: 1px solid #e6e6e6;padding-bottom: 10px;}.movie_body .pic_show{width: 64px;height: 90px;}.movie_body .pic_show img{width: 100%;}.movie_body .info_list{margin-left:10px;flex: 1;position: relative; }.movie_body .info_list h2{font-size: 17px; line-height: 24px;width: 150px;overflow: hidden;white-space: nowrap;text-overflow:ellipsis ;}.movie_body .info_list p{font-size:13px;color: #666;line-height: 22px;width: 200px;overflow: hidden;white-space: nowrap;text-overflow:ellipsis ;}.movie_body .info_list .grade{font-weight: 700;color: #faaf00;font-size: 15px;}.movie_body .info_list img{width: 50px;position: absolute;right: 10px;top: 5px;}.movie_body .btn_mall, .movie_body .btn_pre{width: 47px;height: 27px;line-height: 28px;text-align: center;background-color: #f03d37;color: #fff;border-radius: 4px;font-size: 12px;cursor: pointer;}.movie_body .btn_pre{background-color: #3c9fe6;}
</style>

3、即将上映(ComingSoon)

<template><div class="movie_body"><ul><li><div class="pic_show"><img src="../../../public/images/007.png" alt=""></div><div class="info_list"><h2>佐罗和麦克斯</h2><p><span class="person">46465</span>人想看</p><p>主演:格兰特·鲍尔 艾米·斯马特 博伊德·肯斯特纳</p><p>未来30天内上映</p></div><div class="btn_pre">预售</div></li><li><div class="pic_show"><img src="../../../public/images/008.png" alt=""></div><div class="info_list"><h2>废材特工</h2><p><span class="person">64645</span>人想看</p><p>主演: 杰西·艾森伯格,克里斯汀·斯图尔特,约翰·雷吉扎莫</p><p>未来30天内上映</p></div><div class="btn_pre">预售</div></li><li><div class="pic_show"><img src="../../../public/images/009.png" alt=""></div><div class="info_list"><h2>凤凰城遗忘录</h2><p><span class="person">42465</span>人想看</p><p>主演:Clint Jordan</p><p>未来30天内上映</p></div><div class="btn_pre">预售</div></li><li><div class="pic_show"><img src="../../../public/images/010.png" alt=""></div><div class="info_list"><h2>新灰姑娘</h2><p><span class="person">46465</span>人想看</p><p>主演: Cassandra Morris,Kristen Day</p><p>未来30天内上映</p></div><div class="btn_pre">预售</div></li><li><div class="pic_show"><img src="../../../public/images/011.png" alt=""></div><div class="info_list"><h2>鲨卷风4:四度觉醒</h2><p><span class="person">38465</span>人想看</p><p>主演: 塔拉·雷德,Ian Ziering,Masiela Lusha</p><p>未来30天内上映</p></div><div class="btn_pre">预售</div></li><li><div class="pic_show"><img src="../../../public/images/012.png" alt=""></div><div class="info_list"><h2>全境警戒</h2><p><span class="person">46465</span>人想看</p><p>主演: 戴夫·巴蒂斯塔,布兰特妮·斯诺,Angelic Zambrana</p><p>未来30天内上映</p></div><div class="btn_pre">预售</div></li></ul></div>
</template><script>export default {name: "ComingSoon"}
</script><style scoped>#content .movie_body{flex: 1;overflow: auto;}.movie_body ul{margin: 0 12px;overflow: hidden;}.movie_body ul li{margin-top: 12px;display: flex;align-items: center;border-bottom: 1px solid #e6e6e6;padding-bottom: 10px;}.movie_body .pic_show{width: 64px;height: 90px;}.movie_body .pic_show img{width: 100%;}.movie_body .info_list{margin-left:10px;flex: 1;position: relative; }.movie_body .info_list h2{font-size: 17px; line-height: 24px;width: 150px;overflow: hidden;white-space: nowrap;text-overflow:ellipsis ;}.movie_body .info_list p{font-size:13px;color: #666;line-height: 22px;width: 200px;overflow: hidden;white-space: nowrap;text-overflow:ellipsis ;}.movie_body .info_list .grade{font-weight: 700;color: #faaf00;font-size: 15px;}.movie_body .info_list img{width: 50px;position: absolute;right: 10px;top: 5px;}.movie_body .btn_mall, .movie_body .btn_pre{width: 47px;height: 27px;line-height: 28px;text-align: center;background-color: #f03d37;color: #fff;border-radius: 4px;font-size: 12px;cursor: pointer;}.movie_body .btn_pre{background-color: #3c9fe6;}
</style>

4、搜索组件(Search)

<template><div class="search_body"><div class="search_input"><div class="search_input_wrapper"><i class="fa fa-search"></i><input type="text"></div></div><div class="search_result"><h3>电影/电视剧/综艺</h3><ul><li><div class="img"><img src="../../../public/images/001.png" alt=""></div><div class="info"><p><span>机械师2 </span><span>8.9</span></p><p>剧情,喜剧,犯罪</p><p>2020-6-30</p></div></li></ul></div></div>
</template>
<script>export default {name: "Search"}
</script>
<style scoped>#content .search_body{flex: 1;overflow: auto;}.search_body .search_input{padding: 8px 10px;background-color: #f5f5f5;border-bottom: 1px solid #e5e5e5;}.search_body .search_input_wrapper{padding: 0 10px;border: 1px solid #e6e6e6;border-radius: 5px;background-color: #fff;display: flex;}.search_body .search_input_wrapper i{font-size: 16px;padding: 4px 0;}.search_body .search_input_wrapper input{border: none;font-size: 13px;color: #333;padding: 4px 0;outline: none;}.search_body .search_result h3{font-size: 15px;color: #999;padding: 9px 15px;border-bottom: 1px solid #e6e6e6;}.search_body .search_result li{border-bottom: 1px #c9c9c9 dashed;padding: 10px 15px;box-sizing: border-box;display: flex;}.search_body .search_result .img{width: 60px;float: left;}.search_body .search_result .img img{width: 100%;}.search_body .search_result .info{float: left;margin-left: 15px;flex: 1;}.search_body .search_result .info p{height: 22px;display: flex;line-height: 22px;font-size: 12px;}.search_body .search_result .info p:nth-of-type(1) span:nth-of-type(1){font-size: 18px;flex: 1;}.search_body .search_result .info p:nth-of-type(1) span:nth-of-type(2){font-size: 16px;color: #fc7103;}
</style>

6.4.3设计影院页面组件

影院列表组件(CiList)

<template><div class="cinema_body"><ul><li><div><span>大地影院延庆金锣湾店</span><span class="q"><span class="price"> 38.5</span> 元起</span></div><div class="address"><span>延庆区北街39号H座首层</span><span> >100km </span></div><div class="card"><div>小吃</div><div>折扣卡</div></div></li><li><div><span>燕山影剧院</span><span class="q"><span class="price"> 37.5</span> 元起</span></div><div class="address"><span>房山区燕山岗南路3号</span><span> >120km</span></div><div class="card"><div>小吃</div><div>折扣卡</div></div></li><li><div><span>万达影城昌平保利光魔店</span><span class="q"><span class="price"> 37.9</span> 元起</span></div><div class="address"><span>昌平区鼓楼南街佳莲时代广场四层</span><span> >80km </span></div><div class="card"><div>小吃</div><div>折扣卡</div></div></li><li><div><span>门头沟影剧院</span><span class="q"><span class="price"> 30.9</span> 元起</span></div><div class="address"><span>门头沟区新桥大街12号</span><span>  >110km </span></div><div class="card"><div>小吃</div><div>折扣卡</div></div></li></ul></div>
</template>
<script>export default {name: "CiList"}
</script>
<style scoped>#content .cinema_body{flex: 1;overflow: auto;}.cinema_body ul{padding: 20px;}.cinema_body li{border-bottom: 1px solid #e6e6e6;margin-bottom: 20px;}.cinema_body div{margin-bottom: 10px;}.cinema_body .q{font-size: 11px;color: #f03d37;}.cinema_body .price{font-size: 18px;}.cinema_body .address{font-size: 13px;color:#666;}.cinema_body .address span:nth-of-type(2){float: right;}.cinema_body .card{display: flex;}.cinema_body .card div{padding: 0 3px;height: 15px;line-height: 15px;border-radius:2px;color: #f90;border:1px solid #f90;}.cinema_body .card div.or{color: #f90;border: 1px solid #f90;}.cinema_body .card div.bl{color: #589daf;border: 1px solid #589daf;}
</style>

6.4.4设计我的页面组件

只有一个登录/注册组件(未实现后端交互)

<template><div class="login_body"><div><input class="login_text" type="text" placeholder="账号/手机号/邮箱"></div><div><input class="login_text" type="password" placeholder="请输入您的密码"></div><div class="login_btn"><input type="submit" value="登录"></div><div class="login_link"><a href="#">立即注册</a><a href="#">找回密码</a></div></div></template><script>export default {name: "Login"}
</script><style scoped>#content .login_body{width: 100%;}.login_body .login_text{width: 100%;height: 40px;border: none;border-bottom: 1px #ccc solid;margin:0 5px;outline: none;}.login_body .login_btn{height: 50px;margin: 10px;}.login_body .login_btn input{display: block;width: 100%;height: 100%;background: #e54847;border-radius: 3px;border: none;color: white;}.login_body .login_link{display: flex;justify-content: space-between;}.login_body .login_link a{text-decoration: none;margin: 0 5px;font-size: 12px;color:#e54847;}
</style>

6.5设计项目页面组件及路由配置

6.5.1电影页面组件及路由

<template><div id="main"><!-- 头部组件--><Header title="风云电影"></Header><div id="content"><div class="movie_menu"><router-link tag="div" to="/movie/city" class="city_name"><span>北京 </span><i class="fa fa-caret-down"></i></router-link><div class="hot_swtich"><router-link tag="div" to="/movie/nowPlaying" class="hot_item active">正在热映</router-link><router-link tag="div" to="/movie/comingSoon" class="hot_item">即将上映</router-link></div><router-link tag="div" to="/movie/search" class="search_entry"><i class="fa fa-search"></i></router-link></div><!--二级路由渲染--><keep-alive><router-view></router-view></keep-alive></div><!-- 尾部组件--><TabBar></TabBar></div>
</template>
<script>import Header from '../../components/Header';import TabBar from '../../components/TabBar';export default {name:'Movie',components:{Header,TabBar}}
</script>
<style scoped>#content .movie_menu{width: 100%;height: 45px;border-bottom: 1px solid #e6e6e6;display: flex;justify-content: space-between;}.movie_menu .city_name{margin-left: 20px;height: 100%;line-height: 45px;}.movie_menu .city_name.router-link-active{color: #ef4238;border-bottom: 2px solid #ef4238;box-sizing: border-box;}.movie_menu .hot_swtich{display: flex;height: 100%;line-height: 45px;}.movie_menu .hot_item{font-size: 15px;color: #666;width: 80px;text-align: center;margin: 0 12px;font-weight: 700;}.movie_menu .hot_item.router-link-active{color: #ef4238;border-bottom:2px solid #ef4238;}.movie_menu .search_entry{margin-right: 20px;height: 100%;line-height: 45px;}.movie_menu .search_entry.router-link-active{color: #ef4238;border-bottom:2px solid #ef4238;box-sizing: border-box;}.movie_menu .search_entry i{font-size: 24px;color: red;}
</style>

配置路由:

// movie路由
export default {path:'/movie',//按需载入的方式component:()=>import('../../views/Movie'),// 二级路由,使用children进行配置children:[{path:'city',component:()=>import('../../components/City')},{path:'nowPlaying',component:()=>import('../../components/NowPlaying')},{path:'comingSoon',component:()=>import('../../components/ComingSoon')},{path:'search',component:()=>import('../../components/Search')},// 重定向:当路径为/movie时,重定向到/movie/nowPlaying路径{path:'/movie',redirect:'/movie/nowPlaying'}]
}

6.5.2影院页面组件及路由

<template><div id="main"><Header title="风云影院"></Header><div id="content"><div class="cinema_menu"><div class="city_switch">全城 <i class="fa fa-caret-down"></i></div><div class="city_switch">品牌 <i class="fa fa-caret-down"></i></div><div class="city_switch">特色 <i class="fa fa-caret-down"></i></div></div><CiList></CiList></div><TabBar></TabBar></div>
</template>
<script>import Header from '../../components/Header';import TabBar from '../../components/TabBar';import CiList from '../../components/CiList';export default {name:'Cinema',components:{Header,TabBar,CiList}}
</script>
<style scoped>
#content .cinema_menu{width: 100%;height: 45px;border-bottom: 1px solid #e6e6e6;display: flex;justify-content: space-around;align-items: center;background: white;
}
</style>

配置路由:

// Cinema路由
export default {path:'/cinema',component:()=>import('../../views/Cinema')
}

6.5.3我的页面组件及路由

<template><div id="main"><Header title="我的影院"></Header><div id="content"><Login></Login></div><TabBar></TabBar></div>
</template>
<script>import Header from '../../components/Header';import TabBar from '../../components/TabBar';import Login from '../../components/Login';export default {name:'Mine',components:{Header,TabBar,Login}}
</script>
<style scoped></style>

配置路由:

// mine路由
export default {path:'/mine',component:()=>import('../../views/Mine')
}

总结

百度文库源码提取链接:https://pan.baidu.com/s/1k_65SO6rIQxDaTe-So3lpw
提取码:点赞文章后私聊
参考文献:《Vue.js 3.0从入门到精通》清华大学出版社
文档参考:https://blog.csdn.net/qq_45408390/article/details/118151297
Vue中文文档:https://cn.vuejs.org/v2/guide/

Vue.js 3.0快速入门(附电影购票APP开发实战源码)相关推荐

  1. 【转】Vue.js 2.0 快速上手精华梳理

    Vue.js 2.0 快速上手精华梳理 Sandy 发掘代码技巧:公众号:daimajiqiao 自从Vue2.0发布后,Vue就成了前端领域的热门话题,github也突破了三万的star,那么对于新 ...

  2. 不会几个框架,都不好意思说搞过前端: Vue.js - 60分钟快速入门

    Vue.js--60分钟快速入门 Vue.js是当下很火的一个JavaScript MVVM库,它是以数据驱动和组件化的思想构建的.相比于Angular.js,Vue.js提供了更加简洁.更易于理解的 ...

  3. 开源三级联动,Vue.js编写省份、城市、区、县三级联动源码

    开源三级联动,Vue.js编写省份.城市.区.县三级联动源码 1.三级联动框样式 上图: 请访问:这里!! 查看三级联动器效果. 2.如何在html里面引用 文件的目录路径为: data.js是存放我 ...

  4. 基于JAVA星星电影购票网站计算机毕业设计源码+系统+数据库+lw文档+部署

    基于JAVA星星电影购票网站计算机毕业设计源码+系统+数据库+lw文档+部署 基于JAVA星星电影购票网站计算机毕业设计源码+系统+数据库+lw文档+部署 本源码技术栈: 项目架构:B/S架构 开发语 ...

  5. Vue.js——60分钟快速入门

    Vue.js是当下很火的一个JavaScript MVVM库,它是以数据驱动和组件化的思想构建的.相比于Angular.js,Vue.js提供了更加简洁.更易于理解的API,使得我们能够快速地上手并使 ...

  6. Vue.js—60分钟快速入门

    Vue.js介绍 Vue.js是当下很火的一个JavaScript MVVM库,它是以数据驱动和组件化的思想构建的.相比于Angular.js,Vue.js提供了更加简洁.更易于理解的API,使得我们 ...

  7. Vue.js基于Springboot的校园新闻发布网站-java毕业设计成品源码

    一.源码描述   这是一款前后端分离的Springboot和vue源码,前端vue,采用javaweb,基于B/S模式,idea或者eclipse为开发工具,,功能也比较全面,比较适合 作为毕业设计使 ...

  8. springboot vue电影购票选座网站源码

    开发环境及工具: 大于Jdk1.8,大于mysql5.5,nodejs,idea(eclipse),vscode(webstorm) 技术说明: Springboot mybatis html vue ...

  9. 电影购票APP快速搭建(平台开发)

    电影购票APP开发,电影购票APP开发搭建,电影购票APP开发平台.伴随着我们生活水平不断提升,当然期待根据各种各样主题活动来发展见识,看电视剧则是非常好的选择,由此可见电影购票APP开发设计也是给大 ...

最新文章

  1. 土壤学报:张福锁院士等提出根际生命共同体新概念
  2. 状态同步与帧同步的简介
  3. 我的世java途径错误_我的世界JAVA路径错误的解决方法分享
  4. 超好用的免费文献管理软件Mendeley 简易入门教程
  5. c++STL之vector简易使用
  6. 记录一次bug解决过程:eclipse Installed JREs 配置引出的问题
  7. Google File System设计方面的问题汇总
  8. PS基础学习 2---图层蒙版
  9. struts国际化java_Struts2 的国际化实现方式示例
  10. 判断二进制半整数_牛客网
  11. 武汉科技大学ACM:1006: 我是老大
  12. 关于Excel的几点高级应用
  13. 多频子量子计算机,量子计算机研究:纠错和容错计算
  14. Django/Python发送HTML邮件 (包含图片)
  15. power bi报表html,数据可视化系列:Power BI基于Web数据的报表制作(经典级示例)
  16. 怎么查看本地IP地址
  17. 玩纸牌游戏计算机教案,小班数学活动好玩的扑克牌教案
  18. 【iOS教程】SideLoadly自签名IPA 教程
  19. iphone转通用,xib里面的view怎么改成ipad大小?
  20. 自己实现搭建完整的物联网(IOT)系统(基于 CC3200、云服务器)

热门文章

  1. 获取字符串中每个字符出现的次数
  2. 三菱fx1n40mr001接线图_三菱FX1N-14MR-001使用说明书FX1N-14MR-001手册 - 广州凌控
  3. bk在python_python bk
  4. 计算机应用基础教材编写建议,计算机应用基础校本教材编写研究论文
  5. VLC实现简单的视频播放器——Qt
  6. 机器人香囊_Myethos 国家宝蔵 葡萄花鸟纹银香囊 1/7 拟人手办
  7. 并行处理类毕业论文文献有哪些?
  8. 毕业设计-基于BIT的双时相遥感影像变化检测(附下载链接-Python源码+毕业论文+答辩PPT+相关资料等等)
  9. 【笔记】浮动属性float的应用02——浮动图像和标题
  10. k8s搭建部署(超详细)