前言:
前端主流框架有Vue、react、angular,目前比较火因为Vue比较容易学习,运营起来比较快速;
Vue是什么呢?
是一个基于MVVM架构的,前端框架;
如果你之前已经习惯了用jQuery操作DOM,学习Vue.js时请先抛开手动操作DOM的思维,因为Vue.js是数据驱动的,你无需手动操作DOM。
它通过一些特殊的HTML语法,将DOM和数据绑定起来。一旦你创建了绑定,DOM将和数据保持同步,每当变更了数据,DOM也会相应地更新。
当然了,在使用Vue.js时,你也可以结合其他库一起使用,比如jQuery。
个人理解: HTML标签显示内容和Vue对象中的变量是一致的;
一、简单使用
步骤1 引入Vue.js文件
<head> <meta charset="UTF-8"> <title>Title</title> <script src="vue.js"></script> </head>
步骤2 创建HTML标签
步骤3 实例化Vue对象,并传参设置对象属性;
参数介绍:
el属性:该属性的值必须为 最外层HTML标签的id名称,这样绑定之后就可以在#app标签中也可以应用Vue对象的属性和指令了;
data属性:
在data中Vue中声明变量(注意只有 data属性中声明的变量在Vue中才可以使用)
步骤4、将Vue对象中声明的变量渲染到HTML标签
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="vue.js"></script> <!--1、 引入Vue.js 、--> </head> <body> <div id="app"> <!--2、创建HTML标签--> <p>{{temp1}}</p> <!-- 6、把Vue中声明的变量渲染到 HTMK标签 --> <b>{{temp2}}</b> </div> </body> <script> new Vue({ // 3、实例化1个实例化 Vue对象 el:'#app', // 传入1个为el的属性(注意:1、该属性的值必须为 最外层HTML标签的 id名称,这样绑定之后就可以在#app标签中应用Vue的属性和指令了) data:{ // 5、传入2个为data的属性,该属性保存Vue的变量 temp1:'Hello world !', // 6、在data中Vue中声明变量(注意只有 data属性中声明的变量在Vue中才可以使用) temp2:'Hel lo girl !' } }) </script> </html>
二、Vue指令介绍
除了通过{{变量名}},把Vue对象声明的变量渲染到HTML中之外,还可以通过指令的方式对DOC元素(HTML标签)赋值,或其他操作;
1、v-html="variable" 渲染标签变量
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="vue.js"></script> </head> <body> <div id="app"> <div v-html="ele1"></div> <!--渲染标签变量 --> <b></b> </div> </body> <script> new Vue({ el:'#app', data:{ ele1:'<a href="http://www.baidu.com">跳转</a>' } }) </script> </html>
2、v-text='variable ' 渲染文本字符串变量
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="vue.js"></script> </head> <body> <div id="app"> <div v-text="temp"></div> <!--渲染文本字符串 --> <b></b> </div> </body> <script> new Vue({ el:'#app', data:{ temp:'你好!' } }) </script> </html>
3、v-show 显示和隐藏(通过display来控制显示与隐藏,真实标签不会被删除)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <script src="vue.js"></script> <body> <div id="app"> <div v-show="ok">我是青年</div> <!-- 根据布尔值 显示或者隐藏渲染效果--> <div v-show="ok1">我是坏人</div> </div> </body> <script> new Vue({ el: '#app', data:{ ok:true, ok1:false } }) </script> </html>
4、v-if/else 通过判断语句控制显示与隐藏 (和v-show的区别,标签会被插入、删除)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="vue.js"></script> </head> <body> <div id="app"> <p>{{temp1?666:444 }}</p> <!--Vue支持三元表达式的形式做变量渲染 --> <p v-if="yes">yes</p> <!--Vue的变量渲染支持 if 和else判断 --> <p v-else>flase</p> </div> </body> <script> new Vue({ el:'#app', data:{ yes:true } } ) </script> </html>
5、v-for 遍历
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="vue.js"></script> </head> <body> <div id="app"> <ul> <li v-for="(item,index) in arr"> 下标:{{index}} <!-- 遍历Vue对象中声明的变量,第2个值为 item --> 数值:{{item}} <!-- 遍历Vue对象中声明的变量,第1个值为 index --> </li> </ul> <ul> <li v-for="(value,key) in obj"> {{value}} <!--遍历字典 第1个值为 字典的值和 Python正好相反 --> {{key}} <!--遍历字典 第2个值为 字典的键和 Python正好相反 --> </li> </ul> <ul> <!--Vue 遍历嵌套类型数据 --> <li v-for="item in obj2"> <!-- 注意不要加括号() --> {{item.name}} <!--对象的name--> {{item.sex}} {{item.age}} </li> </ul> </div> </body> <script> new Vue({ el: '#app', data: { arr: [11, 22, 33, 44, 55, 66], obj: {name: '小三', sex: '女', age: 18}, obj2: [{name: '小三', sex: '女', age: 18}, {name: '小四', sex: '女', age: 28}], } }) </script> </html>
6、v-bind:标签属性=‘ 变量’ Vue动态操作标签的属性
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="vue.js"></script> </head> <body> <div id="app"> <!---v-bind 操作标签的属性 --> <a v-bind:href='url' v-bind:class='cla' v-text="text" style="text-decoration: none"></a> </div> </body> <script> vm= new Vue({ el:'#app', data:{ url:"http://www.baidu.com", cla:'person', text:'百度一下', } }) setTimeout(function () { //setTimeout 设置2秒钟后修改 Vuel对象中的变量 vm.url='http://www.le.com' //如果修改了 Vuel对象中声明的变量,页面中的效果也会动态改变 vm.text='乐视一下' },2000) </script> </html>
7、v-on:click="事件(args)="事件(args)"Vue为标签绑定事件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="vue.js"></script> </head> <body> <div id="app"> <input type="button" value="点我有饭吃" v-on:click="showme(args)"> <!-- v-on:click绑定事件,支持传入参数--> <input type="button" value="点我有饭吃" @click="showme(args)"> <!-- @:click绑定事件,也支持传入参数--> </div> </body> <script> new Vue({ el:'#app', data:{ args:'不吃' }, methods:{showme:function (a) { alert(a) } } }) </script> </html>
8、v-model数据双向绑定(所见即所得)
我们在前端页面form 标签就是为了向后台提交数据,有了v-model 再也不用寻找到input标签再去获取val值了,
如果我们接收到了后台的数据,赋值给Vue变量,页面标签显示的内容也更新了,这就是v-model双向绑定的优势所在;
把视图(HTML标签显示内容)和model数据(Vue中声明的变量)进行双向绑定,通过视图可以改变数据,通过数据也可以改变视图;
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="vue.js"></script> </head> <body> <div id="myapp"> <input type="text" v-model="showtemp"> <p>{{showtemp}}</p> <p>{{showtemp}}</p> <input type="button" v-on:click="showme" value="点击我"> <!--显示层数据和model层数据一致,输入的内容改变变量自动改变;--> <select v-model="sel"> <!--select选中那个option,sel变量被赋值为那个option的value --> <option value="1" selected>111</option> <option value="2">222</option> <option value="3">333</option> </select> </div> </body> <script> new Vue({ el:'#myapp', data:{ showtemp:'', // model层数据和显示层数据一致,input标签输入的内容改变 showtemp变量内容改变; sel:'1' }, methods:{showme:function () { alert(this.sel) }} }) </script> </html> <!--MVVM框架的优势 --> <!--Vue中很大的一个特性,数据的双向绑定 优势1:我们在前端页面form 标签就是为了向后台提交数据,有了v-model 再也不用寻找到input标签再去获取val值了 优势2:如果我们把后台的数据,赋值给Vue变量,页面标签显示的内容也更新了,v-model双向绑定的优势! -->
9、Vue三元表达式的形式做变量渲染
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="vue.js"></script> </head> <body> <div id="app"> <p>{{temp1?666:444 }}</p> <!--Vue支持三元表达式的形式做变量渲染 --> </div> </body> <script> new Vue({ el:'#app', data:{ temp1:true } } ) </script> </html>
10、修改Vue data属性中的变量(页面效果动态改变)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="vue.js"></script> </head> <body> <div id="app"> <p>{{temp1}}</p> <b>{{temp2}}</b> </div> </body> <script> vm=new Vue({ el:'#app', data:{ temp1:'大大大大', temp2:'小小小小' , } }) setTimeout(function () { //setTimeout 设置2秒钟后修改 Vuel对象中的变量 vm.temp1='小小小小' //如果修改了 Vuel对象中声明的变量,页面中的效果也会动态改变 vm.temp2='大大大大' },2000) </script> </html>
11、Vue中变量支持数值运算
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <script src="vue.js"></script> <body> <div id="app"> <p>{{temp1}}</p> <p>{{temp1}}</p> <p v-text='temp0+temp1'></p> <!--Vue支持数字运算 --> </div> </body> <script> new Vue({ el: '#app', data:{ temp0:100, temp1:1 } }) </script> </html>
12、 mounted(存放 所有html加载完毕之后,立即自动执行的事件)
mounted:function () { // mounted自动加载showme 函数
this.showme()
},
13、methods(存放 事件触发后执行的函数)
methods: {
showme: function () {
var url = "./static/hotcity.json";
var self = this;
axios.get(url).then(function(respose){
self.arr = respose.data.data.hotCity;
})
}
}
三、Vue前后端数据交互(Axios)
无论使用什么前端框架和后端进行交换是不可避免的,例如jQuery使用ajax,Vue也有和后端交换的方法Axios;
1、 axios.get()
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="vue.js"></script> <script src="axios.js"></script> </head> <body> <div id="app"> <input type="button" value="点我" v-on:click="showlist"> <ul> <li v-for="item in lists"> {{item.cityCode}} {{item.cityName}} </li> </ul> </div> </body> <script> new Vue({ el:'#app', data:{ lists:[] }, methods:{showlist:function () { url='./hotcity.json'; var self = this; // 由于Vue对象,是类实例化的,所以this是局部对象不是windows对象,赋值给self; axios.get(url) .then(function (res) { self.lists=res.data.data.hotCity //self 现在是 showlist函数中的局部this; }).catch(function (error) { }) } } }) </script> </html>
axios.get(url,{params:{username:'zhanggen'} })带参数的get请求
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="vue.js"></script> <script src="axios.js"></script> </head> <body> <div id="app"> <input type="button" value="点我" v-on:click="showlist"> <ul> <li v-for="item in lists"> {{item.cityCode}} {{item.cityName}} </li> </ul> </div> </body> <script> new Vue({ el:'#app', data:{ lists:[] }, methods:{showlist:function () { url='./hotcity.json'; var self = this; // 把new创建的Vue对象this, 赋值给self变量,在回调函数中才能通过sel变量获取 Vue对象中声明的变量; axios.get(url,{params:{username:'刘德华'} }) //params:{}指get请求携带的参数 .then(function (res) { self.lists=res.data.data.hotCity //self 现在是 showlist函数中的局部this; }).catch(function (error) { }) } } }) </script> </html>
2、 axios.post()
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="axios.js"></script> <script src="vue.js"></script> </head> <body> <div id="myapp"> <p>姓名:<input type="text" v-model="username"></p> <p>密码:<input type="password" v-model="pwd"></p> <p><input type="button" value="登录" v-on:click="login" ></p> </div> </body> <script> a= new Vue({ el: '#myapp', data: { username: '', pwd: '' }, methods: { login: function () { var url='http://127.0.0.1:8000/api/' axios.post(url, { name: this.username, password: this.pwd }, { 'headers':{'Content-Type': 'application/x-www-form-urlencoded'} }).then(function (res) { alert(res) }).catch(function (error) { }) } } }) </script> </html>
Django后端接收
from django.shortcuts import render,HttpResponse
import json
def api1(request):
print(request.method)
if request.method=='POST':
obj = HttpResponse('ok')
obj['Access-Control-Allow-Origin'] = "*"
print(request.POST)
return obj
四、Vue的运行平台 node.js
1、node.js介绍
Node.js 可以用JavaScript写一个服务端的服务器,是一个基于 Chrome V8 引擎的 JavaScript 后端运行环境,Vue框架也是基于Node.js运行的;
Node.js 的包管理器 npm(类似于linux的yum),是全球最大的开源库生态系统。
类似于:
Python可以用Django创建服务端给别人提供数据、php可以在Apache创建服务端、Java可以使用Tomcat构建服务端一样;
官网:http://nodejs.cn/
Node.js的应用场景:
由于Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,适用于开发聊天工具 、电子商务等高并发app;
银角补充:websock 是http协议的弟弟,都是基于TCP协议,不同于http协议的是websock使用的长连接,并且连接需要经过握手+验证;如果想要装逼(Magic strings)
2、安装node.js平台并创建Vue项目
2.1 登录官网:
http://nodejs.cn/download/
2.2 选择适配操作系统:
2.3 检查是否安装成功:node -v
2.4 通过脚手架创建Vue项目
全局安装脚手架:npm install vue-cli -g
创建基于webpack模板的项目: D: vue init webpack myproject
进入项目安装依赖包:cd myproject npm install (该环节会比较慢)
2.5 启动项目:npm run dev 或 npm start ( 以上环节可能会报错,以项目启动成功为最终目的)
四、基于node.js平台开发Vue项目
Vue非常火的原因是可以快速开发单页面应用( 1个网站只有1个页面,通过点击这个页面的菜单加载 1个组件)
项目 目录结构介绍
1、node_models目录
存放npm下载的插件
2、src目录
项目开发目录(开发项目关注的目录)
assets目录
存放静态图片
components目录
存放网页组件,在此目录下创建新组件
router目录
index.js (为组件 设置访问路径)
app.vue (根组件 所有组件的入口)
所有组件的根组件,为所有组件设置路由 和组件关系,把所有组件整合渲染到首页;
main.js
核心文件,和项目最外层index.html默认首页是组合关系,为默认首页创建Vue对象(只能创建1个Vue对象);
4、index.html
项目最外层index.html作为1个div标签,把根组件 和所有组件中所有内容 放在index里面;
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>myproject</title> </head> <body> <div id="app"></div> <!-- built files will be auto injected --> </body> </html>
5、package.json
批量安装插件
小结:
基于node.js使用Vue创建单页面应用思路:
1、在components目录下创建组件(.vue结尾的文件)
<template> <div> 刘娟 </div> </template> <!-- export default: 对外开放1个接口,在组件中export 导出了,才能在router目录的index.js文件里 导入! name : 组件名称 data () :函数(对于组件来说 data 必须是函数) methods :写其他函数 --> <script> export default { name: 'liujuan', data () { return { msg: '我相信你是好的朋友' } } } </script> <style scoped> </style>
2、在router目录下的index.js中导入新组件, 并为组件设置访问url生成路由
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
// 导入components目录下的 zhanggen组件
import zhanggen from '@/components/zhanggen.vue'
// 为新创建的组件设置URL
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'zhanggen',
component: HelloWorld
},
{
path: '/zhanggen/',
name: 'SSD',
component: zhanggen
}
]
})
3、通过根组件 把组件和链接展示到首页(<router-link to="/">你</router-link>)
<!--App.vue是1个根组件,所有的组件都要通过根组件配置 路由和组件关系 它包含三部分 template(写html代码) script(写js代码) css(写css代码) --> <!-- <router-view/>用来建立 组件和之间的路由关系 --> <template> <div id="app"> 欢迎来到老男孩 <router-link to="/">你</router-link> <router-link to="/zhanggen/">好</router-link> <router-view/> </div> </template> <!--javescript代码 --> <script> export default { name: 'app' } </script> <!--css代码 --> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
通过package.json批量安装插件
1、以管理员身份运行cmd cd 项目目录 npm install axios(插件名称)
2、展开node_modules目录,查看安装的插件名称(插件源)
3、在package.json文件引入插件源中的插件名称
4、使用
在src目录下main.js中
import axios from 'axios' // 导入第3方插件 Vue.use(axios) // 使用插件
在组件里引入
<script>
import axios from 'axios'
</script>
在组件里使用
<script> import axios from 'axios' //引入安装好的axios插件 </script>
<script> import axios from 'axios' //引入安装好的axios插件 export default { name: 'HelloWorld', data () { return { msg: '我相信你是好的朋友', arr:[], } }, mounted: function () { // mounted自动加载showme 函数 this.showme() }, methods: { showme: function () { var url = "./static/hotcity.json" ; var self = this ; axios.get(url).then(function(respose) { self.arr = respose.data.data.hotCity; }) } } } </script>
<template> <div> this is a div elements. <ul> <li v-for="item in arr"> 姓名:{{item.name }} 年龄:{{item.age}} 性别:{{item.sex}} </li> </ul> <div> <p>姓名:<input type="text" v-model="username"> </p> <p>年龄:<input type="text" v-model="age"> </p> <p>性别:<input type="text" v-model="sex"> </p> <input type="button" value="添加" v-on:click="add"> </div> </div> </template> <!-- export default: 对外开放1个接口 name : 组件名称 data () :函数(对于组件来说 data 必须是函数) methods :写其他函数 --> <script> export default { name: 'zhenggen', data () { return { msg: '我相信你是好的朋友', arr: [], username:'', age:'', sex:'' } }, mounted: function () { this.showlist() }, methods: { showlist(){ //定义函数 showlist(){} this.arr=[ {name:"日天",age:"18",sex:'femele'}, {name:"日地",age:"12",sex:'femele'}, {name:"日空气",age:"14",sex:'femele'}, ] }, add(){ //arr.push({}) 添加元素 this.arr.push({name:this.username,age:this.age,sex:this.sex } ) } } } </script> <style scoped> ul li{ list-style-type:none; } </style>
五、知识总结
1、前后端分离:
经过对Vue的一些学习得知Vue可以通过组件构建单页面应用,并且可以通过路由在当前页做页面的跳转,还可以使用axios插件(ajax)向后获取和提交数据;
那么Django后台return的响应,再也不需要响应redirect和模板渲染了,只需要提供1个API接口(url),给前端、APP 返回json数据即可(1个APi适配多中应用),
这种前后端搭配模式叫做前后端分离;
例如
前端代码运行在node.js平台上,域名 https://www.le.com;(让客户访问)
前端启动起来之后,向后端获取数据 https://api.le.com;(给前端提供数据)
2、Vue项目
可以把node.js中的Vue项目,分为3层;
1层index.htmm包含所有组件的内容,src目录下的main.js为index.html实例化创建vue对象
2层 根组件app.vue
<template> <div id="app"> 欢迎来到老男孩 <router-link to="/">首页</router-link> <router-link to="/zhanggen/">课程</router-link> <router-link to="/liujuan/">Luffy学位</router-link> <router-view/> </div> </template> 注释: 1、<router-link to="路由中的path">首页</router-link>,最终会生成1个a标签,用户点击那个a标签; 2、用户点击哪个a标签,就在 <router-view/>中渲染哪个组件;
3层router目录下的index.js承上启下 为各组件生成访问路径,让根组件调用;
4层 components目录下创建 各个组件
3、Vue插件扩展
跟Python的pip 类似,如果在项目开发中需要使用其他插件,使用npm去网络上自动下载,下载成功后后存放在node_modeule站点包目录下,使用import导入;
4、关于JavaScript的this关键字
1.初步认识
js 函数中的 this关键字代指Window全局对象,类中的 this关键字代指 类的对象;
<script> //1、js 函数中的 this代指Window全局对象 function zhanggen() { alert(this) } zhanggen() //2、js 类中的 this代指 类的对象 function Foo() { this.name='egon' } obj= new Foo() alert(obj.name) </script>
2、进阶认识
如果函数 被对象.函数执行,那么函数中的this代指该对象本身
如果在自执行函数中 this代指 window 对象;
this可以被赋值,由于this 被赋值为 that,那么即使在自执行函数中也是 userinfo对象
<script> userinfo={ name:'alex', age:18, show:function () { //userinfo 是1个字典对象 // alert(this.age) //this是userinfo对象 var that = this; (function () { console.log(this) //window对象 console.log(that) // that 还是userinfo对象 })() } } userinfo.show() //如果函数 被对象.函数执行,那么函数中的this代指该对象本身 //如果在自执行函数中 this代指 window 对象; //this可以被赋值,由于this 被赋值为 that,那么即使在自执行函数中也是 userinfo对象 </script>