内容:项目打包部署、图表、服务器端渲染、typescript
日期:2020-09-14`
npm run build
(1)备份本地数据文件,然后在服务器上创建一个数据库,并导入已备份的数据库
(2)将接口项目上传到服务器,然后通过pm2把接口项目运行起来
(3)代理配置
把打包好的项目文件上传到服务器上,并配置域名进行解析
如果线上服务器用的是nginx,需要进行nginx代理转发配置,从而实现请求线上的接口地址。
nginx的网站配置文件中添加如下代理规则:
location ^~/uploads{
proxy_pass http://服务器域名或ip地址:端口;
}
location /api/{
proxy_pass http://服务器域名或ip地址:端口;
}
官网:https://www.highcharts.com.cn/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="http://cdn.highcharts.com.cn/highcharts/highcharts.js"></script>
</head>
<body>
<div id="container" style="width: 600px;height:400px;"></div>
<script>
// 图表配置
var options = {
chart: {
type: 'bar' //指定图表的类型,默认是折线图(line)
},
title: {
text: '我的第一个图表' // 标题
},
xAxis: {
categories: ['苹果', '香蕉', '橙子'] // x 轴分类
},
yAxis: {
title: {
text: '吃水果个数' // y 轴标题
}
},
series: [{ // 数据列
name: '小明', // 数据列名
data: [1, 0, 4] // 数据
}, {
name: '小红',
data: [5, 7, 3]
}]
};
// 图表初始化函数
var chart = Highcharts.chart('container', options);
</script>
</body>
</html>
官网:https://echarts.apache.org/
引入:https://cdn.jsdelivr.net/npm/echarts@4.9.0/dist/echarts.js
在vue中使用
安装echarts
npm i echarts --save
在页面组件中引入并使用
<template>
<div>
<div id="main" style="width: 600px;height:400px;"></div>
</div>
</template>
<script>
import echarts from "echarts";
export default {
data() {
return {
myChart: null
};
},
mounted() {
this.myChart = echarts.init(document.getElementById("main"));
var option = {
title: {
text: "本周订单数量"
},
tooltip: {},
legend: {
data: ["数量"]
},
xAxis: {
data: ["周一","周二","周三","周四","周五","周六","周日"]
},
yAxis: {},
series: [
{
name: "数量",
type: "line",
data: [5, 20, 36, 10, 66, 10, 20]
}
]
};
// 使用刚指定的配置项和数据显示图表。
this.myChart.setOption(option);
}
};
</script>
<style></style>
百度开放平台网址:http://lbsyun.baidu.com/
(1)注册成为开发者
(2)创建应用并获取秘钥
(3)在页面中使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript" src="http://api.map.baidu.com/api?v=1.0&type=webgl&ak=你的秘钥"></script>
<style type="text/css">
html {
height: 100%
}
body {
height: 100%;
margin: 0px;
padding: 0px
}
#container {
height: 100%
}
</style>
</head>
<body>
<div id="container"></div>
<script>
var map = new BMapGL.Map("container"); // 创建地图实例
var point = new BMapGL.Point(113.634821,34.736549); // 创建点坐标
map.centerAndZoom(point, 15); // 初始化地图,设置中心点坐标和地图级别
map.enableScrollWheelZoom(true); //开启鼠标滚轮缩放\
map.setMapType(BMAP_EARTH_MAP); // 设置地图类型为地球模式
</script>
</body>
</html>
Vue.js 是构建客户端应用程序的框架。默认情况下,可以在浏览器中输出 Vue 组件,进行生成 DOM 和操作 DOM。然而,也可以将同一个组件渲染为服务器端的 HTML 字符串,将它们直接发送到浏览器,最后将这些静态标记"激活"为客户端上完全可交互的应用程序。
优势:
更好的SEO优化
渲染速度快
缺陷:
开发条件受限,vue的某些生命周期钩子函数无法使用
部署和构建有要求,在node环境下运行
更多的服务器端负载
ssr本质就是将vue的语法功能延伸到服务器端,在服务器端渲染好节点内容,给客户端浏览器去编译。
创建一个文件,并进入到命令行中
(1)初始化node环境
npm init -y
(2)安装vue和ssr
npm i vue vue-server-renderer --save
(3)将vue模板内容编译成字符串
const Vue = require('Vue')
//实例化vue
const app = new Vue({
data:{
msg:'vue ssr 学习'
},
template:'<div>hello,{{ msg }}</div>'
})
//引入ssr
const renderer = require('vue-server-renderer').createRenderer();
renderer.renderToString(app,(err,html)=>{
if(err) throw err;
console.log(html)
})
(4)启动一个服务器,并展示编译后的字符串
const Vue = require('Vue')
const express = require('express')
const server = express();
//实例化vue
const app = new Vue({
data:{
msg:'vue ssr 学习'
},
template:'<div>hello,{{ msg }}</div>'
})
//引入ssr
const renderer = require('vue-server-renderer').createRenderer();
server.get('/index',(req,res)=>{
renderer.renderToString(app,(err,html)=>{
if(err) throw err;
res.end(html)
})
})
server.listen(3000,()=>{
console.log('服务器运行在3000端口....')
})
(5)结合html文件和模板语法来实现ssr
const Vue = require('Vue')
const express = require('express')
const server = express();
const fs = require('fs')
//实例化vue
const app = new Vue({
data:{
msg:'vue ssr 学习'
},
template:'<div>hello,{{ msg }}</div>'
})
//引入ssr
const renderer = require('vue-server-renderer').createRenderer({
template:fs.readFileSync('./index.html','utf-8')
});
let htmldata = {
title:'vue-ssr服务端渲染-标题'
}
server.get('/index',(req,res)=>{
renderer.renderToString(app,htmldata,(err,html)=>{
if(err) throw err;
res.end(html)
})
})
server.listen(3000,()=>{
console.log('服务器运行在3000端口....')
})
index.html内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title }}</title>
</head>
<body>
<!--vue-ssr-outlet-->
</body>
</html>
在index.html中一定要有 占位符,否则无法把内容展示在html中。
(1)安装
npm i npx -g
npm i create-nuxt-app -g
(2)初始化项目
npx create-nuxt-app 项目名称
? Project name nuxtdemo
? Project description My superior Nuxt.js project
? Author name ming
? Choose the package manager Npm
? Choose UI framework None
? Choose custom server framework None (Recommended)
? Choose Nuxt.js modules Axios
? Choose linting tools Prettier
? Choose test framework None
? Choose rendering mode
> Universal (SSR)
Choose development tools jsconfig.json (Recommended for VS Code)
(3)运行项目
npm run dev
官网:https://www.tslang.cn/
Typescript是Javascript的超集,由微软开发和开源。
通俗的理解为Javascript的一个特殊版本,其语法规范严谨,适用于开发大型项目。
(1)安装
npm i typescript -g
验证是否安装成功
tsc -v
(2)编译
①手动编译
创建一个index.ts,并在其中写一行普通的js代码
在命令行中,进入到指定的目录,执行命令tsc index.ts进行编译,在同级目录下会生成一个同名的js文件。
(2)自动编译(vscode)
生成ts配置文件
tsc --init
此时,就会在指定的目录下生成一个tsconfig.json的配置
{
"compilerOptions": {
/* 基本选项 */
"target": "es5",// 指定 ECMAScript 目标版本: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'
"module": "commonjs",// 指定使用模块: 'commonjs', 'amd', 'system', 'umd' or 'es2015'
"lib": [],// 指定要包含在编译中的库文件
"allowJs": true,//允许编译 javascript 文件
"checkJs": true,//报告javascript文件中的错误
"jsx": "preserve",//指定jsx代码的生成: 'preserve', 'react-native', or 'react'
"declaration": true,//生成相应的 '.d.ts' 文件
"sourceMap": true, //生成相应的 '.map' 文件
"outFile": "./",//将输出文件合并为一个文件
"outDir": "./",//指定输出目录
"rootDir": "./",//用来控制输出目录结构 --outDir.
"removeComments": true,//删除编译后的所有的注释
"noEmit": true,//不生成输出文件
"importHelpers": true,//从tslib导入辅助工具函数
"isolatedModules": true,//将每个文件做为单独的模块(与 'ts.transpileModule' 类似).
/* 严格的类型检查选项 */
"strict": true,//启用所有严格类型检查选项
"noImplicitAny": true,//在表达式和声明上有隐含的any类型时报错
"strictNullChecks": true,//启用严格的null检查
"noImplicitThis": true,//当this表达式值为 any 类型的时候,生成一个错误
"alwaysStrict": true,//以严格模式检查每个模块,并在每个文件里加入 'use strict'
/* 额外的检查 */
"noUnusedLocals": true,//有未使用的变量时,抛出错误
"noUnusedParameters": true,//有未使用的参数时,抛出错误
"noImplicitReturns": true,//并不是所有函数里的代码都有返回值时,抛出错误
"noFallthroughCasesInSwitch": true,//报告switch语句的fallthrough错误。
/* 模块解析选项 */
"moduleResolution": "node",//选择模块解析策略:'node' (Node.js) or 'classic' (TypeScript pre-1.6)
"baseUrl": "./",//用于解析非相对模块名称的基目录
"paths": {},//模块名到基于 baseUrl 的路径映射的列表
"rootDirs": [],//根文件夹列表,其组合内容表示项目运行时的结构内容
"typeRoots": [],//包含类型声明的文件列表
"types": [],//需要包含的类型声明文件名列表
"allowSyntheticDefaultImports": true, //允许从没有设置默认导出的模块中默认导入。
/* Source Map Options */
"sourceRoot": "./",//指定调试器应该找到 TypeScript 文件而不是源文件的位置
"mapRoot": "./",//指定调试器应该找到映射文件而不是生成文件的位置
"inlineSourceMap": true,//生成单个 soucemaps 文件,而不是将 sourcemaps 生成不同的文件
"inlineSources": true,//将代码与 sourcemaps 生成到一个文件中,要求同时设置了 --inlineSourceMap 或 --sourceMap 属性
/* 其他选项 */
"experimentalDecorators": true,//启用装饰器
"emitDecoratorMetadata": true//为装饰器提供元数据的支持
}
}
修改配置文件,“outDir”: "./"注释解开,具体目录地址可以自行设置
编写index.ts文件的内容
vscode 工具栏 > 终端 > 运行生成任务 > tsc:监视-tsconfig.json
这样,在index.ts文件,编写了内容,就会自动生成对应的js文件。
在根目录下创建一个index.html,并引入生成好的js文件
ts最大的特点就是进行严谨的数据类型验证,要求我们在声明一个变量时就定义好该变量的数据类型,且赋值的内容必须对应的数据类型保持一致。
(1)声明变量
语法格式:
var 变量名:数据类型名称;
var 变量名:数据类型名称 = 内容;
(2)数据类型
String、Number、Boolean、Function、Object、Array
在ts中定义数组
let 变量名 : Array<数组元素数据类型>;
示例代码:
// 原生js
// let arr = []
// let arr = new Array();
// ts方式
let arr : Array<String>;
// arr[0] = true;//如果给数组元素赋值了错误的数据类型,此时会出现警告
新增的数据类型:
①元组
语法格式:
let 变量名: [ 第一个元素的数据类型, 第N个元素的数据类型] = [ 元素1,元素N ]
此时元素的数据类型必须和设置好数据类型保持一致
②枚举
语法格式:
enum 变量名 { 值1,值N }
示例代码:
enum orderStatus { '已下单' = 1,'已发货','已收货' }
console.log(orderStatus.已收货)//会返回此内容在枚举中的索引位置
③any
// any 任意类型(不明确变量类型时),此时对res变量的赋值就和原生js没有区别了
let res : any;
res = 'hello'
res = 100
res = true
④void
void 一般用于函数,表示函数无返回值
⑤never
never
类型表示的是那些永不存在的值的类型。
function error(message: string): never {
throw new Error(message);
}
ts中的函数相关知识和es6有很多相同之处
(1)函数定义
在ts中,定义一个函数,需要定义函数的返回值类型,如果没有返回值则类型为void,如果函数有参数的话,需要给参数也指定数据类型
格式:
function 函数名([参数名:参数的数据类型]):函数返回值的数据类型{...}
示例代码:
function getMsg():String{
//return true;//此时函数的返回值应该是String,不能是其他类型
return 'msg';
}
(2)函数参数
ts里的每个函数参数都是必须的
①默认参数
function checkPhone(phone:Number = 111111):Boolean{
console.log(phone);
return true;
}
②可选参数
可选的参数如果没有传递,在函数中仍然用到了这个参数,则它的值是undefined
function checkLogin(username:string,password?:string):Boolean{
console.log(username)
console.log(password)
return true;
}
③剩余参数
替代传统的函数的arguments的作用
剩余参数需要是所有参数中的最后一位,不然就做不到剩余。
function getStr(str1:string,...str2:Array<any>){
console.log(str1)
console.log(str2)
}
getStr('小明',100,200,'500',888)
如果传递的参数数量比较多或者是一个对象,那么这个函数的参数校验规则就无法实现校验
接口(interface)是类中的一个很重要的概念,它是对行为的抽象,而具体如何实现需要由类(class)去实现(implements)
接口定义
interface Person{
name:String,
age:Number
}
var p1 : Person;
p1 = {
name:'小王',
age:18
}
装饰器是一种特殊的类型声明,它可以被附加类、方法、属性、参数上面,可以修改类的行为。
装饰器就是一个方法或者说是一个特殊函数,可以被注入到类、方法、属性、参数上。
装饰器分类:类装饰器、属性装饰器、方法装饰器、参数装饰器
装饰器也是es7的标准特性之一。
类装饰器是在声明类之前(紧靠类的声明处),类装饰器应用于类的构造函数,可以监视、修改或者替换类定义。
①普通装饰器
声明装饰器:
function logClass(target:any):void{
console.log(target)
target.prototype.url = 'www.baidu.com'
}
调用装饰器:
@logClass //调用装饰器
class Animal{
type:string = ''
}
在声明类之前,通过@装饰器名称来调用装饰器
②装饰器工厂(可以传递参数)
声明装饰器:
function logClass(params:any){
return function(target:any){
target.prototype.name = params;
}
}
调用装饰器:
@logClass('汗血宝马') //调用装饰器并传递参数
class Animal{
type:string = ''
}
声明装饰器
function logProperty(target:any,propertyName:string):void{
console.log(target,111111111)
console.log(propertyName,222222)
}
调用装饰器
class Animal{
@logProperty
type:string = ''
}
它可以被运用到方法的属性描述上,可以用来监视、修改、替换方法定义
运行时,需要传递三个参数
(1)对于静态类成员来说是类的构造函数,对于实例成员来说是类的原型对象
(2)成员(属性)的名字
(3)成员的属性描述
定义方法装饰器
function logAction(target:any,methodName:string,desc:any):void{
console.log(target,1111111)
console.log(methodName,22222)
console.log(desc,33333)
}
使用方法装饰器
class Animal{
type:string = ''
@logAction
run():void{
console.log('running....')
}
}
运行时会被当做函数调用,可以使用参数装饰器为类的原型增加一些元素数据,传入三个参数
(1)对于静态类成员来说是类的构造函数,对于实例成员来说是类的原型对象
(2)方法名字
(3)参数在函数参数列表中的索引
定义装饰器
function logParams(target:any,methodName:string,paramIndex:number):void{
console.log(target,111111111)
console.log(methodName,2222222)
console.log(paramIndex,33333333)
}
使用装饰器
class Animal{
type:string = ''
run(n,@logParams m:number):void{
console.log(m)
}
}
创建一个页面组件,修改script代码
<script lang="ts">//lang=ts 表示使用ts语法
//引入类装饰器Component和Vue类
import { Component,Vue } from 'vue-property-decorator'
@Component({})
export default class Home extends Vue{
}
</script>
我们在定义data、生命周期、计算属性、事件方法、数据监听、组件引入都有一定的变化
在class组件中没有了data、methods
(1)定义初始变量
export default class Home extends Vue{
str : string = "超级天王"//定义初始变量
}
(2)定义方法
export default class Home extends Vue{
str : string = "超级天王"//定义初始变量
changeStr():void{
this.str = "中原一点红"
}
}
(3)生命周期
mounted() {
console.log("组件挂载完成")
}
生命周期直接在类中以函数的方式使用即可
(4)计算属性
没有了computed,直接写在前面并带上一个get
//计算属性
get newStr(){
return '我是'+this.str;
}
新脚手架中父子组件通信,需要使用Prop装饰器
父组件:
<template>
<div class="about">
<h1>This is an about page</h1>
<!-- 使用子组件并传递数据 -->
<v-child :gift="msg"></v-child>
</div>
</template>
<script lang="ts">
import { Component,Vue } from 'vue-property-decorator'
//引入子组件
import vChild from './Child.vue';
//利用装饰器,注册子组件
@Component({
components:{
vChild
}
})
export default class About extends Vue{
msg:string = "父组件上的数据"
}
</script>
子组件:
子组件中要通过Prop装饰器来接收数据
<template>
<div class="about">
<h1>这是子组件</h1>
<p>gift:{{ gift }}</p>
</div>
</template>
<script lang="ts">
import { Component,Vue,Prop,Emit } from 'vue-property-decorator'
@Component({})
export default class Child extends Vue{
// @Prop(String) readonly gift : string | undefined
@Prop({
type:String,
required:true
})
gift : string | undefined
}
</script>
父组件:
在父组件中传递一个自定义事件
<v-child :gift="msg" @changeStr="changeMsg"></v-child>
并在父组件的类中定义对应的函数
export default class About extends Vue{
msg:string = "父组件上的数据"
changeMsg(str:string){
console.log("父组件上的函数被子组件触发了..."+str)
}
}
子组件:
在子组件中通过Emit装饰器来触发父组件的事件
<template>
<div class="about">
<h1>这是子组件</h1>
<p>gift:{{ gift }}</p>
<button @click="send">发送</button>
</div>
</template>
<script lang="ts">
import { Component,Vue,Prop,Emit } from 'vue-property-decorator'
@Component({})
export default class Child extends Vue{
// @Prop(String) readonly gift : string | undefined
@Prop({
type:String,
required:true
})
gift : string | undefined
@Emit("changeStr")//触发父组件的事件
send(){
return '子组件传递的数据';//传递数据给父组件
}
}
</script>