vue总结

vue已经成了前端最热门的框架之一。在项目用的就是vue框架做开发,一直没有对vue总结,现在对vue进行一下总结。

一、vue常用指令

vue中带v-xxx 都是指令
v-html: 给元素的innerHTML 赋值,当值有标签时不显示标签。
v-text:给元素当innerText赋值,当值有标签时会展示出标签
v-if:判断是否显示,如果值为false,页面会展示 作为标记,如果变成true的时候往进插值
v-else:和else作用一样
v-else-if:和else if 作用一样
v-if家族是对元素的插入和移除的操作
v-show:是对元素显示隐藏做操作

二、v-bind使用

vue中给属性赋值使用v-bind:给元素的属性赋值。
可以给元素自带的属性赋值如value class src等等
也可以给自定义属性赋值
语法:v-bind:value=‘常量 || 变量名’、v-bind:class、v-bind:src等
简写::value=‘变量名’

<h3 v-bin:class="{add:变量名}"></h3>

三、v-on 使用

vue中所有的事件都是通过v-on来绑定。
v-on:click、v-on:scroll 等所有的原生事件。
也可以操作变量。
语法:v-on:click=“事件处理函数”
简写::click=“事件处理函数”

<button :click="事件处理函数"></button>
// 或者
<button v-on:click="事件处理函数"></button>
// 操作变量
<button :click="isShow = false"></button>

事件修饰符:
原生js可以用下面来阻止事件冒泡
1.event.stopPropagation();
2.return false;
在vue中使用:click.stop=“事件函数”;可以阻止事件冒泡

原生js取消事件默认行为
event.preventDefault()
vue中可以用:click.prevent=“事件函数”.

修饰符:self capture stop prevent的使用:

<div id="demo">
    <!--第一种情况-->
    <!--<div @click="divEven" style="border:1px #188eee solid;">-->
        <!--<a href="www.baidu.com" @click="aEven">百度链接</a>-->
    <!--</div>-->
    <!--stop的使用:阻止事件冒泡的发生-->
    <!--<div @click="divEven" style="border:1px #188eee solid;">-->
        <!--<a href="www.baidu.com" @click.stop="aEven">百度链接</a>-->
    <!--</div>-->
 
    <!--prevent的使用:阻止默认事件的发生-->
    <!--<div @click="divEven" style="border:1px #188eee solid;">-->
        <!--<a href="www.baidu.com" @click.stop.prevent="aEven">百度链接</a>-->
    <!--</div>-->
 
    <!--self的使用:只有点击他本身时才去执行,点击他的子元素不去执行-->
    <!--<div @click.self="divEven" style="border:1px #188eee solid;">-->
        <!--<a href="www.baidu.com" @click.prevent="aEven">百度链接</a>-->
    <!--</div>-->
 
    <!--capture的使用:触发捕获事件()先执行大盒子的事件,起执行小盒子的事件-->
    <div @click.capture="divEven" style="border:1px #188eee solid;">
        <a href="www.baidu.com" @click.prevent="aEven">百度链接</a>
    </div>
</div>

还有很多不常用的事件修饰符。这里就不一一列举了;可以到Vue 官网事件处理查看
点击此处查看Vue 事件处理

四、v-model

用在表单元素上
v-model主要用于数据双向绑定;
页面改变影响内存(js);
内存改变影响页面(js);

v-bind和v-model的区别:
v-bind:可以给任何属性赋值,是从vue到页面的单向数据流。
v-model只给具备value的属性的元素进行双向数据绑定(必须使用的是有value属性元素);

五、v-for使用

基本语法:v-for=“item in arr”; 主要用于遍历数组和对象
对象的操作:v-for=“item in obj”;
如果有列表哟id可以不用写index,如果没有可以写成v-for="(item,index) in arr"
还有一个比较重要的一点 v-for尽量都写上:key,有id了些id,没有了写上index;
如下代码:

<ul>
    <li v-fro="(item,index) in arr" :key="index"></li>
</ul>

v-for中为什么要加:key
查阅相关文档给出的解释如下:
vue和react的虚拟DOM的Diff算法大致相同,其核心是基于两个简单的假设。
首先讲一下diff算法的处理方法,对操作前后的dom树同一层的节点进行对比,一层一层对比,如下图:
在这里插入图片描述
当某一层有很多相同的节点时,也就是列表节点时,Diff算法的更新过程默认情况下也是遵循以上原则。
比如一下这个情况:
在这里插入图片描述
我们希望可以在B和C之间加一个F,Diff算法默认执行起来是这样的:
在这里插入图片描述
即把C更新成F,D更新成C,E更新成D,最后再插入E,是不是很没有效率?
所以我们需要使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点。
在这里插入图片描述
vue中列表循环需加:key=“唯一标识” 唯一标识可以是item里面id index等,因为vue组件高度复用增加Key可以标识组件的唯一性,为了更好地区别各个组件 key的作用主要是为了高效的更新虚拟DOM.\。

六、父子组件传值

1、组件:
局部组件components
全局组件 Vue.component(‘组件名字’,{options})

组件传值:

父组件传值给子组件: 方法一、props,props是写在子组件中的
1、在父组件中绑定自定义属性
2、在子组件中使用props接收父组件传递的数据 3、可以在子组件中任意使用父组件数据

子组件传值给父组件

方法一、$ emit()
1、在父组件绑定自定义事件
2、子组件中出发原生的事件,在函数中使用$emit出发自定义事件

1、父用子时通过属性传递
2、子组件要声明props:[‘属性名’]来接收
3、接收到后就可以随便使用

七、单双向数据绑定

单向数据流绑定(vue -> html)

 <input type="text" :value="text">

双向数据绑定(vue -> html -> vue)

<input type="text" v-model="text">

vue基本原理:数据发生改变,视图跟着发生改变,简言之数据驱动视图(vue的核心思想)
v-mode原理
v-model双向数据绑定的体现,只会体现在UI控件中,只能应用在有value的属性上,
v-model实际上就是语法糖,他的实际原理是v-bin:value和v-on:input的体现

八、slot:就是父组件传递给DOM结构

内置的组件
slot就是父组件传递给DOM留下的坑
<子组件>DOM</子组件>
slot是动态的DOM,props是动态的数据;

slot插槽:无名插槽和具名插槽
<slot name="two"></slot>
使用的时候 <h2 slot="two"></h2>

九、生命周期

vue生命周期
beforeCreate // 组件创建之前
created // 组件创建了

beforeMount // 组件挂载dom之前
mounted // 组件挂载dom

beforUpdate // 数据更新之前
updated // 数据更新

beforeDestroy // 组件销毁之前
destroyed // 组件销毁

activated // 组件被激活
deactivated // 组件被停用

errorCaptured // 捕获组件异常
errorHandler // 捕获全局异常
<keep-alive></keep-alive> // vue内置组件,能将组件在切换的过程中将组件保存在内存中,防止重复渲染DOM,配合组件v-if 隐藏显示的时候使用。和生命周期activated和deactivated使用。
keep-alive两个属性:
include: 字符串或正则表达式。只有匹配的组件会被缓存。
exclude: 字符串或正则表达式。任何匹配的组件都不会被缓存。
例子:

<body>
    <div id="app">
        <App></App>
    </div>
    <script src="./node_modules//vue/dist/vue.min.js"></script>
    <script>
        Vue.component("Test",{
            data(){
                return{
                    msg:"hello world",
                    isShow:true
                }
            },
            template:`
               <div>
                  <h3>{{msg}}</h3>
               </div>
            `,
            methods:{
            },

            beforeCreate(){   // 组件创建之前
               console.log(this.msg)
            },
            created() {   // 组件创建之后
                console.log(this.msg)
                // created方法可以操作后端的数据  数据驱动视图
            },

            beforeMount() {
                // 将数据挂载在数据之前调用
                console.log(document.getElementById("app"))
            },
            mounted() {
                // 挂载数据到DOM之后调用,vue作用以后的Dom,操作dom
                console.log(document.getElementById("app"))
            },

            beforeUpdate() {
                // 在DOM更新数据之前调用,应用:可以获取原始Dom
                console.log(document.getElementById("app").innerHTML)
            },
            updated() {
                // 在DOM更新数据之后调用,应用:可以获取新的DOM
                console.log(document.getElementById("app").innerHTML)
            },

            beforeDestroy() {   // 组件销毁前
                console.log("beforeDestroy")
            },
            destroyed() {  // 组件销毁
                console.log("destroyed")
            },

            activated() {
                console.log("组件被激活了")
            },
            deactivated(){
                console.log("组件被停用了")
            }
        });
        var Header = {
            data(){
                return{
                    mas:"我是头部",
                    isShow:true
                }
            },
            template:`
                <div>
                   {{mas}}                   
                   <button @click="clickFun">点击</button>
                </div>
            `,
            components:{
               
            },
            methods: {
                clickFun(){
                    this.mas = this.mas + "测试";
                }
            },


        };
        var App = {
            data(){
                return{
                    isShow:true
                }
            },
            template:`
               <div class="app">
                  <Header/>
                  <keep-alive>
                      <Test v-if="isShow"/>
                  </keep-alive>
                  
                  <button @click="changeg">显示隐藏</button>
               </div>
               
            `,
            methods: {
                changeg(){
                    this.isShow = !this.isShow;
                }
            },
            components:{
                Header,
            },
           
        };

        var vm = new Vue({
            el: '#app',
            data() {
                return {
                }
            },
            methods: {
            },
            // template:`<app></app>`,
            components:{
                App,
            }
        })
    </script>
</body>

十、vue中获取DOM

1、在template中任意Dom元素任意标签上写上ref=“xxxx”,
2、通过组件对象this.$refs.xxxx来获取dom元素

 var Header = {
	   template:`
	      <div class="header" ref="header">      // ref = "xxxx"
	          <button  @click="funCli">点击</button>
	          <input type="text" ref="input">
	      </div>
	   `,
	   methods: {
	       funCli(){
	           this.$refs.header.style.background="red";     // 通过this.$refs.xxxx获取上面的dom
	       }
	   },
	   mounted(){
              this.$nextTick(function(){    // 真正等vue渲染dom后在操作的,可以放在this.$nextTick中执行
				     this. $refs.input.focus()
				})
       }
	};

$属性: $refs获取组件内的元素,
$parent:获取当前组件对象的父组件
$children:获取子组件
$root:获取new Vue的实例 vm
$el: 组件对象的DOM元素

十一、路由

1、前端路由原理
做vue路由时候先来了解下前端路由:hash(哈希模式) 和 history模式
(1)、原生hash(哈希模式)
前端路由的原理是:锚点值做不同的显示,页面不跳转,加上innerHTML的替换,如下代码:

<body>
      <a href="#/login">点我登录</a>
      <a href="#/register">点我注册</a>
      <div id="content"></div>
</body>
<script>
     var oDiv = document.getElementById('content');
      window.addEventListener('hashchange',() =>{
         switch(location.hash){
            case '#/login':
            oDiv.innerHTML = "<h1>登录页面吧</h1>";
            break;
            case '#/register':
            oDiv.innerHTML = "<h1>注册页面</h1>";
            break;
          }
      })
</script>      

(2)、history模式
如果不想看到#可以使用history模式,原理依赖于history.pushState函数

  1. a标签点击以后,如果没有#必然会页面跳转发起请求
  2. 使用pushState函数可以改变url 比如 /abc而不会 发起请求
  3. js通过location.pathname获取/abc做页面局部替换

下面是原生history模式的实现

// 01_history.html文件代码
	<body>
		<!--类似于router.link-->
		<a href="javascript:void(0)" onclick="goHistory('/user')">去看User</a>
		<a href="javascript:void(0)" onclick="goHistory('/goods')">去看goods</a>
		
		<div id="box"></div>
		<script type="text/javascript">
		// 点击按钮时
			function goHistory(url){
				let text = '';
				switch(url){
					case '/user':
					   text = '用户页面'
					   break;
					case '/goods':
					   text = '商品页面';
					   break;
				}
				// 判断后做相应url改变
				history.pushState({},'',url);
				// 改变页面效果
				document.getElementById("box").innerHTML = text;
			}

			// 当页面加载的时候
			// 处理刷新的时候
			window.onload = function(){
                let text2 = '';
				let path = location.pathname;
				switch(path){
					case '/user':
					   text2 = '用户页面';
					   break;
					case '/goods':
					   text2 = '商品页面';
					   break;
				}
				document.getElementById("box").innerHTML = text2
			}
		</script>
	</body>
*********************************************************************************************
//01_server.js  服务端代码 
const http = require('http');
const fs = require('fs');

http.createServer((req,res) => {
    fs.readFile('./01_history.html',(err,data) => {
        res.end(data)
    })
})
.listen(8888);

*******************************************
需要在服务端启动看效果
node ./01_server.js

在这里插入图片描述

2、vue路由
《一》、步骤:
(1)、引入vue插件 vue-router.js
(2)、安装插件Vue.use(Vue.router);
(3)、创建一个路由对象
var router = new VueRouter({
(4)、配置路由对象
routes:[{
path:/login,component:Login}]})
(5) 、将配置好的路由对象关联到vue实例中
(6)、指定路由改变局部的位置
例子:

<body>
      <div id="app"></div>
</body>
<script src="../node_modules/vue/dist/vue.min.js"></script>
<script src="../node_modules/vue-router/dist/vue-router.min.js"></script>
<script>
    var Login = {
        template: `<div>我是登录页</div>`
    };
    var NewPage = {
         template:`<div>我是新闻</div>`
       };
    // 2
    Vue.use(VueRouter);      // Vue.use(插件对象); 过程中会注册一些全局组件,及给vm或者组件对象挂在属性;
    // 3
   var router = new VueRouter({
    // 4
	     routes:[
			     {name:'login',path:'/login',component: Login},
			     { name:'news',path:'/newPage',component:NewPage},
			     { path:'vue/:id', // params使用  name:'vue',component:VuePage },
	     ]
	 }) 
     // 6
       var App = {
           template: `
              <div>
                 <router-link :to="{name:'login'}">登录页</router-link>
                 <router-link :to="{name:'news'}">新闻页</router-link>
                  <router-view></router-view>
               </div>
           `
       };
       // 5
       var vm = new Vue({
           el: '#app',
           router:router, 
           components: {
               app:App
           },  
           template: `
                  <app/>
               `,
       })
</script>

《二》、 router-link

   <router-link :to="{path:'路径'}" ></router-link>  
   <router-link :to="{name:'路径名'}" ></router-link> 

router-link
Vue.prototype.xxx = {add:in}
所有组件中,使用this.xxx就能拿到这个对象
1、配置 :to="{name:'detail',query:{id:1}}" 或者 :to="{name:'detail',params:{id:1}}"
2、规则 {name:'detail',path:'/detail',component:Detail}
3、获取 this.$route.query.id
4、生成 <a href='/detail?id=1'></a>


path方式:
1、配置 :to="{name:'detail',params:{name:'abc'}}"
2、规则 {name:'detail',path:'/detail/:name'}
3、获取 this.$route.params.name
4、生成 <a href='/detail/1'></a>


命名路由:
1、给路由对象一个名字{name:“home”,path:’/home’,component:Home}
2、在router-link属性中描述这个规则:通过名称找路由对象,获取path,生成自己的href <router-link :to="{name:'home'}"></router-link>
3、优点降低维护成本,锚点值改变只用在main.js中改变path属性即可。


总结:
vue-router使用步骤:
1、引入vue-router.js
2、安装插件
3、创建路由实例
4、配置路由规则
5、将路由对象关联vue
6、留坑<router-view></router-view>


router-link :to=“xxx” 命名路由
1、在路由规则对象中加入name属性
2、在router-link中绑定对象 :to="{name:‘名字’}"


生僻API梳理:
1、 Vue.use(插件对象); 过程中会注册一些全局组件,及给vm或者组件对象挂在属性;
2、给vm及组件对象挂在的方式:

Object.defineProperty(Vue.prototype,'$router',{
     get:function(){
        return 自己的router对象;
     }
 })

vue-router中的对象:
$route 路由信息对象,只读对象; this.route.query.name
$router 路由操作对象,只写对象; this.router.push('/login')


路由嵌套实例:

<body>
    <div id="app"></div>
    <script src="../node_modules/vue/dist/vue.min.js"></script>
    <script src="../node_modules/vue-router/dist/vue-router.min.js"></script>
    <script>
        var WebPage = {
           template:`
              <div>前端学习页</div>
           `
        };
        var ReactPage = {
            template:`
               <div>react学习页</div>
            `
        };
        var HomePage = {
            template:`<div>
               我是首页
               <hr/>
               <router-link :to="{name:'webPage'}">前端总结</router-link>
               <router-link :to="{name:'reactPage'}">React学习</router-link>
               <router-view></router-view>
            </div>`,
        };
        var NewsPage = {
            template:`<div>我是新闻</div>`
        };
        var router = new VueRouter({
            routes:[
                {path:'/', redirect:'home'},    // redirect路由重定向
                {path:'/home',component:HomePage,name:'home',
                  children:[    // 嵌套路由
                      { path:'/',redirect: 'webPage'},
                      {path:'webPage', component:WebPage,name:'webPage'},
                      {path:'reactPage',component:ReactPage,name:'reactPage'}
                  ]},
                {path:'/news',component:NewsPage,name:'news'}
            ]
        });
        var App = {
            template:`
              <div>
                 <router-link :to="{name:'webPage'}">首页</router-link>
                 <router-link :to="{name:'news'}">新闻</router-link>
                 <router-view></router-view>
              </div>
            `,
            components:{
                HomePage
            }
        };
        var vm = new Vue({
            // el:'#app',
            template:`<App/>`,
            router,
            components:{
                App
            }
        }).$mount('#app')
    </script>
</body>

路由参数实例:

<body>
    <div id="app"></div>
    <script src="../node_modules/vue/dist/vue.min.js"></script>
    <script src="../node_modules/vue-router/dist/vue-router.min.js"></script>
    <script>
        var VuePage = {
            template:`<div>vuePage</div>`
        };
        var ReactPage = {
            template: `<div>reactPage</div>`
        };
        var AngularPage = {
            template: `<div>angularPage</div>`
        };

        var HomePage = {
            template:`
               <div>
                 我是首页
                <br/>
                 <router-link :to="{name:'vue',params:{id:1}}">vue</router-link>   // params参数使用
                 <router-link :to="{name:'react',query:{userId:1}}">react</router-link>   // query参数使用
                 <router-link :to="{name:'angular'}">angular</router-link>
                 <router-view></router-view>
               </div>
            `
        };
        var NewsPage = {
            template: `
            <div>我是新闻</div>
        `
        };
        var router = new VueRouter({
            routes:[
                { path:'/', redirect:'home'},
                { path:'/home',name:'home',component:HomePage,
                  children:[
                     {path:'/',redirect:'vue'},
                     {path:'vue/:id',    // params使用 name:'vue',component:VuePage},
                     {path: 'react', name: 'react',component: ReactPage},
                     {path:'angular',name:'angular',component:AngularPage}
                  ] },
                { path:'/news', name:'news', component:NewsPage}
            ]
        });
        var App = {
            template:`
               <div>
                   <router-link :to="{name:'home'}">首页</router-link>
                   <router-link :to="{name:'news'}">新闻</router-link>
                   <router-view></router-view>
               </div>
            `
        };
        var vm = new Vue({
            el:"#app",
            data(){
                return{

                }
            },
            template:`<App>`,
            router,
            components:{
                App
            }
        })
    </script>
</body>

路由meta简单模拟拦截登录实例
知识点:
路由meta元数据 > meta是对于路由规则是否需要验证权限的配置
1、路由对象中和name属性同级{meat:{isChecked:true}}
路由钩子 > 权限控的函数执行时期
1、每次路由匹配,渲染组件到router-view之前
2、router.beforeEach(function(to,from,next){})
redirect里有重定向

<body>
    <div id="app"></div>
    <script src="../node_modules/vue/dist/vue.min.js"></script>
    <script src="../node_modules/vue-router/dist/vue-router.min.js"></script>
    <script>
        var isLogin = false;
        var HomePage = {
            template:`
               <div>
                 我是登录页
               </div>
            `,
            created() {
                isLogin = true;
            },
        };
        var NewsPage = {
            template: `
            <div>我是新闻</div>
        `
        };
        var router = new VueRouter();
        router.addRoutes([     // 这样的写法可以多次的追加路由规则,动态获取路由规则,更为灵活,可以方便调用后追加路由规则
            // { path: '/', redirect: 'home' },
            { path: '/home', name: 'home', component: HomePage, },
            // meta:{isChecked:true}给未来路由的权限权限控制,全局路由守卫来做参照条件
            { path: '/news', name: 'news', component: NewsPage, meta:{isChecked:true}}
        ]);
        router.beforeEach(function(to,from,next){
            console.log(to);
            console.log(from)
           if(to.meta.isChecked){
                if(isLogin){
                    next();    // next(false) 取消用户导航行为
                } else {
                    alert("请先登录");
                    next({name:'home'});   // 可以个对象也可以给锚点值
                }
           } else {
              next();   // 不调用会卡住
           }
        });

        var App = {
            template:`
               <div>
                   <router-link :to="{name:'home'}">登录</router-link>
                   <router-link :to="{name:'news'}">新闻</router-link>
                   <router-view></router-view>
               </div>
            `
        };
        var vm = new Vue({
            el:"#app",
            data(){
                return{

                }
            },
            template:`<App>`,
            router,
            components:{
                App
            }
        })
    </script>
</body>

后端路由的原理就是 url + 请求方式 后端判断(只做了解)
前端路由 url(锚点值)+ innerHTML


(2)、原生history模式
去除了#方式,每次都向服务器请求index.html,再由客户端分析当前url,做不同的变化。
实现原理:
1、在页面通过location.pathname获取当前请求url
2、让服务器不论什么请求都返回以上这个index.html

1、在页面通过location.pathname获取当前请求url
//HTML代码
switch(location.apthname){
   case '/user':
      document.body.innerHTML = '用户页面';
      break;
   case '/login':
      document.body.innerHTML = '登录页面';
      break;
   default:
      document.body.innerHTML = '我是history模式'   
}

2、让服务器不论什么请求都返回以上这个index.html
// 前端服务器代码
const http = require('http');
const fs = require('fs');
let server = http.createServer();
server.on('request',(req,res) => {
   fs.readFile('./index.html',(err,data) => {
       res.end(data)
   })
})
server.listen(8888);

vue History模式

import Vue from 'vue'
import Router from 'vue-router'

import wxEntrance from '@/wx.vue'

/* 
import Home from '@/components/Home/Home';
import Member from '@/components/Member/Member';
*/

const home = r => require.ensure([], () => r(require('../components/Home/Home.vue')), 'home') //首页
const member = r => require.ensure([], () => r(require('../components/Member/Member.vue')), 'member');  // 会员


Vue.use(Router);  // 注册全局组件 router-view  router-link 挂在在Vue.prototype.$router || $route,未来所有的组件中的this对象,就具备该属性,所有的this就是vue的子类对象

export default new Router({
  mode:'history',      // 设置history路由模式
  base:__dirname,
  routes: [{
      path: '/',
      redirect: '/home',
      component: wxEntrance,
      children: [
        { path: '/', redirect:'/home' },
        { name:'home', path:'/home', component:home, meta:{ requireAuth: false}},
        { name:'member', path:'/member', component:member,meta:{ requireAuth: false}},、
      ]
    },
  ],
  scrollBehavior(to, from,savedPosition){     // 记录滚动的位置
       console.log(to);
       console.log(savedPosition);
       return{
            x:0,y:50      //  return 期望滚动到那个位置
       }
   }
})

History模式可以设置页面滚动

十二、过滤器filter:全局过滤器和局部过滤器

1、局部过滤器:直接在局部组件中使用

filters:{
    // 声名过滤器
   filteName:function(value){
      return "$"+vvalue
   }
}

2、全局过滤器 Vue.filter

Vue.filter("filterName",function(value){
   return value.split('').reverse().join('')
})

十三、watch监听

watch监听的是单个属性

基本数据类型简单监听
复杂数据类型深度监听

例如:

var mag = '';
var arr = [{name:"jack"}]
Watch:{
  mag:function(newV,oldV){    // 简单监听 newV新值   oldV旧值
      console.log(newV,oldV)
  },
  arr:{    // 深度监听复杂类型arr数组
     Deep:true,
     handler:function(newV,oldV){
      console.log(newV)
    }
  }
}

computed计算属性:
计算属性只有getter,
但是在适当的时候可以用setter

十四 axios

Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
特性

  • 从浏览器中创建 XMLHttpRequests
  • 从 node.js 创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换 JSON 数据
  • 客户端支持防御 XSRF

模拟请求示例:

<body>
    <div id="app"></div>
    <script src="./vue.min.js"></script>
    <script src="./vue-router.min.js"></script>
    <script src="./axios.min.js"></script>
    <script>
        var App = {
            template:`
               <div>
                   <button @click="sendAjax">点击发送</button>
                </div>
            `,
            components:{
            },
            methods: {
                sendAjax(){
                    axios.get("http://127.0.0.1/:8080",{})
                    .then(res =>{
                        console.log(res)
                    })
                    .catch(err => {
                        console.log(err)
                    })
                    
                    //***********************************************
                    // 配置公共请求数据连接(接口前面一样的,可以写成下面里面)
                    this.$axios.defaults.baseURL = "http://127.0.0.1/";
                    // ************************************************
                    
                     // 合并多个请求,并处理其成功和失败
                    //var q1 = this.$axios.get('');
                    //var q2 = this.$axios.get('add','a=1');
                    //this.$axios.all([q1,q2])
                    //.then(this.$axios.spread((res1,res2)=>{
                    //}))
                    //.catch(err => {
                    //})
            
                }
            },
        };
        Vue.prototype.$axios = axios;
        var vm = new Vue({
            el:"#app",
            data(){return{}},
            template:`<app/>`,
            components:{
                App
            }
        })
    </script>
</body>

十五、预渲染prerender(在spa进一步做了优化)

SPA搜索引擎优化(SEO)
1、安装插件:

npm install prerender-spa-plugin -D

2、配置webpack.prod.js文件

const PrerenderSpaPlugin = require("prerender-spa-plugin");
plugins:[
   new PrerenderSpaPlugin({
        staticDir:path.join(__dirname,'..','dist'),
        routes:['/','/user']   // 根据这两个路由规则找到组件渲染HTML文件
   })
]

3、配置路由变更对象,传递构造属性
mode:‘history’
4、构建项目代码 npm run build

5、进入dist目录 启动生成的代码 hs -o -p 999

十六、骨架屏(Sekeleton)

请求数据回来之前展示的效果,可以提前预览结构,类似于loading,
相当于loading图标,相比较loading图标而言,用户可以预览未来要看到的结构,同时避免了白屏的尴尬,还能操作,因此用户体验较好,当然这些是跟需求走,也有应用将loading结合骨架屏来实现的。
可以通过lavas插件来实现骨架屏: 点击查看lavas文档
操作步骤:
1、npm i -g lavas
2、lavas init
3、选择包含app_shell 也包含了骨架屏的功能

可以配置多个骨架屏
1、预渲染解决静态数据SEO
2、骨架屏,代替loading图标,用户体验更好,可以提前预览结构
如果配合上WPA中的service worker就可以缓存各种数据,不必要请求多余的资源(包括骨架屏资源)
service worker可以实现离线浏览(所有资源缓存在期中,拦截浏览器请求,相应保存的结果)

阶段总结:

1、路由懒加载的使用
2、通过router-view传递参数$refs 在要使用的子组件内props:[‘xxx’]
3、this.xxx.header使用

理解面试和沟通的
SPA是什么?
vue-router中是否可以不使用#来开发,使用history模式,默认是hash模式
在history模式下,可以scroll导航后滚动
history模式实现其实是基于服务器每次返回index.html而客户端根据location.pathname来做渲染。

SEO是什么,搜索引擎优化
SPA下SEO必然比较差的
使用预渲染,然后固定的页面,作为服务器响应的结果响应回来,也是基于history模式

vue 多页面应用:

核心思想:就是两个vue项目,一次webpack打包,关联url联系
webpack操作:
1、多个入口{main1:’./usermain.js’,main2:’./goodsmain.js’}
2、多个html插件

注意事项:

// 文件名称
filename:filename+’.html’
// 页面模版需要加对应的js脚本,如果不加这行则每个页面都会引入所有的js脚本
chunks:[‘manifest’,‘vendor’,filename]

getHtmls的思路
更为灵活的读取各项目下的js文件(入口)entry:{‘js文件名’:‘js文件路径’}
更为灵活的读取各项目下的html文件(首页.html)plugins:[].concat([new HtmlWebpackPlugin()]); 有几个 new 几个
filename属性是生成的相对dist的文件名xxx.html
template模版生成的参照物 需要绝对路径||相对路径’./xxx.html’
chunks:[filename]指定第三引入的js文件名称

PWA(渐进式/web/application)谷歌开发的

安装

vue init pwa 项目名称
hs -o -p 端口号

应用:
离线浏览web应用,生成桌面应用,顶部通知(页面都可以不存在),预缓存(在页面没有启动前,请求资源保存在浏览器)(真正访问的时候,非常快,请求本地),骨架屏,App shell(利用缓存机制保存html+css+js等)

服务器渲染(SSR)(插件vue-server-renderer)

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

(一)、简易的服务端渲染理解
在这里插入图片描述
简单的node.js服务器渲染demo

cd 到对应文件 => 运行 npm init --yes =>然后在运行npm in vue express vue-server-prenderer

在文件夹新建 server.js文件,输入如下代码:

const Vue = require('vue')
const express = require('express')()
// 创建服务端的渲染器
const renderer = require('vue-server-renderer').createRenderer()

// 创建vue实例
const app = new Vue({
    template:'<div>hello 我是简单的服务端渲染页面</div>'
})

// 服务端渲染的核心就在于:通过vue-server-renderer插件的renderToString()方法,将Vue实例转换为字符串插入到html文件
express.get('/',(req,res) => {
    renderer.renderToString(app,(err,html) => {
        // console.log(html)
        if(err){
            return res.state(500).end("运行错误")
        }
        res.send(`
            <!DOCTYPE html>
            <html lang="en">
            <head>
                <meta charset="UTF-8">
                <title>Vue2.0 SSR渲染页面</title>
            </head>
            <body>
                ${html}
            </body>
            </html>
        `)
    })
})
// 服务端渲染
express.listen(8001,()=>{
    console.log("服务端已启动")
})

命令行运行node ./server.js 启动项目
渲染结果如下:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值