什么是服务器端渲染 (SSR)?

Vue.js 是构建客户端应用程序的框架。默认情况下,可以在浏览器中输出 Vue 组件,进行生成 DOM 和操作 DOM。然而,也可以将同一个组件渲染为服务器端的 HTML 字符串,将它们直接发送到浏览器,最后将这些静态标记"激活"为客户端上完全可交互的应用程序。

服务器渲染的 Vue.js 应用程序也可以被认为是"同构"或"通用",因为应用程序的大部分代码都可以在服务器和客户端上运行。

为什么使用服务器端渲染 (SSR)?

  • 与传统 SPA (单页应用程序 (Single-Page Application)) 相比,服务器端渲染 (SSR) 的优势主要在于:

    • 更好的SEO,由于搜索引擎爬虫抓取工具可以直接查看完全渲染的页面
      请注意,截至目前,Google 和 Bing 可以很好对同步 JavaScript 应用程序进行索引。在这里,同步是关键。如果你的应用程序初始展示 loading 菊花图,然后通过 Ajax 获取内容,抓取工具并不会等待异步完成后再行抓取页面内容。也就是说,如果 SEO 对你的站点至关重要,而你的页面又是异步获取内容,则你可能需要服务器端渲染(SSR)解决此问题。
    • 更快的内容到达时间 (time-to-content),特别是对于缓慢的网络情况或运行缓慢的设备。无需等待所有的 JavaScript 都完成下载并执行,才显示服务器渲染的标记,所以你的用户将会更快速地看到完整渲染的页面。通常可以产生更好的用户体验,并且对于那些「内容到达时间(time-to-content) 与转化率直接相关」的应用程序而言,服务器端渲染 (SSR) 至关重要。
  • 使用服务器端渲染 (SSR) 时还需要有一些权衡之处:
    • 开发条件所限浏览器特定的代码,只能在局限于某些生命周期钩子函数(beforeCreate&&created(lifecycle hook) 中使用;一些外部扩展库 (external library) 可能需要特殊处理,才能在服务器渲染应用程序中运行。
    • 涉及构建设置和部署的更多要求。与可以部署在任何静态文件服务器上的完全静态单页面应用程序 (SPA) 不同,服务器渲染应用程序,需要处于 Node.js server 运行环境
    • 更多的服务器端负载。在 Node.js 中渲染完整的应用程序,显然会比仅仅提供静态文件的 server 更加大量占用 CPU 资源 (CPU-intensive - CPU 密集),因此如果你预料在高流量环境 (high traffic) 下使用,请准备相应的服务器负载,并明智地采用缓存策略
  • 在对你的应用程序使用服务器端渲染 (SSR) 之前,你应该问的第一个问题是,是否真的需要它。这主要取决于内容到达时间 (time-to-content) 对应用程序的重要程度。例如,如果你正在构建一个内部仪表盘,初始加载时的额外几百毫秒并不重要,这种情况下去使用服务器端渲染 (SSR) 将是一个小题大作之举。然而,内容到达时间 (time-to-content) 要求是绝对关键的指标,在这种情况下,服务器端渲染 (SSR) 可以帮助你实现最佳的初始加载性能。

nuxt.js

https://www.nuxtjs.cn/
https://zh.nuxtjs.org/docs/

  • 创建项目:npm create-nuxt-app 项目名
  • 在集成的服务器端框架之间进行选择:
    None (Nuxt 默认服务器)
    Express
    Koa
    Hapi
    Feathers
    Micro
    Fastify
    Adonis (WIP)
  • 选择您喜欢的 UI 框架:
    None (无)
    Bootstrap
    Vuetify
    Bulma
    Tailwind
    Element UI
    Ant Design Vue
    Buefy
    iView
    Tachyons
  • 选择您喜欢的测试框架:
    None (随意添加一个)
    Jest
    AVA
  • 选择你想要的 Nuxt 模式 (Universal or SPA)
  • 添加 axios module 以轻松地将 HTTP 请求发送到您的应用程序中。
  • 添加 EsLint 以在保存时代码规范和错误检查您的代码。
  • 添加 Prettier 以在保存时格式化/美化您的代码。
  • 运行:cd 文件夹
  • npm run dev
数据请求和 跨域问题
  • 使用原版 axiox,也可以使用 this.$axios
  • 跨域:nuxt.config.js
 axios: {proxy: true},proxy:{"/api":{target:"http://localhost:3000"}},
  • 视图出口:<Nuxt />
  • 插件plugins
  • plugins文件夹下定义插件
*domian.js
import Vue from "vue"
Vue.prototype.$domian = "http://localhost:3000"*element-ui.js
import Vue from 'vue'
import Element from 'element-ui'
import locale from 'element-ui/lib/locale/lang/en'
Vue.use(Element, { locale })*guard.js
// app 应用实例
export default(({app})=>{// 定义全局守卫app.router.beforeEach((to,from,next)=>{// console.log(to,from);next()})
})*mint-ui.js
import Vue from 'vue'
import MintUI from 'mint-ui'
import 'mint-ui/lib/style.css'
Vue.use(MintUI)
  • nuxt.config.js注册插件配置
  plugins: ['@/plugins/element-ui','@/plugins/mint-ui',"@/plugins/guard.js","@/plugins/domain.js",],
  • 状态管理(vuex)
  • store/index.js
export const state = () => ({counter: 0
})export const mutations = {increment(state) {state.counter++}
}
  • store/todo.js
export const state = () => ({msg: "hi"
})
  • 组件内
  import {mapState,mapMutations} from "vuex"computed:{...mapState(["counter"]),msg(){console.log(this.$store)return this.$store.state.todo.msg;}},
  • 组件中asyncData()是设置服务器端渲染的数据的方法:

    • 异步的数据:服务器端会执行的函数
    • 没有this
   // context: 组件实例async asyncData(context) {// console.log(context)// console.log(context.app)// console.log(this); //没有this// console.log(context.$axios)//  通过context 获取axioslet res = await context.$axios.get("/api/getbanner");console.log(res);// 返回一个对象,服务器端渲染使用的数据源return { name: "World",list:res.data.list};},
  • 路由:定义一个组件就是定义了一个一级路由,嵌套路由(创建一个同名的文件夹,其下的路由就为当前路由的子路由)
  • 导航:<nuxt-link to="/">首页</nuxt-link>(声明式路由写法)
  • 子路由视图出口:<nuxt-child></nuxt-child>
  • 动态路由:新建一个_参数名.vue的文件(_传参,获取:<p>{{$route.params.id}}</p>

腾讯云开发者手册

https://cloud.tencent.com/developer/devdocs

vant-ui

https://vant-contrib.gitee.io/vant/#/zh-CN/col

mint-ui

https://www.w3cschool.cn/mintui/

typeScript和项目升级

https://www.tslang.cn/docs/home.html

// 定义变量声明数据类型
let a:number = 1;
const b:string = "1";
let c:boolean;
c = true;
// a = "hello"; //报错
let und:undefined =undefined;
let nul:null = null;
// 定义数组
let arr1:number[] =[1,2,3];//number 值构成的数组
let arr2:Array<string> = ["a","c"];//字符串构成的数组
// 元组: 定义数组成员的个数和类型
let arr3:[number,string] = [1,"a"];//
let d:number|string ="1";// 可以是字符串或者是number ,使用管道符隔开
let arr4:[number,string|number] = [1,2];//
//any 可以是任意数据类型
let arr5:any[] = [1,"c"];
// 对象
let obj:object ={a:1};
// 枚举:给数字取名,默认第一项是0,数值递增
enum colors{red,blue,green}
// let color = colors.red;
// console.log(color);
// console.log(colors[0]);
enum colors1{red=100,blue,green}
let color1 = colors1.red;
console.log(color1);
console.log(colors1[102]);

ts javascript的超集:

什么是TypeScript

TypeScript 是 JavaScript 的一个超集,主要提供了类型系统对 ES6 的支持,它由 Microsoft 开发,代码开源于 GitHub 上。

TypeScript 是 JavaScript 的类型的超集,它可以编译成纯 JavaScript。编译出来的 JavaScript 可以运行在任何浏览器上。TypeScript 编译工具可以运行在任何服务器和任何系统上。TypeScript 是开源的。

为什么选择TypeScript

TypeScript 增加了代码的可读性和可维护性

  • 类型系统实际上是最好的文档,大部分的函数看看类型的定义就可以知道如何使用了
  • 可以在编译阶段就发现大部分错误,这总比在运行时候出错好
  • 增强了编辑器和 IDE 的功能,包括代码补全、接口提示、跳转到定义、重构等

TypeScript 非常包容

  • TypeScript 是 JavaScript 的超集,.js 文件可以直接重命名为 .ts 即可
  • 即使不显式的定义类型,也能够自动做出[类型推论]()
  • 可以定义从简单到复杂的几乎一切类型
  • 即使 TypeScript 编译报错,也可以生成 JavaScript 文件
  • 兼容第三方库,即使第三方库不是用 TypeScript 写的,也可以编写单独的类型文件供 TypeScript 读取

TypeScript 拥有活跃的社区

  • 大部分第三方库都有提供给 TypeScript 的类型定义文件
  • Google 开发的 Angular2 就是使用 TypeScript 编写的
  • TypeScript 拥抱了 ES6 规范,也支持部分 ESNext 草案的规范

TypeScript 的缺点

任何事物都是有两面性的,我认为 TypeScript 的弊端在于:

  • 有一定的学习成本,需要理解接口(Interfaces)、泛型(Generics)、类(Classes)、枚举类型(Enums)等前端工程师可能不是很熟悉的概念
  • 短期可能会增加一些开发成本,毕竟要多写一些类型的定义,不过对于一个需要长期维护的项目,TypeScript 能够减少其维护成本
  • 集成到构建流程需要一些工作量
  • 可能和一些库结合的不是很完美

安装 TypeScript

TypeScript 的命令行工具安装方法如下:

npm install -g typescript

以上命令会在全局环境下安装 tsc 命令,安装完成之后,我们就可以在任何地方执行 tsc 命令了。

tsc -v 查看版本

用 TypeScript 编写 React 时,以 .tsx 为后缀。

编辑器

TypeScript 最大的优势便是增强了编辑器和 IDE 的功能,包括代码补全、接口提示、跳转到定义、重构等。

主流的编辑器都支持 TypeScript,推荐使用Visual Studio Code。

  • 新建文件架:tsconfig.json 以及一些ts 文件
  • 或者执行 :tsc --init
  • tsconfig.json
 {// 编译配置项"compilerOptions": {"allowJs":true,"outDir":"dist","target":"ES6",},//包含"include": ["src/**/*"],// 排除"exclude": ["node_modules","**/*.spec.ts"]    }
  • vscode->终端->运行生成任务->点击 tsc 监视 config.json
基本数据类型
  • 定义变量声明数据类型
 let a:number = 1;const b:string = "1";let c:boolean;c = true;  // a = "hello"; //报错let und:undefined =undefined;let nul:null = null;
  • 定义数组
 // let arr1:number[] =["1",2,3];//number 值构成的数组let arr2:Array<string> = ["a","c"];//字符串构成的数组// 元组: 定义数组成员的个数和类型let arr3:[number,string] = [1,"a"];//let d:number|string ="1";// 可以是字符串或者是number ,使用管道符隔开let arr4:[number,string|number] = [1,2];////any 可以是任意数据类型let arr5:any[] = [1,"c"];
  • 对象
let obj:object ={a:1};
  • 枚举:给数字取名,默认第一项是0,数值递增
 enum colors{red,blue,green}// let color = colors.red;// console.log(color);// console.log(colors[0]);enum colors1{red=100,blue,green}let color1 = colors1.red;console.log(color1);console.log(colors1[102]);
  • 函数:
 "use strict";function foo() {return "hello";}var boo = function () { }; //兼容 es6箭头函数
  • 定义参数的数据类型, 参数括号后面的部分是指定返回值的数据类型
 // 不返回数据可以指定 void 类型或者是anyvar baz = function (a, b) {// return a + b+"";return a + b;};// console.log(baz(1,2))baz(3, 1);var baz1 = function (a, b) {console.log(a + b);};
  • 设定默认值
 var baz2 = function (a, b) {if (a === void 0) { a = 2; }if (b === void 0) { b = 3; }console.log(a + b);};baz2();baz2(1, 100);
  • 参数后面? 代表这是一个可选参数,可以传实参也可以不传
 var baz3 = function (a, b) {if (b) {console.log(a + b);}else {console.log(a);}};baz3(1, 11);baz3(13);
  • 类型推断,完整写法
 var baz4 = function (a, b) {if (b) {console.log(a + b);}else {console.log(a);}};
  • 类型断言, 变量 as 类型
 function baz5(n) {// console.log(n.length)if (n.length) {console.log(n);}else if (n) {console.log(1 + n);}}baz5(1);baz5("1");
  • …后面代表剩余参数,后面所有参数
 function baz6(a) {var b = [];for (var _i = 1; _i < arguments.length; _i++) {b[_i - 1] = arguments[_i];}console.log(b);}baz6(1, 3, 5, 7);
  • 接口和类:
 // stu 是一个对象:interface 接口interface stu{name:string;age:number;sex?:string;}let s:stu = {name:"jack",age:18,sex:"male"}let s1:stu = {name:"makc",age:19,}
  • 函数接口
 interface fo{(a:number,b:number):number;}let foo3:fo = function name(a:number,b:number):number {return a+b;}
 class Greeter {greeting: string;//定义类的属性constructor(message: string) {this.greeting = message;}greet() {return "Hello, " + this.greeting;}} let greeter = new Greeter("world");
  • 继承
 class Animal {// public:当前类,子类,类的外部,默认// protected :当前类,子类// private:当前类 // static: 通过类来访问public legNum:number;static moveable = true;protected cry = true;private age:number[] = [1,500000];constructor(legs:number){// console.log(this.moveable);// console.log(this.cry)console.log(this.age)this.legNum = legs;}// 函数的参数定义数据类型 以及默认值move(distanceInMeters: number = 0) {console.log(this.legNum);console.log(`Animal moved ${distanceInMeters}m.`);}}console.log(Animal.moveable)class Dog extends Animal {constructor(legs:number){super(legs);console.log(this.cry)// console.log(this.age)}bark() {console.log(this.legNum)console.log('Woof! Woof!');}}const dog = new Dog(4);console.log(dog.legNum)// console.log(dog.cry)dog.bark();dog.move(10);dog.bark();

装饰器

  • 装饰器是一种特殊类型的声明,它能够被附加到类声明,方法, 访问符,属性或参数上。 装饰器使用 @expression这种形式,expression求值后必须为一个函数,它会在运行时被调用,被装饰的声明信息做为参数传入。
  • 普通装饰器
// 可以视为是一个装饰器
function log(params:any){console.log(params); //构造函数params.prototype.msg = "hello web"
}
//  使用装饰器,开启 tsconfig.json 中的装饰器功能 :experimentalDecorators
// //  @ log函数作为 装饰器使用
@log
class Web1{}
@log
class Java1{}
let web0817 = new Web1()
console.log(web0817)
console.log(new Java1())
  • 装饰器工厂:可以接受参数的装饰器
 // 可以视为是一个装饰器// 外部的函数负责接收参数的function logFactory(it:string){return function(params:any){console.log(params); //构造函数params.prototype.msg = "hello "+ it;} }//  @ log函数作为 装饰器使用@logFactory("web")class Web{}@logFactory("java")class Java{}let web0727 = new Web()console.log(web0727)console.log(new Java())
  • 属性装饰器
 function logpro(params:any){return function(target:any,attr:string){// target 类的原型// attr: 被装饰的属性 boo// parmas : "abc"console.log(target,attr,params)target[attr] = params;}   } class Foo{@logpro("abc")public boo:string = '123';}console.log(new Foo())

vue-cli3升级

  • 卸载旧版本 vue-cli

    • npm uninstall -g vue-cli
    • vue --verseion
  • 安装新版本
    • npm install -g @vue/cli
  • 使用2.x 的模板,安装桥接器: 安装之后 可以通过 vue init webpack 创建项目
    • npm install -g @vue/cli-init
  • 创建项目:vue create <项目名>
  • 语法
 <template><div class="home"><div>count:{{count}}--{{sqrt}}</div><button @click="increment">increment</button><HelloWorld :msg="msg" @ch="ch"/></div></template><script lang="ts">import { Component, Vue,Watch } from 'vue-property-decorator';import HelloWorld from '@/components/HelloWorld.vue'; // @ is an alias to /src@Component({components: {// 注册子组件HelloWorld,},})// 每一个组件都是一个类export default class Home extends Vue {// 定义dataprivate count:number = 10;msg:string="Welcome to Your Vue.js + TypeScript App";// methodsprivate increment(){this.count++;}// get 开头 函数就是计算属性get sqrt():number{return this.count*this.count;}mounted(){console.log("mounted")}// 监听属性,方法装饰器@Watch("count",{deep:true})foo(v1:number,v2:number):void{console.log(v1)}ch(val:string){this.msg = val;}}</script>
  • 子组件:
 <template><div class="hello"><h1>{{ msg }}</h1><!-- <button @click="fn">change msg</button> --><button @click="ch">change msg</button></div></template><script lang="ts">import { Component, Prop, Vue,Emit} from 'vue-property-decorator';@Componentexport default class HelloWorld extends Vue {// 属性装饰器接收 props@Prop() private msg!: string;// fn 函数触发时 触发ch 的自定义事件// @Emit("ch")/* fn(){// 自定义事件的事件处理函数 就是 fn 函数返回值return "new msg"} */@Emit()ch(){//  会触发名为ch 的自定义事件// 自定义事件的事件处理函数 就是 fn 函数返回值return "new msg"}}</script>

stylus

https://stylus.bootcss.com/

  • 富有表现力、动态的、健壮的css
  • 安装:npm i stylus stylus-loader@3.0.2 -D
  • style的lang属性:stylus
  • 特性:
    • stylus可以省略所有想省略的字符
    • 可以嵌套,必须使用缩进代表嵌套关系
    • 变量声明,使用 = 给变量赋值($h1=30px)
    • 进行运算,运算符需要空格,除法需要用()包裹
    • 属性可以定义为变量{ }包裹$w=width-->{$w} 500px
    • 使用@获取某个属性的值height ($h1 / 2) + @width
    • 使用&指代上一级
    • 执行函数,函数内可以使用流程控制语句if
 <style lang="stylus">      $h1 = 30px;    $w = widthadd(a, b=10px){if(b>5px){a+b}else{a}}foo(pro,val){-webkit-{pro} val-moz-{pro} val-o-{pro} val-ms-{pro} val{pro} val}#app{background:red.box{{$w} 500px// height $h1 + 20// height $h1 - 5// height $h1 * 2height ($h1 / 2) + @widthbackground gray&:hover{background yellow}.wrapper{// height add(100px,2em)height add(100px,5px)background green(#f00, 255) ;foo(border-radius,10%)for num in 1 2 3{.span{num} {font-size num * 1rem}        }/* .span1 {font-size 1 * 1rem}.span2 {font-size 2 * 1rem}.span3 {font-size 3 * 1rem} */          }}    }     </style>

vue服务器渲染/nuxt/vant-ui/mint-ui/typeScript/stylus(简单了解带网址)相关推荐

  1. Vue.js学习系列七——Vue服务器渲染Nuxt学习

    我又回来啦~这次我们来学习Vue的服务器渲染SSR. 关于SSR的文章网上很多,一开始看得我云里雾里.然后去Vue.js 服务器渲染指南和nuxt官网看了看,发现文章大多都是搬运官网的内容,真正讲的清 ...

  2. 从0带您打造企业级 Vue 服务器渲染 Nuxt.js (一) 入门

    写在开始前 公司团队技术栈一直主要使用 Vue,由于 SPA 模式开发有几大痛点,团队在2017年开始尝试 SSR(服务端渲染). 记得刚开始 Nuxt.js 还没有到1.0(坑哭了),到目前为止团队 ...

  3. 【Vue学习总结】22.使用Mint UI的infinite-scroll实现上拉分页加载

    接上篇<21.Vue-UI框架之Mint UI的使用> 上一篇我们讲解了Vue的UI框架Mint UI的使用,本篇我们来通过Mint UI提供的infinite-scroll组件结合api ...

  4. vue_SSR框架:搭好的Vue服务器渲染框架,用vue做网站开发、做seo的首选。

    前端江太公 搭好的Vue服务器渲染框架,用vue做网站开发.做seo的首选 最成熟的Vue ssr框架,一个命令就能启动和部署.零侵入开发,跟开发vue纯客户端一模一样. 体验优秀成熟的ssr框架 使 ...

  5. vue服务器渲染nuxtjs

    项目介绍 项目中使用用了vue + nuxt + axios + element-ui + vue-router(nuxt整合的),这是在学习服务器渲染框架nuxtjs过程中写的一个小demo:项目的 ...

  6. html mint ui,Mint UI 使用文档

    Mint UI 使用文档 本文将介绍 Mint UI 的安装方式和基本的用法. npm 安装 推荐使用 npm 的方式安装,它能更好地和 webpack 打包工具配合使用. npm i mint-ui ...

  7. vue服务器渲染的现成和成熟的框架和代码

    由于我们的react和vue这些框架,它生成的html代码,div的内容是空的,title这些由于他是单页应用,所以seo非常不友好. 基本用vue开发的网站就无法被百度收录,所以对于我们vue程序员 ...

  8. Vue学习计划十:了解Vue服务器渲染以及Vue-SSR使用方法

    Vue.js 是一个流行的前端框架,它提供了一些有用的功能,例如组件化.虚拟 DOM 和响应式数据绑定.然而,在某些情况下,仅仅使用客户端渲染(Client-side Rendering)可能会带来一 ...

  9. 【移动端vue ui框架学习】vue项目如何使用基于vue的UI框架mint ui

    看了下饿了么团队开发的PC端vue ui框架Element ui之后,顺便看了看同团队开发的移动端的vue ui框架mint ui,那么在vue项目中应该如何使用mint ui呢?以下做简单的记录. ...

最新文章

  1. OpenCV meanshift目标追踪
  2. python字符串换行连接_零基础学python_03_字符串(拼接+换行+制表符)
  3. Leaflet中使用leaflet.easyPrint插件实现打印效果
  4. gmail收件箱标签设置_通过多个收件箱实验室有效管理您的Gmail
  5. .NET的MVVM框架
  6. Java虚拟机(四)——类加载机制
  7. 投毒、伪装、攻击,DNS 欺骗和钓鱼网站如何一步步诱人掉入陷阱?
  8. matlab密钥生成,使用文件安装密钥安装产品
  9. syntaxhighlighter高亮动态代码
  10. 启动jar包报错: 找不到或无法加载主类
  11. 文件后缀名批量修改工具
  12. Python 编码错误的本质原因
  13. 针对于网站被黑被劫持了的解决办法、网站被劫持了怎么办
  14. CF1467B Hills And Valleys 题解
  15. BI、大数据、数字化转型傻傻分不清?5分钟带你了解区别和联系
  16. HTML+CSS大风车及十字架的实现
  17. 视觉中国图片编码_学习编码第14天的应用视觉设计第4部分
  18. 从傅里叶变换到加窗傅里叶变换
  19. 用c语言编写流水灯的思路原理,花样流水灯 单片机设课设.doc
  20. 小猿圈分享-web报表中电子印章/水印的轻松实现

热门文章

  1. R语言手动绘制分类Logistic回归模型的校准曲线(Calibration curve)(3)
  2. DBeaver 一款替代Navicat的数据库可视化工具
  3. 计算机高国家线50分调剂,这些考生注意,即使初试分数再高,超过国家线,也只能调剂读研!...
  4. 职称考试计算机需要带什么,职称计算机考试考前需要准备什么
  5. win10安装Ubuntu20.04双系统出现Turn off RST问题
  6. signature=d0108467db7c8f306f2bd7cd45de4c83,Programmable data-routing multiplexer
  7. 异步电动机的工作原理
  8. 五种主流web报表工具的功能对比
  9. 今天牛顿忌日:他留下了什么手稿 | 直播预告
  10. 关于最长公共子序列问题的空间优化