2018.10.15 day01
vue安装
npm install [email protected] --global
权限
vue第一个项目
下载vue基础项目模板(不包含依赖)
vue init webpack app01
安装依赖
cd app01
npm install
启动服务(webpack-server)
启动webpack-server
构建项目工程 (转换-打包)
部署
访问
http://localhost:8080
交付
npm run build
dist
index.html
static
css
img
js
font
vue核心技术点
特点
可以以模块化方式构建工程,具有完备的工具
mvvm模式使得程序员从dom操作中脱离出来
纯前端思想
m model 数据模型
v view 视图
vm viewModel 视图与数据的绑定 控制器 (框架本身提供)
全栈思想
mvc模式(JSP)
m model Java Pojo
v view JSP (servlet)
动态的在服务器端产生
c controller(编程)
控制
url toIndex
Servlet IndexServelt
查询所有栏目 m
查询所有文章 m
跳转JSP
index.jsp
http://localhost:8888/app01/toIndex
名称
vue-Router vue核心下的一个重要插件,实现虚拟路由的功能(页面局部刷新)
es-lint 代码格式约束
unit
介绍
src
node_modules
index.html
package.json
.vue vue的模块 (html+css+js)
html代码,直接子元素只能有一个
Vue-loader
vue转换器
vue对象实例化
new Vue({
el:’’,
data(){
},
components:{}
})
el属性表示vue实例绑定到哪个dom中,只能在使用new关键字创建Vue实例的时候应用。
data 表示vue中绑定的数据,在子模块中必须通过函数返回一个对象,这样避免变量共享。
components 表示组件注册,组件的应用包含:
1. 定义 (一个vue文件表示一个组件)
2. 引用 import Bind from ‘./comp/bind’
3. 注册
export default {
…
components:{
Bind
}
}
4. 应用
组件名作为标签名直接应用
methods 表示事件处理函数
单个值绑定
循环绑定
v-for=‘item in arr’
条件绑定
v-if=’’
v-else
双向数据绑定(表单)
事件绑定
2018.10.16 day02
Vue开发
vue init webpack app01
cd app01
npm install
npm run dev
或
npm run start
npm run build
Vue实例
var v = new Vue({
data:{
a:1,
b:2
},
methods:{
…
foo(){
this
}
bar(){
}
},
components:{},
//生命周期钩子函数
beforeMount(){
},
mounted(){
}
})
每个.vue中都有一个Vue实例
export default {
data(){
return {
}
}
}
Vue
Vue中的method中的函数,生命周期钩子函数中的this指向当前Vue实例。
vue实例可以直接访问data中定义的变量和methods中定义的函数
vue文件
一个vue文件中包含三部分
模板 html tempate
脚本 js script
样式 css style
简单的数值绑定
mvvm model – vm – view
data :{
a:‘hello’
}
mounted(){
setTimeout(()=>{
this.a = ‘world’
},1000);
}
循环渲染
data:{
users:[{
id:1,
name:‘terry’
},{
id:2,
name:‘larry’
}]
}
条件渲染
双向数据绑定
data:{
a:‘hello’
}
生命周期
绑定html
data(){ return { msg:'绑定属性
绑定事件处理函数
双大括号中表达式
data :{
user:{
id:1,
name:‘terry’,
gender:1
}
}
{{ user.gender==1?‘男’:‘女’ }}
{{ user.id+1 }}
简写
属性绑定
计算属性
{{reverseMsg}} //使用的时候当做属性来用
{
data(){
return {
msg
}
},
computed:{
reverseMsg(){ //定义的时候使用是方法
return
}
}
}
与方法区别:
1) 计算属性在使用的时候当做属性来用,而方法必须加()才能被调用
2) 计算属性多次调用,如果值没有改变,多次调用只会调用一次函数,而方法每次调用都会执行一次函数
侦听器
export default {
data(){
return {
a:1,
b:{
a:1,
b:2
}
}
},
watch:{
//1) 监听基本类型的值
b:function(now,old){
console.log(‘a值的改变:’,now,old);
}
//2) 监听对象
b:{
handler:function(now,old){
},
deep:true
}
}
}
class与style的绑定
data:{
dyClass:‘one’,
one:true,
first:false,
activeClass:‘active’,
errorClass: ‘text-danger’
}
9.1 class的绑定
1) 绑定的值为字符串
3) 绑定的值为数组
2018.10.22 day06
set数组
var arr = [];
let set = new Set(arr);
let arr2 = […set]
es6 commonjs
语法
es6
export
export default
import
commonJS
module.exports
require()
应用级别
commonJS
后台开发,node支持程度高,
不经过打包直接跑在node,一定用commonJS
webpack
webpack是运行在node上,webpack.config.js里面的模块化用的就是commonJS
module.exports {
entry:'',
output:{}
}
es6
node支持程度低
经过打包,运行在浏览器或者node,一般采用es6模块化
vue
export default {
}
vue函数调用
函数绑定
}
}
函数相互调用
增删改查
successHandler
$.get(’’,successHandler)
$.ajax({
url:’’,
data:{
},
success:successHandler,
error:erroHandler
})
异步操作 闭包
function foo(){
var a = 3;
setTimeout(function(){
console.log(a);
},1000);
for(a;a<1000;a++){
}
}
foo();
监听器
语法
data(){
return {
num:0,
parentCategory:0,
obj:{
num:0,
flag:true
}
}
},
watch:{
num:function(now,old){
},
'obj.num':{
handler:function(){
},
deep:false
},
obj :{
handler:function(){
},
deep:true
}
}
监听值
监听对象
class类
构造函数
原型
class Student{
constructor(name,age){
this.name = name;
this.age = age;
}
sayName(){
},
static foo(){
}
}
function Student(name,age){
this.name = name;
this.age = age;
}
Student.prototype.sayName(){
}
Student.foo(){}
vue生命周期
mvvm
model vm view
data:{
msg:“hello”
beforeCreate vm.msg
created vm.msg //hello
beforeMount
Promise
初始化 成功 失败
用于封装异步
new Promise((resolve,reject)=>{
resolve,
reject
});
vue
作用域插槽
vue生态
vue 核心
插件
VueRouter 路由
http://localhost:8080/index.html#/category
http://localhost:8080/index.html#/article
App.vue
Vuex 数据状态
数据状态维护
ElementUI
Bootstrap
myModal
myInfo
组件
vue-cli
index.html
作用域插槽
1. 自定义组件
let myList = {
template:,
data(){
return {
}
},
props:['data'],
componenets:{},
methods:{
foo(){
this.$emit('bar')
}
},
watch:{
},
computed:{
}
}
2. 注册
Vue.component('my-list',myList);
3. 引用
btn
2018.10.25 day09
vue开发环境搭建
vue工程
vue项目结构
app01
build webpack的配置文件目录
config 当前项目的配置信息
dist 打包后文件存储目录(交付)
index.html
static
(js css img font)
node_modules 第三方模块
src 源码目录
components
…
main.js
App.vue
index.html 首页
package.json node项目的核心配置
.babelrc babel配置文件
.gitignore git忽略文件
node_modules
src
…
Vue实例
mvvm
model vm view
.vue vue模块文件
模板
js
export default {
data(){
return {
}
},
}
css
new Vue({
el:’#app’,
data:{
msg:’’
},
methods:{
foo(){
this 指向当前Vue实例
}
},
components:{
},
beforeMount(){
},
mounted(){
this指向当前Vue实例
}
})
结论:
1. vue实例对象如何访问
1) let vm = new Vue({})
2) 可以在methods,生命周期钩子函数中定义的方法内通过this来访问
2. vue实例可以直接访问data,methods中定义的属性和方法
this.a a定义在data中
this.foo() foo定义在methods中
vue实例的生命周期
new Vue({
data:{
msg:‘hello’,
users:[]
},
create(){
this.users = data;
}
methods:{
foo(){
}
}
})
{{msg}}
数值绑定
简单绑定
{{msg}}
表达式绑定
data:{
user:{
name:‘terry’,
age:12,
gender:‘male’
}
}
性别:{{ user.gender==‘male’?‘男’:‘女’ }}
年龄:{{ user.age+1 }}
html绑定
data:{
a:“
属性绑定
data:{
b:‘this is b’
}
事件绑定
methods:{
foo(){
}
}
指令简写
v-bind:title
=>
:title
v-on:click
=>
@click
计算属性
用于将data中的值计算后输入,表达式渲染也可以完成该功能,但是,如果计算过程比较复杂,表达式将难以维护;方法也可以完成该功能,但是方法的效率低于计算属性
data:{
msg:‘hello’
}
methods:{
reverseMsg(){
return this.msg.split(’’).reverse().join(’’)
}
},
computed:{
reverseM(){
return this.msg.split(’’).reverse().join(’’)
}
}
{{ msg.split(’’).reverse().join(’’) }}
{{ reverseMsg() }}
{{ reverseM }}
数值监听
基本值监听
watch:{
num:function(now,old){
now 改变后的值
old 改变前的值
}
}
引用数值监听
watch:{
queryObj:{
handler:function(now,old){
},
deep:true //深度监听
}
}
class与style的绑定
v-bind增强使用
绑定一个字符串
绑定一个对象
data:{ obj :{ first:true, two:false } }绑定一个数组
data:{ a:first, b:two }条件渲染
...什么情况下使用v-if,什么情况下使用v-show?
在频繁切换dom显示与隐藏状态的时候使用v-show
列表渲染
事件处理
@mousedown.left
表单输入绑定
data {
user:{
name:’’
}
}
单行文本框
多行文本框
富文本编辑器替换
复选框
v-model修饰符
.number
.trim
组件基础
定义全局组件
Vue.component(组件名称,参数对象)
例如:
Vue.component(‘my-info’,{
template:
,
data(){
return {
info:"警告! "
}
},
methods:{
foo(){
alert(this.info);
}
}
});
引用
局部注册
var myInfo = {
template:``,
data(){
return {}
},
methods:{},
components:{ “my-alert”:myAlert}
}
var userComponent = {
template:
,
data(){},
methods:{},
components:{“my-info”:myInfo}
}
new Vue({
el:’’,
components:{
“user-component”:userComponenet
}
});
父组件向子组件传递数据
在子组件中的props属性中定义期望父组件传递给子组件的属性
props的取值为数组
props:[“color”,“msg”]
props的取值为对象,属性名为期望接受的属性,值为数据类型
props:{
msg:String,
color:String,
num:Number
},
如果想要为子组件传递Number类型,Boolean的值,Array类型的值,Object类型的值 那么需要使用动态传值(v-bind:num 或 :num) ,默认静态传值传递的是String类型,即使你直接传递的是数组或者布尔类型,也会被默认转换为String
let myInfo = {
props:[“num”]
}
num接收到Number类型1
为子组件一次性传递多个值
data:{
prop:{
msg:‘two’,
color:‘teal’,
num:2
}
}
等价于>
props传递值是单向的数据流,也就是说父组件如果改变了传递的值,子组件会跟着改变。子组价不能改变props中的值
子组件在有的时候可能不希望直接应用父组件通过props传递过来的值。
let myInfo = {
template:`
`,
props:["num"], //父组件没有传递num,如果直接使用num,可能会出现问题,但是子组件又不能直接改变num的值,这时候可以通过计算属性,重新计算出一个值来
computed:{
number:function(){
return this.num?this.num:1;
}
}
}
自定义事件
子组件事件触发的时候要通知父组件
子组件
var myBtn = {
template:,
computed:{
btnName(){
return this.name?this.name : “按钮”
}
},
props:[“name”],
methods:{
foo(){
// 子组件向父组件发射事件
this.$emit(‘bar’)
}
}
}
父组件
new Vue({
data:{
num:0
}
methods:{
handle(){
this.num++;
}
}
})
插槽
当调用子组件的时候,在模块中可以通过标签来调用。如果向标签内部添加内容,子组件默认不接受,如果想要让标签内的内容显示在子组件中,子组件需要提供一个slot标签来接受父组件传递过来的内容。
默认插槽
var myInfo = {
template:
}
具名插槽(用于多个插槽)
var myInfo = {
template:
}
作用域插槽
element-ui应用
axios
vue
elementui
vueRouter
vuex
axios (ajax封装库)
Ajax
原生Ajax
Http协议 (B/S架构)
浏览器 服务器
http://120.78.164.247:8099/manager/user/findAllUser
var user = {
name:‘terry’,
gender:‘male’
}
序列化 对象-> 具有特殊格式字符串
1) 表单格式 查询字符串
key=val&key=val
2) json
‘{“name”:“terry”,“gender”:“male”}’
3) 二进制格式
文件上传
请求方(浏览器)
请求报文
请求行
GET /manager/user/findAllUser
请求头
HOST http://120.78.164.247:8099
Accept text/html;application/json
Content-Type application/x-www-form-urlencoded
…
user agent 苹果电脑火狐浏览器
user agent 苹果手机safari浏览器
请求体
name=terry&gender=male
响应方
响应报文
响应行(状态行)
200 OK
响应头
Content-Type application/json
Content-Length 199kb
…
响应体
‘[{},{}]’
XMLHttpRequest
创建一个xhr对象
let xhr = new XMLHttpRequest();
打开一个连接
xhr.open(method,url);
设置请求头信息
xhr.setRequestHeader(‘Content-Type’,‘application/json’);
发送请求
xhr.send(data);
// data的类型取决于我们设置的Content-Type,如果content-Type为json,data一定要序列化为json字符串。如果content-type为x-www-form-urlencoded的时候,data一定序列化为查询字符串
监听响应
xhr.onreadystatechange = function(){
if(this.readyState == 4){
if(this.status == 200){
}
}
}
200 请求成功
404 请求失败,找不到请求资源
500 请求失败,后台代码异常
403 请求失败,权限被拒绝
请求类型
同步请求
在浏览器地址栏中输入一个地址,点击回车
特点:造成页面全部刷新。请求数据会直接显示到浏览器页面上
异步请求
ajax发送一个请求
特点:局部刷新页面。请求数据无法直接显示到浏览器页面上,而是要通过js获取
ids:[1,2,3]
查询字符串
ids[]=1&ids[]=2&ids[]=3
ids[0]=1&ids[1]=2&ids[2]=3 struts2
ids=1&ids=2&ids=3 springmvc
options=[{title:‘one’,code:1},{title:‘two’,code:2}]
options[0].title=one
options[0].code=1
options[1].title=two
options[1].code=2
jQuery ajax
特点:
ajax仅属于jquery中一部分;
回调函数机制;
依赖XMLHttpRequest,所以只能运行在浏览器中
自动将data数据转换为查询字符串
$.ajax({
url:’’, 请求地址
method:‘get’, 请求方式 get/post
data:’’, 提交数据 post,如果data为对象,该对象在发送到服务器之前会先被自动转换为查询字符串(由于contentType默认为x-www-form-urlencoded)。可以通过processData选项来阻止这样的默认转换行为
dataType:'', 期望接受的数据类型
async:true 异步
contentType:'application/x-www-form-urlencoded'
application/x-www-form-urlencoded
查询字符串 key=val&k2=v2,如果value中有特殊字符,特殊字符使用十六进制表示,比如空格,中文
multipart/form-data
二进制
text/plain
普通字符串
=============
application/json 。 post(),在发送post请求之前先会发送一个options请求。
processData:true,
beforeSend:function(){}, 在调用send方法之前
success:function(){}, 成功
error:function(){}, 失败
complete:function(){} 完成
})
有如下数据,以json格式发送到服务器端
var user = {
name:‘terry’,
gender:‘male’
}
$.ajax({
url:"",
method:“post”,
data:JSON.stringify(user),
contentType:‘application/json?charset=UTF-8’,
processData:false
})
有如下数据,以查询字符串格式发送到服务器端
var user = {
name:‘terry’,
gender:‘male’
}
$.ajax({
url:"",
method:“post”,
data:user,
})
$.ajaxSetup({})
$.ajax({})
$.get()
$.getJSON()
$.post()
GET / POST / DELETE / PUT (REST架构)
GET 查询
POST 添加
DELETE删除
PUT 修改
异步文件上传
post
contentType:‘multipart/form-data’,
processData:false,
…
axios
特点:
纯粹ajax库;
应用了promise机制;
可以直接运行在node环境下,也可以运行在浏览器下;
自动将data数据转换为JSON
底层API
axios({
baseURL:‘http://120.78.164.247:9999’
url:’/user/findAll’
method:‘get’
data:{}, //post
params:{}, //get
headers:{
‘Content-Type’:‘application/json’
}
transformRequest:[function(data,headers){
return qs.stringify(data);
}],
paramsSerializer:function(params){
return qs.stringify(params);
}
})
通过id删除一个用户信息,get方式传递id
axios({
url:’’,
method:‘get’,
params:{
id:1
},
paramsSerializer:function(params){
return qs.stringify(params);
}
})
保存用户信息,data格式json
axios({
url:’’,
method:“post”,
data:user
})
保存用户信息,data格式查询字符串
axios({
url:’’,
method:“post”,
data:user,
headers:{
‘Content-Type’:‘application/x-www-form-urlencoded’
},
transformRequest:[function(data,headers){
return qs.stringify(data);
}]
})
{
name:‘js’,
options:[{
id:1,
name:‘String’
},{
id:2,
name:‘Number’
}]
}
name=js&options[0].id=1&options[0].name=String
快捷API
axios.get()
axios.post()
18.VueRouter
1) 核心
路由表定义
路由地址切换
组件显示
路由
localhost:8080/index.html#/
路由地址 - 模块
/ Index.vue
/category Category.vue
/article Article.vue
/user User.vue
2) VueRouter
1. 安装
> npm install vue-router --save
2. 配置
1) 创建路由表
src/router/index.js
import Vue from 'vue';
import VueRouter from 'vue-router'
import HelloWorld from '@/pages/HelloWorld'
Vue.use(VueRouter);
export default new VueRouter({
routes:[{
path: '/',
component: HelloWorld
},{
}]
});
2) 在main.js
将路由表注册到根vue实例
import router from '@/router'
new Vue({
el:'',
router,
})
3. 应用
1) 改变路由地址
http://localhost:8080/index.html#/category
article
2) 组件渲染位置
3) 动态路由匹配
new VueRouter({
routes:[{
path:'/article/:id',
component:Article
}]
})
/article/1 id为1的用户界面
/article/2 id为2的用户界面
...
/article/300 id为2的用户界面
this.$route.params
http://39.108.81.60:80/#/article/23
http://39.108.81.60:80/#/article/29
http://39.108.81.60:80
如果改变动态路由中的参数,组件不会重新加载,也就说很多生命周期钩子函数只会执行一次(created,mounted),要想监控这种改变,可以通过watch来监听$route
4) 嵌套路由
new VueRouter({
routes:[{
path:'/category',
component:'Category',
children:[{
path:'check',
component:'CategoryCheck',
}]
}]
})
栏目管理
category.vue
栏目审核 check.vue 栏目预览
用户管理
文章管理
app.vue
栏目审核 栏目预览
check.vue
/category
/category/check
技术选型
vue + bootstrap + jquery +fontawesome
全局样式,组件,插件 bs支持,ajax
如何应用bs,jquery
1) npm install xxx
2) script
vue + elementui
本周作业
使用 vue+bs3+jquery+fontawesome+lodash完成看点咨询
代码规范
src
components
MyModal.vue
pages
Category.vue
增
表单验证(正则表达式)
删
先询问再删除
改
修改与添加的模态框为同一个
查
列表 (bs table)
Article.vue
User.vue
App.vue
分别引入pages中的页面
main.js
全局组件注册
组件定义
组件注册
全局
局部
父组件传值给子组件 (子组件中定义props)
子组件传事件给父组件(子组件事件处理函数$.emit())
2018.10.26
Vuex
技术栈
Vue + VueRouter + Vuex(中大型项目)
elementui axios qs lodash font-awesome animte.css
VueRouter
1. 作用
vue路由机制(虚拟路由)
后台(路由地址->方法(数据库操作))
/manager/category/findAllCategory
class CategoryController{
findAllCategory(){
从数据库中查询所有栏目信息
}
}
前台(路由地址 -> 组件(页面布局更新))
/category
Category.vue
2. vueRouter应用
1) 安装
> npm install vue-router --save
2) 配置
1. 路由表
src/router/index.js
import Router from 'vue-router';
import Vue from 'vue'
import ...
Vue.use(Router);
export default new Router({
routes:[{
path:'/',
component:Hello
},{
path:'/category',
component:Category
}]
})
2. 集成vue中
src/main.js
import router from '@/router'
new Vue({
el:'',
router,
components:'App'
});
3. 应用
http://localhost:8080/#/
http://localhost:8080/#/category
4. 路由改变方式
1) 直接修改浏览器地址栏 (程序员测试)
2)
3)
4) 导航?
1. 自己编写导航代码(router-link / $router)
2. 组件库
3. 动态路由
new Router({
routes:[{
path:'article/:id',
component:Article
}]
})
/article/1
/article/2
...
/article/1000
1) 如何在Article中获取id
1. $route (过度依赖底层API)
this.$route.params
this.$route.path
this.msg
{{$route.params.id}}
{{msg}}
2. 通过props获取参数
new Router({
routes:[{
path:'/article/:id',
component:Article,
props:true
}]
})
动态传值:
静态传值:
{{$route.params.id}}
{{id}}
4) 嵌套路由
new Router({
routes:[{
path:'/exam',
component:Exam
children:[{
path:'create',
component:ExamCreate
},{
path:'place',
component:ExamPlace
}]
}]
})
App.vue
router-view
/exam
Exam
导航
router-view
/exam/create
导航
ExamCreate
/exam/place
导航
ExamPlace
5) 命名视图
path:'/person'
components:{
a:Nan,
b:Nv
}
path:'/dog'
components:{
a:Gong,
b:Mv
}
6) 命名路由
new Router({
routes:[{
path:'/exam',
component:Exam
children:[{
path:'create',
name:'createExam',
component:ExamCreate
},{
path:'place',
name:'examPlace'
component:ExamPlace
}]
}]
})
this.$router.push('/exam/create')
this.$router.push({
name:examPlace
})
this.$router.push({
path:'/exam/create'
})
7) 重定向
new Router({
path:'/',
redirect:{name:'examPlace'}
},{
path:'/',
redirect:'/a'
})
当路由为/,重定向到命名为examPlace的路由中
path
component
name
props
children
components
redirect
alias
8) history模式
http://localhost:80/#/article/1
http://localhost:80/article/1
www
cms
index.html
static
http://39.108.81.60:80/cms/index.html#/article/1
http://39.108.81.60:80
进入到apache的部署目录 www
/ - www
/cms - www/cms
/cms/index.html - www/cms/index.html
http://39.108.81.60:80/cms/index.html1/article/
404
图片服务器
8888 nginx
节点1 节点2 节点3
group1 group1 group1
后台服务部署阿里云
完成看点咨询精选后台(企业网站服务器)
vue+vueRouter+elementui+axios+qs(vue-cli)
完成看点咨询精选前台(企业网站前台)
vue+vueRouter
index.html
css
images
js
将代码打包部署到阿里云
www
cms
fhauwphfawuehfap
http://ip:80/cms
http://ip:80/fhauwphfawuehfap 权限
答辩(介绍)
2018.10.30
看点资讯后台
主要用于维护资讯相关信息(栏目支持二级栏目,文章管理,用户管理)
vue-cli (vue脚手架)
vue (基础框架)
vueRouter (路由管理)
axios (ajax数据交互)
element-ui (组件)
font-awesome (图标)
看点咨询前台
主要用于显示资讯相关信息
不使用vue-cli来做(大材小用)
vue
axios
font-awesome
也可以使用bootstrap
列表页面(首页)如果列表样式发生变化就需要使用路由。就要使用脚手架。反之使用页面跳转方法。
内容页面 (文章详情显示)