关于vue.js:学习Vue看这篇文章就够了你都掌握了吗

Vue外围语法

面试题:Vue框架的特点

  1. 组件【component】式开发,能够复用代码,进步开发效率
  2. 申明式编程

不必操作DOM,操作数据,进步开发效率【数据发生变化,视图跟着变动,不必操作DOM,只是关怀数据】

  1. 采纳虚构DOM+优良DIFF算法,能够复用DOM

总结:组件化、申明式编程、虚构DOM+优良DIFF算法

获取Vue依赖包

官网下载:https://cn.vuejs.org/v2/guide…

npm:npm、yarn下载

cdn:cdn下载都能够

首次理解

Vue首次理解:
一、Vue框架次要关注于视图(view)的一个框架
二、Vue渐进式JavaScript框架
总结:渐进式,Vue框架提供外围的语法,能够在外围语法根底之上欠缺我的项目性能、路由、集中式治理等等慢慢欠缺我的项目。
Vue全家桶:vue+周边外围插件,统称为全家桶
渐进式:Vue框架提供一些外围的语法【指令等等】
我的项目当中须要应用路由性能:Vue框架没有这个性能-vue-router配置路由
我的项目中须要应用一些通用组件成果:轮播图、遮罩层,element-ui
我的项目当中想要集中式治理数据:vuex等等

根本用法

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 第一步:引入vue.js -->
    <!-- vue框架对外裸露了一个构造函数【类】Vue构造函数 function Vue(){}-->
    <script src="../js/vue.js"></script>
</head>

<body>
    <!-- 第二部:筹备容器 -->
    <div id="root">
        <!-- 展现动态数据 ,要用双大花括号-->
        <!-- {{}}:插值语法,胡子语法-->
        <!-- 留神:插值语法只能在文本区域书写,不能再标签属性中书写-->
        <h2>您好,{{name}}</h2>
    </div>

    <script>
        //Vue对外裸露一个构造函数Vue
        // Vue的实例个别叫做VM
        // new Vue构造函数的时候须要传递一个【配置对象】
        const VM = new Vue({
            el:"#root",//el的属性值个别是字符串类型的css选择器,它的作用是VM与容器进行关联
            data:{//data的属性值个别是对象,它的作用是给实例对象VM增加一些属性
                name:'浩哥'
            }
        });
        console.log(VM);
        /* 
        VM:Vue类的实例,数据能够和容器进行关联
        VM实例属性的属性值发生变化,视图上的数据就跟着变动
        数据变动跟着视图变动
        留神:VM身上的属性是【响应式数据】,数据发生变化,视图跟这变动!!!
        */

    </script>
</body>

</html>

胡子语法(插值语法)注意事项:

  1. 能够书写实例的属性
  2. 能够书写JS表达式

表达式:最终会产生一个数值,能够书写在胡子语法外面

eg:数学运算符:+ – * / %;

​ 比拟运算符;

​ 逻辑运算符

​ 三元运算符

​ 固定的某一个数值

​ 函数调用,函数执行的后果也有返回值

切记:如下的语法不能在胡子语法中书写:

if、for、switch等等,不是表达式

Vue开发者工具的装置

Vue开发者工具,是服侍开发者的,对我的项目调试有很大用途

能够判断一个我的项目是不是Vue我的项目

配置对象的其余写法

 const VM = new Vue({
         //配置属性data的作用:给实例对象VM减少响应式数据
        //data第二种写法(函数的写法)
        //data functions should return an object:如果data配置项写法如果是函数,必须要返回一个对象
        //data函数返回后果作为VM属性与属性值
         data(){ 
           return {
              name:"明天是一个好日子,吃了火锅",
              age:18,
              sex:'爷们',
              hobby:'游戏'
           }
        },
        //methods配置项的作用:能够给实例对象VM减少办法,留神:办法不能书写为箭头函数
        methods:{
            handle(){
            
            }
        }
    
 });
 //上面这行代码:也能够将VM与容器进行关联
 //$mount是Vue.prototype原型上的一个办法,Vue类的实例能够调用,作用是与el配置项性能一样的
 //就是把VM实例与容器进行关联
 //小总结:Vue类的实例办法个别都是以$结尾的
 VM.$mount('#app');

指令【directive】

v-bind

作用:能够给标签绑定动静属性值【数据发生变化、标签的属性值也跟着变动】动静属性值与VM无关,VM属性值发生变化,视图跟着变动!!!

简写(1个冒号) :
总结:
胡子{{}}:给标签绑定动静文本
v-bind:给标签绑定动静属性值

例如:

<img v-bind:src="url"><br />
<input v-bind:type="leixing">
<p v-bind:id="name"></p>
<hr>
<h1>v-bind简写形式</h1>
<img :src="url"><br />
<input :type="leixing">
<p :id="name"></p>
//初始化Vue实例,进行关联
const VM = new Vue({
    el: '#app',
    data: {
        url: "./images/1.jpg",
        leixing: 'text',
        name: 'box'
    }
})

v-model(数据的双向绑定)

作用:能够让表单元素实现数据的双向绑定【页面+数据同步】,次要作用是 收集表单元素 的信息,

留神:非表单元素p、div、a、img等等不能应用v-model

文本框:
        <input type="text" v-model="msg">
<hr>
单选:
<input type="radio" value="nan" v-model="sex"/>男
<input type="radio" value="nv"  v-model="sex"/>女
<hr>
复选:在通过数据双向绑定收集数据的时候,复选框用数组收集数据
<input type="checkbox" value="eat"   v-model="hobby">吃饭
<input type="checkbox" value="sleep"  v-model="hobby">睡觉
<input type="checkbox" value="fire"   v-model="hobby">打豆豆
<hr>
<!-- 
  下拉菜单:下拉菜单数据双向绑定的时候,给select进行绑定的
-->
<select v-model="city">
  <option value="bj">北京</option>
  <option value="sh">上海</option>
  <option value="gz">广州</option>
  <option value="sz">深圳</option>
</select>
const VM = new Vue({
    el: '#app',
    data() {
        return {
          msg:'我是祖国的老花骨朵',
          sex:'nv',
          hobby:['eat'],
          city:'sz'
        }
    }
})

v-on

用法:v-on:事件名字=”事件处理函数” v-on:click=”handle”

作用:给标签绑定事件

简写:@ @click=”handle”

<!-- 传递参数-->
<button @click="getMessage(666) ">点击我传递一个参数</button>

<!-- 
    事件对象的写法$event,切记$必须要书写
    event:事件对象,事件对象能够获取鼠标地位、键盘码、阻止默认事件、阻止事件流传
-->
<button @click="getMessage2($event,12306,'喜爱张杰') ">点击我传递多个参数</button>


<!-- 

    @click="getMessage3",不传递参数,不写小括号,事件回调函数默认注入事件对象,第一个参数就是事件对象

    @click="getMessage3($event)",这样代表的传递参数事件对象,回调能力获取到事件对象

    @click="getMessage3()" 这样书写代表传递参数,然而你没有传递参数,形参获取的第一个变量数值为undefined
 -->
<button @click=" getMessage3">event获取注意事项</button>

v-if的应用

//v-if:是Vue框架给咱们提供一个指令,它次要的作用是能够让元素进行显示或者暗藏
//v-if指令,右侧须要个别是布尔值,真代表以后元素显示、假代表元素暗藏。
//v-bind|v-model|v-on|v-if,右侧属性值能够VM对象的属性|JS表达式
//须要留神:在应用v-if|v-else-if|v-else两头不要呈现其余的标签【货色】,否则生效!!!

//v-if是通过何种伎俩实现元素的显示与暗藏?
//显示:每一次展现都是创立一个新的DOM
//暗藏:每一次都须要移出、干掉DOM进行暗藏。
//因为v-if:间接操作DOM创立与销毁,频繁的操作DOM,很耗性能的。

v-show的应用

//v-show通过什么实现的显示与暗藏?
  //v-show是通过款式display实现元素的显示(block)与暗藏(none)

总结:

v-if|v-show:都能够实现元素的显示与暗藏。

v-if:通过创立新的DOM节点|移除DOM节点实现DOM显示与暗藏【频繁的创立、销毁DOM】比拟耗费性能的
v-show:通过CSS款式管制元素的显示与暗藏【DOM节点仅仅只是须要创立一次即可】

v-for的应用

//v-for指令,到底能遍历哪些数据?
//v-for能够遍历以下数据:数组、数字、字符串、对象
//v-for遍历数据:工作、我的项目当中个别只是应用数组!!!!

<!-- 列表的渲染
  v-for右侧的属性值不能瞎写、不能胡写、不能乱写。依照人家的语法来搞
  v-for = "元素  in  数组"
  stu:是数组外面的每一个元素   stu你能够当中一个变量,变量在应用的时候,须要用到插值语法
  students:须要遍历的数据【数组】 
  index:是数组外面元素的索引值
  留神:in与后面、前面切记保留住空格,如果没有空格把in当中=做一个整体了,就没有关键字in,导致报错

  v-for渲染列表的时候,也须要加上key属性,且key属性值应该是举世无双的

  key:属性值,是举世无双的,不能雷同。
  key:属性值能够用index,尽可能别应用,万一有逆序的操作会有问题的。
  尽可能应用的是元素的id
-->
<h1>遍历数组</h1>
<ul>
    <li v-for="(stu,index) in students" :key="stu.id">
        {{stu.name}}----{{index}}
    </li>
</ul>
<hr>
<h1>遍历数字</h1>
<!-- 遍历数字的时候,从数字1开始的 -->
<!-- 索引值肯定是从数字零开始的 -->
<p v-for="(num,index) in 6" :key="index">
    {{num}}----{{index}}
</p>
<hr>
<h1>遍历字符串</h1>
<p v-for="(str,index) in '明天是好日子'" :key="str">
     {{str}}---{{index}}
</p>
<hr>
<h1>遍历对象</h1>
<!--
     v:对象的属性值
     k:对象的属性名称
-->
<p v-for="(v,k) in obj" :key="k">
     {{v}}---{{k}}
</p>

修饰符的应用

prevent修饰符的应用:

<!-- form表单:action,action属性的作用是,是把表单数据提交到哪里 -->
<!-- 
    当初点击按钮:点击完按钮,网页会跳转到百度,form标签action属性的作用,
    有默认行为
 -->
<form action="http://www.baidu.com">
    <!-- 
        润饰:prevent->阻止默认事件
        @click.xxxx ->即为修饰符
     -->
    <button @click.prevent="showMessage">点击我弹出1126很帅</button>
</form>

stop修饰符的应用:

<div class="cur" @click="showMessage1">
    <!-- 
        stop:修饰符,能够阻止事件的冒泡
     -->
    <button @click.stop="showMessage1">阻止事件流传</button>
</div>

once修饰符的应用:

<!-- 
    修饰符:once,润饰只会让事件触发一次!!!
    因为有的我的项目,须要让元素事件只会触发一次,利用修饰符once
 -->
 <button @click.once="showMessage2">once修饰符</button>
留神:修饰符能够进行链式语法,谁先谁后无所谓,这种呈现状况比拟是少
这些语法都是反对的,只不过我的项目、工作当中根底没有这种写法!!!!
@click.stop.prevent.once
@click.once.prevent.stop
@click.prevent.stop.once

键盘事件的修饰符

键盘事件的修饰符,个别只是与表单元素一起应用。
键盘相干的修饰符有很多:
    enter->回车键
    left->左键
    right->右键
    up->上键
    down->下键
    esc、
    a-z、
    数字的都能够、书写相应的键盘码数字都能够
    
<input type="text" v-model="game" @keyup.enter="handle">

Object.defineProperty的补充

//Object.defineProperty() 办法会间接在一个 对象上定义一个新属性 ,或者批改一个对象的现有 属性
let obj1 = {age:19,sex:'男'};
//能够通过Object.definedProperty办法,给对象obj增加新的属性
//参数:第一个参数 对象
//参数:第二个参数 对象新增|已有的属性的属性名字
//参数:第三个参数 描述符  对象【描述符】
//第三个参数:配置项【描述符:数据描述符-> value、enumerable、 writable、 configurable】
// Object.defineProperty(obj1,'name',{
//       value:'曹操',//obj1增加了一个新的属性,且属性值为曹操
//       enumerable:true,//enumerable属性值设置为真,代表新增的属性能够进行遍历,默认是false
//       writable:true,//代表新增的属性的属性值能够批改,默认初始值false
//       configurable:true,//描述符,代表新增的属性能够删除,默认初始值false
// });
// obj1.name = "貂蝉";
// delete obj1.name;
// console.log(obj1);


//读取描述符:get||getter、set|setter,办法,是函数
Object.defineProperty(obj1,'name',{
    //get:在读取name的属性值的时候会触发
    //get办法执行返回后果作为属性的属性值
    get(){
       console.log('在读取name属性值的时候get办法会触发');
       return "我爱你1126";
    },
    //set:在设置name的属性的属性值的时候触发
    set(val){
        //set办法执行,零碎会注入一个参数,参数即为这个属性最新的属性值
       console.log(6666,val);
    }
});

//设置name新的属性值
obj1.name = '鲁班七号';

面试高频题:apply、call、bind区别?

只管call、apply和bind三个办法的作用都是扭转函数执行时this的指向,但它们在应用上还是有肯定的区别。

(1)call、apply与bind的区别

  call和apply都是扭转函数的上下文this的指向后立刻执行该函数,而bind则是返回扭转上下文this后的一个函数。

(2)call和apply两者的区别

  call和apply的第一个参数都是要扭转的上下文对象,call从第二个参数开始以及前面的参数都是以参数列表的模式展示,而apply则是把除了要扭转的上下文对象外的其余参数放在一个数组作为它的第二个参数。

面试:响应式数据的原理剖析

Vue2版本响应式数据实现的原理 : 利用Object.defineProperty实现的

面试题:怎么晋升性能?

  1. 应用按需加载
  2. 尽可能应用v-show

ref属性(在Vue实例上是$ref)

<!-- vue框架提供ref技术,能够让你获取实在DOM节点 -->
<!-- ref属性值惟一:如果雷同取后者 -->
<h1 ref="tab">今天天气不错,今天天气更好</h1>
<h2 ref="tab1">今天天气不错,今天天气更好</h2>
<button @click="getMessage">点击我的时候,弹出h1文本内容</button>

当 v-for 用于元素或组件的时候,援用信息将是蕴含 DOM 节点或组件实例的数组。

计算属性

//计算属性:单词千万别写错,配置项K,没有商量余地
computed: {
    //这种写法:代表的是给VM增加一个新的属性,且这和办法的返回值即为这个新增的属性的属性值
    //computed计算属性,新增的属性也是响应式的【底层也是利用Object.defineProperty实现】
    allName() {
        //this,即为Vue实例VM
        console.log('测试是否执行');
        //当新增的属性,依赖的 响应式数据 发生变化的时候,以后函数会再次执行,计算出一个新的属性值提供应用
        //留神的事件事件是:计算属性这里个别不书写异步语句
        //异步语句:提早器、定时器、ajax等等
        //上面写法是谬误的:return返回值作为定时器回调函数的返回值
        // setTimeout(() => {
                //并非是allName这个函数返回值
        //     return this.xing + '-' + this.ming;
        // }, 1000);
        
        return this.xing + '-' + this.ming;
    }
}

//computed计算属性,它次要的作用是利用已有的属性与属性值,创立出一个新的属性与属性值

//计算属性还有另外一种写法:第一种写法->函数写法
//计算属性还有第二种写法:第二种写法->对象
computed: {
    //计算出新的属性
    allName: {
        //get办法,不能瞎写、不能胡写、乱写
        get() {
            //this:this即为以后Vue类的时候,也就是VM
            return this.xing + '-' + this.ming;
        },
        //set:当这个属性的属性值赋予新的数值的时候会触发
        set(val) {
           //获取设置新的数值
           let arr = val.split("-");
           this.xing = arr[0];
           this.ming = arr[1];
        }
    }
}

## 面试题:methods与computed区别?

//methods它次要的作用是给VM实例增加办法   -------办法
 //computed:它是利用已有的属性与属性值创立出一个新的属性与属性值----属性

 //区别1:methods办法在应用的时候个别须要加上小括号,computed计算出来的属性,在应用的时候是不须要加小括号的
 //区别2:计算属性算进去的数值有缓存机制,计算出一个能够屡次应用

动静类名

<!-- 当初这种写法:退学时候所学习,p标签的类名属性值死的 -->
<p class="box box1">大江东去浪淘尽,千古风流人物</p>

<!-- 动静类名的写法,动静类名也能够联合非动静类名一起应用,能够增加多个类名 -->
<h1>动静类名-字符串写法</h1>
<pre class="tab1" :class="selector">
    煮豆持  作羹,漉菽认为汁。

    萁在釜下燃,豆在  釜中泣。

    本自同  根生,相煎何太急?
</pre>
<h1>动静类名对象写法</h1>
<!-- 
    动静类名能够右侧对象的写法:
    {
        K:V
    }
    k:就是未来要增加动静类名
    V:判断的条件,真,动静类名就有,如果是假,动静类名就没有
 -->
 <p :class="obj">
    1.《长城》【唐】汪遵 秦筑长城比铁牢,蕃戎不敢过临洮。 尽管万里连云际,争及尧阶三尺高。
 </p>
<h1>动静类名之数组的写法</h1>
<p :class=" ['cur','ka',selector,obj ] ">
   北京(Beijing),简称“京”,古称燕京、北平,是中华人民共和国的首都、直辖市、国家核心城市、超大城市,国务院批复确定的中国政治核心、文化核心、国际交往核心、科技翻新核心,截至2020年,全市下辖16个区,总面积16410.54平方千米。依据第七次
</p>
data: {
    selector: 'tab',
    obj: { one: true, two:0}
}

动静行内款式

<!-- 容器|模板 -->
<div id="app">
    <!-- 学习CSS时候,行内款式是上面写法,非动静写法 -->
    <div style="width: 400px;height: 100px;background: red;">我是祖国的老骨朵</div>
    <h1>行内款式的动静写法之--对象写法</h1>
    <p v-bind:style=" { width:'600px',height:'50px',color:'red'} ">
        Vue框架行内款式写法
    </p>
    <h1>行内款式动静写法之-数组写法</h1>
    <p :style="[obj,obj1]">
        动静行内款式style反对数组写法
    </p>
</div>
//动静行内款式写法:反对对象写法、反对数组写法。次要记忆对象写法

watch监听属性

 //监听属性,作用:watch也是一个配置项,它次要的作用是,能够监听 VM响应式属性的值 的变动。
 watch: {
    //监听属性的时候,当属性值发生变化的监听的函数会立刻执行一次
    //底下书写的监听VM->属性名字【VM身上没有这个响应式属性,监听不到的】
    //函数写法
    // keyword(){
    //   console.log('我能监听到keyword关键字发生变化,只有关键字发生变化立刻执行一次');
    // } 

    //对象写法
    keyword:{
       //如果是对象的写法,通过handler办法监听属性值的变动
       //函数的名字不能瞎写 
       handler(){
           console.log('VM响应式属性值发生变化');
       }
    }
 }
<script>
    //关联VM
    const VM = new Vue({
        el: '#app',
        data: {
            a: {
                b: {
                    count: 1,
                    msg:'我爱你'
                }
            }
        }
        ,
        watch: {
            //监听VM属性,VM身上有的响应式属性a,[b,count只是这个a属性的属性值]
            //为什么监听不到:因为对象a的属性值,是一个对象【内存地址素来没有变动过,也就是数之没有产生过变动】
            //因而监听不到
            // a(){
            //     console.log('我爱你塞北的雪');
            // }

            //deep,深度监听。尽管a的属性值对象没有发生变化,只有a的属性值发生变化就能检测到数据变动
            a: {
                // immediate:true,//如果加上immediate属性,不论你属性值有没有发生变化,上来立刻执行一次监听。
                deep:true,//深度监听,只能在对象写法当中呈现
                handler() {
                    console.log('监听count变动');
                    //监听属性函数外面能够书写异步语句
                    setTimeout(()=>{
                       this.a.b.msg = '我是祖国的花骨朵'
                    },2000);
                }
            }


        }
    });

    //watch监听,监听的是VM身上响应式属性的属性值的变动->VM身上的属性
</script>

生命周期

4->2->2
beforeCreate:VM未实现齐全的初始化【不能获取VM的属性、办法】
created:VM齐全初始化结束了【能够获取属性、办法】
beforeMount:VM挂载之前
mounted:VM挂载结束*[构造曾经残缺,能够获取DOM节点]

beforeUpdate:VM响应式属性发生变化之前
updated:VM响应式属性值发生变化当前

beforeDestroy:VM销毁之前
destroyed:VM销毁*

//生命周期函数:全副的生命周期函数中最先执行的beforeCreate钩子函数
//VM残缺的初始化未结束
beforeCreate() {
    //这个钩子this->VM(初始化配置还未结束),在这里获取不到VM属性|办法
    console.log('初始化阶段:beforeCreate', 'VM未实现初始化');
},
//VM初始化结束了
created() {
    //VM初始化结束,能够获取属性、办法等等能够获取到了
    console.log('初始化阶段:created', 'VM初始化结束', this.count);
},
//VM挂载之前会执行一次
beforeMount() {
    //this->VM
    //以后钩子能够获取VM属性、办法,获取不到实在DOM节点.
    console.log('初始化阶段:beforeMount', 'VM挂载之前执行一次', this.count);
}
,
//VM挂载结束了*****
//mounted是比拟重要的一个钩子函数,咱们当前比方发申请axios.get|axios.post|axios({})都在这里书写
mounted() {
    console.log('初始化阶段:mounted', 'VM挂载结束', this.$refs.cur);
}
,
//更新阶段:当VM的响应式的数据发生变化的时候会触发一次
beforeUpdate() {
    console.log('更新阶段:beforeUpdate',this.count);
}
,
//更新阶段:当VM的响应式数据发生变化之后触发一次
updated(){
   console.log('更新阶段:updated',this.count);
}
,
//VM销毁之前
beforeDestroy(){
   //this->VM
   console.log('销毁阶段beforeDestroy')
}
,
//VM销毁结束:解决后事,比方后面开启定时器、销毁时候清革除定时器!!!
destroyed(){
  console.log('销毁阶段destroyed');
}
});

//Vue生命周期函数
//初始化阶段:beforeCreate、created、beforeMount、mounted--->会执行一次
//更新阶段:beforeUpdate、updated->当VM的响应式的数据发生变化的时候,会执行
//销毁阶段: beforeDestroy、destroyed!!!!!



//VM销毁并不是说,视图看不见了,VM还是能够拜访到,然而它'不工作了'!!!!

响应式数据数组和对象的注意事项

VM身上的属性->对象的写法【都是响应式数据】

               ->数组的写法,数组外面的元素可能是响应式、不是响应式的

如果数组外面的元素不是响应式,Vue框架就做不到数据发生变化,视图跟着变动。
一种:数组变更
unshift、shift、push、pop、splice、reverse、sort
二种:数组的替换
利用新的数组替换原始数组:map、filter、slice等等办法都能够应用,因为这些办法都会返回一个新的数组

const VM = new Vue({
     el:'#app',
     data:{
         name:"曹操",
         age:18,
         sex:'男',
         hobby:['吃饭','睡觉','打豆豆'],
         arr:["我爱你",123,{name:'豪哥'},true]
     },
     methods: {
         //更新性别
        updateSex(){
           this.sex = '女'; 
        },
        //更新喜好
        updateHobby(){
           //将睡觉变为游戏
           //这种写法是谬误的:hobby是响应式属性,然而hobby右侧数组外面元素 吃饭 、睡觉、打豆豆并非是响应式
                         //this.hobby[1] = '游戏';
           //因而数据变动了,视图不会更新



           //数组检测伎俩----变更办法(7个葫芦娃)
           //shift、unshift、push、pop、splice、sort、reverse->对于起始数组都是有影响的
           //this.hobby.reverse();
           //this.hobby.unshift('喝酒');
           //this.hobby.splice(1,1,"喝酒");


           //替换:利用的新的数据替换原始的数组【Vue框架也能检测到数据变动达到响应式】
           //this.hobby = ['吃饭','喝酒','打豆豆'];
           //数组map、filter、slice都会返回一个新的数组
           this.hobby = this.hobby.map(item=>item=='睡觉'?'游戏':item);
        },
        handle1(){
            //arr,是一个响应式属性,数据变动视图跟这边
            //数组外面的元素 我爱你、123、布尔值true,并非是响应式的数据,尽管批改数据,然而视图不跟着更新
            //这三者只能用数字组的变更(七个)、替换伎俩
            // this.arr[0] = '我恨你',这种形式不会更新视图
            //通过控制台查看数组外面元素{name:'豪哥'},这玩意是响应式的。数据变动视图跟着变动
            this.arr[2].name = '1126';
        }
     }
 });
 
 //真的很重要:你在data当中定义对象都是响应式的。数组外面元素有可能是响应式【对象】、有可能不是响应式的【数字、字符串、布尔值:数组套路变更、替换】
//响应式数据:VM身上的属性值发生变化,视图跟着变动。

单文件组件和非单文件组件

单文件组件:一个文件即为一个组件,这个文件的尾缀.vue文件
非单文件组件:一个文件外面能够定义多个组件,这个文件能够是.html文件

组件的根本应用

//组件:component
//组件:复用的【代码 + 资源(图片、款式、视频)】汇合在一起即为组件!
//Vue框架中从书写角度登程:分为两大类组件
//单文件组件:一个文件即为一个组件,这个文件的尾缀务必是.vue
//非单文件组件:一个文件外面,能够定义多个组件,这个文件尾缀.html
//el配置项:只有new Vue构造函数初始化VM实例才能够应用,el配置项只能呈现一次!!!
//组件不须要书写el配置项!!!!
//组件的 Data的配置项b函数写法
<script>

    //Vue组件应用分为三步骤:
    //第一步:定义
    //第二步:注册
    //第三步:应用

    //定义一个组件:利用的是Vue.extend办法去定义组件
    //extend办法外面也须要传递配置对象,extend配置对象与Vue配置对象简直截然不同!!!
     
   //组件:作为Count子组件

   let Hello = Vue.extend({
          template:"<h1>我是Hello组件</h1>",
          mounted(){

          },
          watch:{

          },
          computed:{
              
          }
   })


    let Count = Vue.extend({
         components:{Hello},
        //组件的本身的数据
        data() {
            return { count: 1 };
        },
        //组件的构造:模板字符串才能够换行 ,双引号字符串不能换行
        template: `
            <div class="box">
                <Hello></Hello>
               <button @click="minus">-</button>
               <span>{{count}}</span>
               <button @click="add">+</button>
            </div>
            `
        ,
        methods: {
            add() {
                this.count++;
            },
            minus() {
                this.count--;
            }
        }
    });



    let Big = Vue.extend({
        data() {
            return { f: 16 }
        },
        template: `
             <div class="box1">
                <p :style="{fontSize:f+'px'}" @click="f++">路是脚踏进去的,历史是人写进去的</p>
             </div>
           `
    })

    //关联VM
    const VM = new Vue({
        el: '#app',
        data: {

        },
        //VM要注册本人想要应用的组件
        components: {
            //注册组件的时候,在应用组件的时候用的K的名字,并不是V
            Count,
            Big
        }
    });


    //总结:第一,组件的应用分为三步。
    //第一步:定义,须要通过Vue.extend办法进行定义。[extend外面配置项与Vue配置项简直截然不同] 
    //不能书写el、组件的响应式数据务必比是函数写法


    //第二步:注册。某一个中央须要组件,进行注册。在components配置项进行注册


    //第三步:应用。【是以自定义标签的模式应用,首字母个别大写】

</script>

版本阐明

Vue依赖包:尤雨溪团队,给开发人员提供很多版本的依赖包 【残缺版本、压缩版本、运行时版本】

全局组件

全局组件的应用:只须要定义一次,能够在任意组件中间接应用。就不必每一次都在注册了。

全局组件个别在这种状况下才会应用:我的项目当中很多中央(组件),大家频繁应用某一个性能,你就能够把这个性能封装为全局组件,定义一次,能够在任意中央间接应用【不须要引入、不须要注册】间接应用。

//定义一个组件
const Carousel = Vue.extend({
    data(){
        return {info:'我是轮播图组件,而且我还是全局组件'};
    },
    //构造编辑器
    template:`
       <h1>{{info}}</h1>
    `
});

Vue.component("Erha",Carousel);
//定义为全局组件 :定义一次,能够在任意中央间接应用,不须要注册。
//第一个参数:全局组件的名字(字符串)  第二个参数:组件(不能书写为字符串)

//全局组件个别在这种状况下才会应用:我的项目当中很多中央(组件),大家频繁应用某一个性能,
//你就能够把这个性能封装为全局组件,定义一次,能够在任意中央间接应用【不须要引入、不须要注册】间接应用。

VM与组件的关系

Vue框架中组件,本质是Vue.extend函数返回的构造函数VueComponent

组件:即为构造函数VueComponent,Vue.extend函数返回的后果【构造函数】

组件外面this并非是VM(Vue类的实例),组件实例是VueComponent类的实例,只不过VueComponent构造函数不是咱们本人调用的,

组件实例身上属性与Vue类的实例VM很类似。组件外面this是VueComponent类的实例,(简称VC);

组件实例能够借用Vue.prototype的办法,震惊三观!!!

VC[组件的实例]原型的原型指向的Vue.prototype
VC.__proto__.__proto__===Vue.prototype

创立组件的简写形式

<script>
    //创立组件:定义、注册、应用
    //上面的写法是Vue.extend简写形式,间接书写配置项即可。
     let App = {
           //组件name配置项,对于组件的应用没有任何影响,只不过name配置项,会影响到开发者工具外面审查组件的显示名字而已。
           name:'Erha',
           data(){
               return {name:'豪哥你真帅,臭不要脸'};
           },
           template:`
              <div>
                 <h1 @click="handler">{{name}}</h1> 
              </div>
           `,
           methods: {
               handler(){
                   this.name = '豪哥爱你们1126';
                   console.log(this);
               }
           }
     }

     //关联VM
     const VM = new Vue({
         el:'#app',
         template:`
           <App></App>
         `,
         components:{
            //注册组件的时候K,决定了组件在应用的时候,这个标签名字
            //开发者工具中审查组件的时候,也是显示K 
            App:App
         }
     })
</script>

Vue脚手架

小提示:
ES5与ES6模块的引入与裸露肯定要把握。

简介

脚手架->vue-cli
vue框架中也存在脚手架’工具’,能够辅助你疾速开发我的项目。应用脚手架工具之前,电脑当中须要装置脚手架工具。

1.1装置脚手架工具。利用npm|yarn工具装置脚手架性能。
脚手架工具官网地址:https://cli.vuejs.org/zh/guide/
npm install -g @vue/cli 这是装置vue脚手架指令
舒适提醒:关上CMD命令行 输出vue -V 打印出5.0.4版本代表装置脚手架工具胜利。

Vue.js:框架版本 1 2 3
vue/cli:工具[脚手架版本] 1 2 3 4 5

脚手架工具的应用.

vue/cli脚手架工具:它次要的作用是能够疾速创立Vue根本构造。怎么疾速创立Vue我的项目构造。

第一步:找到一个文件夹(未来搁置我的项目中央),关上CMD命令,输出【vue create 我的项目的名字】

第二步:抉择提醒第二项 Default(vue2 babel,eslint),这代表的是装置Vue框架2.xxx版本
(babel:将ES6->ES5,eslint:语法测验器)

第三步:怎么运行,找到package.json文件,查看script这个K
“scripts”: {

"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"

},

npm run serve :以后我的项目在本地服务器8080运行起来
npm run build:我的项目完事了,我的项目打包给后盾用这个。->dist
npm run lint:也是本地运行,把webpack一些暗藏的配置项裸露进去。
我的项目运行的注意事项:在我的项目根目录下输出npm run serve

意识意识脚手架目录。

node_modules文件夹:搁置的是我的项目依赖的文件夹

public文件夹:public个别搁置动态资源【HTML|CSS|图片等等】,这个文件夹外面的动态资源,在打包的时候,
会一成不变的打包到dist文件夹外面.
舒适提醒:<%= BASE_URL %>,webpack曾经给你配置好了,就是public文件夹

src文件夹:src文件夹程序员文件夹,当前书写代码都是在src文件夹外面搞。
assets文件夹:也是搁置动态资源的文件夹,assets文件夹外面个别搁置的是组件共用的动态资源,assets文件夹外面的动态资源,在打包的时候,会当中webpack一个模块,打包到JS文件夹外面。

main.js:入口文件,是你整个我的项目最先执行的中央,个别初始化一个VM。
App.vue:整个我的项目根组件
components文件夹:搁置组件的中央

.gitignore文件:git疏忽文件 配置文件很少触碰
babel.config.js:以后这个文件babel’翻译官’配置文件。很少触碰
jsconfig.json文件:它也是一个配置文件。给src文件夹起一个别名。
在你的我的项目当中能够应用@符号,代表的是src文件夹。
目前而言@个别在JS区域书写(其实也能够在css区域书写)

//  @代表是src文件夹,相当于给src起了一个别名。 
//当前在开发大型项目的时候常常用到找src文件夹外面文件关系的。
import MyComponent1 from '@/components/MyComponent1'
import MyComponent2 from '@/components/MyComponent2'

package.json文件:记录我的项目名字、我的项目版本号、我的项目如何运行、我的项目依赖有哪些。

package-lock.json记录依赖下载地址,再次下载依赖的时候,间接从电脑缓存中获取依赖。

readme.md:这玩意不是笔记,我的项目说明书。比方如何装置依赖、比方运行。

vue.config.js文件:能够当做webpack.config.js
举例子:通过webpack代理解决代理跨域问题,就在这个文件外面操作。

启动我的项目后,主动关上浏览器

第一步:

在package.json中增加 –open

  "scripts": {
    "serve": "vue-cli-service serve --open",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  }

第二部:

在vue.config.js文件中增加配置项

{
  transpileDependencies: true,
   //敞开eslint校验工具
   lintOnSave:false,
  //浏览器弹出URL设置
  
    devServer:{
       host:'127.0.0.1',
       port:'8080'
    }
 
}

面试题:scoped

scoped:英文含意范畴
scoped不增加:代表以后组件外面的款式是全局款式(全副的组件都会受到影响)
scoped增加上:代表以后组件内的款式,部分款式,只对于以后组件失效。
咱们当前开发我的项目的时候,大多数状况下都会加上scoped,因为组件款式互相不影响。
目前脚手架默认反对css款式,默认不反对less|scss写法【未来能够】

面试:public与assets文件夹区别?

public文件夹:个别搁置一些动态资源【html、css、图片等等】,放在public文件夹中的动态资源,webpack在打包的时候,会把这些动态资源一成不变打包到dist文件夹中。

src文件夹下的 assets文件夹:它也是搁置动态资源的文件夹,个别搁置组件共用的动态资源(比方1000个组件都应用同一个图片),assets文件夹外面的动态资源,webpack在打包的时候,会把动态资源当作一个模块打包到js文件夹外面。

vue-cli脚手架其余配置项。

vue-cli脚手架的确不便咱们开发、学习Vue。然而有一些细节操作须要整整。
我的项目执行npm run serve命令后, 浏览器是不是本人主动关上。
第一步:找到package.json文件,在serve前面加上 –open(代表浏览器主动关上)
“scripts”: {

"serve": "vue-cli-service serve --open",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"

},
发现:浏览器的确主动关上了 http://0.0.0.0:8080/ 在这个URL上拜访不到我的项目。

第二步:
第一种解决方案:批改脚手架源码.
node_modules/@vue/cli-service/lib/commands/serve.js—->源码文件

serve.js源码批改
const defaults = {
host: ‘127.0.0.1’,
port: 8080,
https: false
}

第二种解决方案:
在vue.config.js文件中新增配置项

devServer: {

host: ‘127.0.0.1’,

port: 8080,

https: false,

}

把eslint校验工具敞开
举例子:申明一个变量,然而没有应用,我的项目会在顶上弹出一个遮罩层,让你无奈观看我的项目。

第一步:找到vue.config.js文件,进行配置敞开eslint校验工具.
新增配置项,即可敞开eslint工具。
lintOnSave:false

vscode插件的装置!!!
Vetur插件:语法提醒、组件格式化、组件观看起来难看
vue-beautify:让你的组件难看
vue-helper:element-ui组件提醒的插件

插件:疾速生成组件模板 vue
配置项:都是一V结尾的

父子组件通信props

父组件给子组件传递数据,能够利用props实现【自定义属性】,
子组件的接管到的props是只读的(只能用不能批改),数据来自于谁,用谁的办法进行批改。

子组件接管父组件传递过去的数据

第一种写法:数组写法,数组外面书写的是自定义属性的名字

props:["car",'money','changeAppMoney']

第二种写法:对象写法[算两种写法,然而都是对象写法]

//对象的这种写法能够束缚props数值类型
  props:{
      //承受的是props名字
      msg:{
        //束缚这个属性的属性值
        //字符串:String 数字:Number  数组Array  对象Object  函数Function
        type:String,
        default:"abc",//设置初始值,然而父组件传递了,初始值生效
      }
  }
  
  //简写
  props:{
     todos:Array,
     a:String
}

props:父子组件通信,次要做的事件,父组件给子组件传递数据!!!!!
第一种:并非函数状况
父组件给子组件的数据:数组、字符串、对象等等
第二种:函数
父组件给子组件传递函数:父组件给子组件传递数据【函数:props】,本质不就是儿子给爹传递数据吗?

面试题:h5新增了哪些个性?

在HTML5【超文本标记语言第五次重大批改当中】
结构层:新增的语义化标签:main、header、footer等等,视频(video)、音频(audio)等等
款式层:2D、3D动画、flex等等

行为层:浏览器存储性能(本地存储,会话存储),canvas画布

浏览器的存储分为两大类:

本地存储:利用localStorage对象实现浏览器浏览器长久化存储j数据

会话存储:利用sessionStorage对象,会话存储应用的语法,与本地存储简直截然不同

浏览器本地存储

本地存储性能:浏览器存储性能之一,本地存储,能够实现浏览器【长久化】存储数据。
浏览器存储性能个别存储字符串类型的数据!!!!

思考问题:开发当中,JSON、数组怎么存储?

答:如果你想存储援用类型的数据:套路先把它变为字符串->存储 JSON.stringify

                    读取的时候再把字符串转换援用类型->读取 JSON.parse

面试: 本地存储有哪些个性:

第一:本地存储个别存储字符串
第二:援用类型数据须要转换为字符串进行操作
第三:浏览器本地存储性能,存储数据是有下限5M左右!!!!
第四:本地存储长久化存储数据,电脑关机、网页敞开,只有步本人手动删除,存储一辈子!!

会话存储特点:
1会话存储存储数据并非长久化,电脑关机、网页敞开,会话存储数据隐没!!!
2:会话存储,存储数据也是有下限的大概5M

代码如下:

//浏览器存储性能之一:本地存储,是通过localStorage对象实现的!!!本地存储数据个别存储的是字符串。

//本地存储存储数据实现 第一个参数:相当于K  第二个参数:相当于V
//长久化存储数据:电脑关机重启数据也在或者把网页敞开也在!!!
//存储性能:如果K一样,后者笼罩前者
//localStorage.setItem("todo",'我是本地存储性能,个别存储字符串');
//localStorage.setItem("todo1",'我是小明,我很帅');

//读取:读取的时候,通过K,获取相应存储的V
//读取浏览器存储数据的时候,如果没有存储过的K,获取数据为null
//   let result = localStorage.getItem("todo");
//   let result1 = localStorage.getItem('todo1');
//   console.log(result);
//   console.log(result1);


//删除本地存储的数据
//删除本地存储数据:通过K移出相应的V
// localStorage.removeItem('todo');

//开发当中咱们个别存储:JSON、数组。
//先把援用类型的数据,转换为字符串进行存储
let todo = ['我爱你','塞北的雪','鲁班七号挺猛'];
let obj = {a:1,b:2};
//本地存储:存储援用类型的数据,先把他们转换为字符串
localStorage.setItem('data',JSON.stringify(todo));
localStorage.setItem('data1',JSON.stringify(obj));


//读取:JSON.parse,能够把字符串转换为援用类型的数据
let result = JSON.parse(localStorage.getItem('data'));
let result1 = JSON.parse(localStorage.getItem('data1'))
console.log(result,result1);

自定义指令

Vue官网提供的指令:

v-bind

v-on

v-model

等等

Vue框架反对程序员本人去定义一个指令:举例;自定义一个upper指令

    <!-- 在应用的时候切记:别忘记后面v- -->
    <h1 v-upper="msg"></h1>

部分指令

//新增一个配置项directives
directives: {
  //书写的时候,不须要书写v-.  应用的时候:v-upper
  //当程序员应用v-upper指令的时候会执行一次!!!
  // upper(element,options){
  //   //element形参:以后绑定指令的实在的DOM节点
  //   //options形参:以后指令一些配置项参数【对象】
  //   //自定义指令:本质能够获取到实在DOM节点,操作DOM节点!!!
  //   element.innerHTML = options.value.toUpperCase();
  // }
},

全局指令:在main.js中定义全局指令

//定义全局自定义指令。只须要定义一次,在任意组件都能够间接应用!!!
//第一个参数:自定义指令名字【定义的时候不须要带v-xxx】
//第二个参数:回调函数[当在某一个VC,当中应用指令的时候会执行一次]
Vue.directive('upper',(element,options)=>{
      console.log(element);
      //element:是你绑定指令的DOM节点!!!!
      element.innerHTML = options.value.toUpperCase();
});

过滤器

<!-- 底下语法:常常叫做'管道' -->
<h1>{{ time|timeFormat }}</h1>

部分过滤器

  //部分过滤器:在哪个组件定义的,就在哪个组件应用!!!!
  filters: {
     //定义一个过滤器
     //当模板中应用过滤器的时候,底部函数会执行一次
     //过滤器函数须要有返回值,返回值即为格式化后果
     //params第一个参数:须要格式化数据,就是管道后面的表达式存储数值!!!
    //  timeFormat(params){
    //      return moment(params).format('YYYY-MM-DD');
    //  }
  },

全局过滤器

//定义一个全局的过滤器
//第一个参数:是过滤器的名字
//第二个参数:是回调函数。【当你应用这个过滤器的时候,会执行一次】
Vue.filter("timeFormat",(val)=>{
     //val:须要格式化的数据
     //回调函数返回的后果即为格式化数据
     return moment(val).format('YYYY-MM-DD');
});

自定义插件

在Vue框架中,Vue官网团队给咱们提供很多插件。
element-ui插件(相似React中的 antd)
vue-router插件(相似react-router)
vuex(相似于redux)
尝试本人封装Vue框架中的插件性能:Vue框架中插件次要的目标,给你的Vue我的项目增加全局的性能。

舒适提醒:装置插件务必应用Vue.use办法装置插件!!!
舒适提醒:插件是一个JS对象,务必要install办法,当装置插件的时候Vue.use,会主动调用install办法
舒适提醒:插件的装置务必在初始化VM之前调用!!!!

在src目录下新建一个文件夹plugins,在plugins下新建element.js文件

element.js代码如下:

//开发本人定义(封装的)插件。插件的目标是给我的项目提供全局的性能!!!!
//定义一个对象:以后对象即为插件对象
//引入moment
import moment from 'moment';
let plguins = {
  //肯定要留神:插件对象身上务必要有install办法
  //当我的项目应用插件的时候->Vue.use().当插件被应用的时候,插件对象的install办法会执行一次
  install(Vue, options) {
    //第一个参数:Vue构造函数(初始化VM、全局组件、全局指令、全局过滤器)
    //第二参数:Vue.use(plugins,1000),将1000赋值给options

    //本人开发最简略的插件
    //提供全局的自定义指令
    Vue.directive('upper', (element, options) => {
      element.innerHTML = options.value.toUpperCase();
    });

    //全局过滤器
    Vue.filter('timeFormat', (value) => {
      return moment(value).format('YYYY-MM-DD');
    });

    //全局组件
    // Vue.component();

    //全局性能
    Vue.prototype.$erha = function () {
       alert('二哈咬人');
    }

  }
}


//对外裸露:别的模块要应用
//默认裸露
export default plguins;

在main.js中装置插件

import Vue from 'vue'
import App from './App.vue'

//入口文件引入插件【默认对外裸露一个对象】
import plugins from './plugins/element';

//如果你想让你的我的项目应用这个插件性能:须要给我的项目装置插件->Vue.use办法装置插件!!!
//上面的代码:代表的含意是,给你的我的项目装置插件!!!!
//Vue.use(plugins)插件对象的install办法会执行一次。

//小留神:装置常见切记在new VM之前装置插件!!!!
Vue.use(plugins, {
  name: 'upper'
});


new Vue({
  render: h => h(App),
}).$mount('#app');


自定义事件

定义事件

<!-- 
      自定义事件,程序员本人定义的事件!!!

      事件源:MySon组件标签
      事件类型:erha(自定义类型)
      事件的回调函数:handler
      自定义事件回调外面没有event;
      怎么触发自定义事件:在事件源(组件)外部通过$emit办法手动触发自定义事件!!!!
    -->
 <MySon @erha="handler"></MySon>
export default {
  name: "",
  components: {
    MySon,
  },
  //父组件王健林的办法
  methods: {
    handler(params1,params2) {
       //自定义事件回调外面没有event;
       console.log('爸爸组件',params1,params2);
    },
  },
};

自定义事件的骚操作

  //当组件挂载结束执行一次----mounted
  mounted(){
     //$on|$emit都是Vue.prototype原型对象的办法:vm能够应用,vc能够应用!!!
     //上面的代码代表含意是:给事件源MySon1组件实例绑定一个自定义事件car
     //第一个参数:自定义事件名字    第二个参数:自定义事件的回调
     this.$refs.cur.$on('car',(params)=>{
         console.log(params);
     })
   
  }

触发事件

export default {
  name: "",
  methods: {
    clickHandler(){
       //VC的原型的原型【Vue.prototype】身上领有$emit办法。
       //能够触发自定义事件
       //第一个参数:自定义事件的类型
       //第二参数当前:注入到事件回调的参数
       this.$emit("erha",'王思聪给你一个亿','王思聪怼央视新闻');
    }
  }
};

自定义事件总结:

1、上面这种写法是自定义事件简写模式.
<MySon @erha=”handler”></MySon>
this.$emit(“erha”,’王思聪给你一个亿’,’王思聪怼央视新闻’);

2、自定义事件残缺写法

事件源.$on(‘erha’,(params)=>{});

事件源.$emit(‘erha’,’一个亿’)

面试题:开发我的项目的时候,组件通信形式接触过多少种?(11种伎俩)

1、props能够实现父给子传递数据。【父->子】
2、自定义事件,能够实现儿子给父亲传递数据【子->父】

3.全局事件总线

全局事件总线

利用的就是Vue.prototype原型对象的$on,$emit实现的。

//Vue原型对象身上增加一个新的属性
//相当于在Vue.prototype原型对象的身上挂载一个Vue类的实例【VM:$on、$emit】
//VC都能够通过原型链找到雷同的属性值【事件源】

在main.js中配置全局事件总线

new Vue({
  //生命周期函数
  beforeCreate(){
     //配置全局事件总线,在Vue的原型上增加$bus属性,属性值为VM【Vue类的实例】
     //底下的this,并非是VC,是VM【Vue类的一个实例】
     Vue.prototype.$bus = this;
  },
  render: h => h(App),
}).$mount('#app');

触发事件

//上面事件源:都是Vue类的实例VM,并非VC
this.$bus.$emit('money',30000);

绑定事件

  //组件挂载结束
  mounted(){

     this.$bus.$on('money',(money)=>{
         console.log('爷爷'+money);
     })

  }

代理服务器

在vue.config.js增加配置

  devServer: {
    proxy: {
      '/erha': {
        target: 'http://localhost:9999',
        pathRewrite: { '^/erha': '' },
      },
    },
  }
  
//erha:如果你的我的项目当中,申请的地址带/erha,代理服务器才会帮你做事!!!!
//target:获取数据那台服务器地址  【书写到端口号即可】
//pathRewrite:门路重写

重启我的项目,因为配置项发生变化

留神:发申请后面须要加上/erha

对axios进行二次封装

通常会在src文件夹下,新建一个api文件夹,新建request.js文件

//对于axios模块进行二次封装!!!
//须要引入axios
import axios from "axios";

//进度条的业务
import nprogress from 'nprogress';
//应用进度条的时候,须要把人家的款式引入!!
import "nprogress/nprogress.css";

//申请拦截器:当你申请的时候触发(服务器没有做出响应)!
axios.interceptors.request.use((config) => {
    //申请拦截器
    //config配置对象,身上有一个很重要货色,申请头****
    console.log('捕捉到发申请');
    //进度条开始动
    nprogress.start();
    return config;
}, (error)=> {
    // 对申请谬误做些什么
    return Promise.reject(error);
});

//响应拦截器:当服务器数据响应胜利触发!
axios.interceptors.response.use((res) => {
    //响应胜利
    console.log('捕捉到申请胜利');
    nprogress.done();
    //个别咱们会简化服务器返回的数据【因为服务器返回的数据个别须要的data:右侧数据】
    return res.data;
}, (error) => {
    nprogress.done();
    //响应失败
    
    return Promise.reject(error);
});


//对外裸露axios
export default axios;

node相干知识点

express是node的一个框架

koa[也是node平台搭建服务器用的,是express降级版本]

面试题:在工作时候有没对axios进行二次封装!!!二次封装你次要干什么?

答:咱们工作的时候常常对于axios进行二次封装,次要给axios增加申请、响应拦截器!!

面试题:什么是跨域?解决跨域的伎俩有哪些?

Vuex

vuex也是一个插件,插件的作用:提供一些全局性能!

装置

npm i –save vuex@3

单词

dispatch->公布、差遣

commit->提交

actions->口头

mutations->扭转

state->状态

vuex外围概念

actions->口头(能够书写业务逻辑的中央,比方if判断、异步语句等等)

mutations->扭转(惟一能够批改仓库数据的中央)
state->状态(仓库存储数据的中央。组件实例能够应用)

getters:仓库的计算属性

应用步骤

1、在src文件夹下创立一个文件夹store,在store文件夹中新建index.js文件

//当前store文件夹外面index文件,就是与vuex仓库相干的文件!!!
import Vue from 'vue';
//引入vuex插件,vuex插件对外裸露是一个对象【插件对象:install办法】
import Vuex from 'vuex';
//应用插件:Vue.use();
Vue.use(Vuex);

//创立咱们仓库
//Vuex插件对象,身上有一个Store办法,它是一个构造函数。执行会返回一个Store类的一个实例【仓库】
let store = new Vuex.Store({
    //存储数据的中央
    state: {
        count: 1,
        hobby: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    },
    //是惟一能够批改state外面数据中央
    mutations: {
        //惟一批改批改数据的中央
        //第一个参数:state即为以后仓库的数据
        ADD(state) {
            state.count++;
        }
        ,
        MINUS(state) {
            state.count--;
            //this即为以后仓库,Store类的实例,就是不必!!
        },
        ADDNINE(state, payload) {
            state.count += payload;
        },
        UPDATECOUNT(state,payload){
            state.count = payload;
        }
    },
    //书写业务逻辑,比方书写if、异步语句等等。然而这里不能间接批改数据!!!
    actions: {
        //解决add类型的action
        //miniStore就是一个对象(小仓库)领有的办法根本与Store类的实例截然不同!!!
        add({ commit, state, dispatch }) {
            //生存例子:相当于add这个办公室这个人,曾经批准这次申请【呈现commit】
            //这次批准人家通知你了,找叫做ADD这个工人去解决这个批改!!!
            commit("ADD");
        },
        //解决minus类型的action
        //commit:提交mutation办法
        //state:即为以后仓库存储的数据
        //dispatch:派发小弟用的办法
        minus({ commit, state, dispatch }) {
            commit("MINUS");
            //this即为以后仓库:Store类的实例。在vuex中不必this
        },
        evenAdd({ commit, state, dispatch }) {
            //生存例子:这次办事,并不是立马就许可了。有条件了【业务判断】
            if (state.count % 2 == 0) {
                commit('ADD');
            } else {
                console.log('不符合条件,临时不解决');
            }

        },
        oddMinus({ commit, state, dispatch }) {
            if (state.count % 2 != 0) {
                commit("MINUS")
            } else {
                console.log('不符合条件,不受理');
            }
        },
        //第一个参数:miniStore小仓库
        addNine({ commit, state, dispatch }, payload) {
            //相当于(批准):你去找名字ADDNINE这个工人,携带一些信息【信外面:VC让我给你带的信息】
            commit("ADDNINE", payload);
        }
        ,
        //delayAdd类型的action
        delayAdd({ commit, state, dispatch }) {
            //能够书写异步语句
            //异步语句:定时器、提早器、ajax、promise等等
            setTimeout(() => {
                commit("ADD");
            }, 2000);

        },
        updateCount({commit,state,dispatch},payload){
             commit('UPDATECOUNT',payload);
        }
    },
    //了解为仓库中的计算属性
    getters: {
        //state,即为仓库中的数据
        total(state) {
            //留神:getters外面的函数this->undefined
            //这里即为计算属性,服侍仓库,利用已有的属性与属性值,造出一个新的属性与属性值!!!!
            return state.hobby.reduce((a, b) => a + b, 0)
        }
    }
});
//对外裸露仓库:裸露的仓库到底是什么鬼?
//裸露的仓库本质即为Store类的一个实例而已!!!
export default store;

2、在main.js中减少store配置项

import Vue from 'vue'
import App from './App.vue'
//仓库曾经建设好了,应用仓库性能!!!
import store from '@/store';
new Vue({
  render: h => h(App),
  //这行代码代表含意是:我的项目当中应用仓库性能,给每一个VC实例身上增加$store属性.【让VC与仓库进行关联】
  store,
}).$mount('#app')

3、应用

<template>
  <div>
    <h1>计数器:{{count}}</h1>
    <h2>getters计算属性的数据简单的写法:{{total}}</h2>
    <h1>{{hobby}}</h1>
    <button @click="add">点击我加上1</button>
    <button @click="minus">点击我减去1</button>
    <button @click="evenAdd">点击我偶数加1</button>
    <button @click="oddMinus">点击我奇数减1</button>
    <button @click="addNine">点击我加上9</button>
    <button @click="delayAdd">点击我两秒之后加上1</button>
    <hr>
    <!-- 
       原生DOM也有这个事件:
       input:当文本框内容发生变化,立刻触发事件
       change:当文本框内容发生变化(点击空白的中央)才会执行!!!
     -->
    <input type="text" :value="count" @input="changeHandler">
  </div>
</template>

<script>
//vuex提供一些辅助性的函数,函数能够把仓库的数据增加组件实例!!
//mapState是vuex别离裸露的函数,须要传递数组|对象
//mapGetters是vuex别离裸露的函数,须要传递数组|对象
import { mapState,mapGetters} from 'vuex';
export default {
  name: "",
  methods:{
      //点击按钮加上1的回调函数
      add(){
         //生存例子:张三差遣一个小弟,通知他【去仓库办公室action,找到名字叫做add这个人,审批这次申请】
         //程序员:VC派发一个add类型的action
         this.$store.dispatch("add");
         console.log(this);
      },
      //点击减去1的回调函数
      minus(){
         //派发actions
         this.$store.dispatch('minus');
      }
      ,
      //偶数加上1
      evenAdd(){
         this.$store.dispatch('evenAdd');
      },
      //奇数减去1 
      oddMinus(){
         this.$store.dispatch('oddMinus');
      }
      ,
      //点击按钮加上9 
      addNine(){
         //派发action
         //第一个参数:vuex仓库外面的actions名字 
         //第二个参数:载荷【payload】,第二个参数起始就是VC组件实例给actions传递参数
         //没有第三个参数了
         this.$store.dispatch('addNine',9);
      }
      ,
      //两秒之后加上1的回调
      delayAdd(){
         //派发action
         this.$store.dispatch('delayAdd');
      },
      changeHandler(e){
          this.$store.dispatch('updateCount',e.target.value)
      }
  },
  //计算属性:利用已有的属性[$store]与属性值,发明出一个新的属性与属性值!!!
  //计算属性:缓存
  computed:{
      //数组外面书写的是state右侧对象的K,将仓库数据作为组件实例的数据!!!!
      ...mapState(['count','hobby']),
      ...mapGetters(['total'])
  },
};
</script>

<style scoped>
</style>

面试题:Vuex仓库存储的数据是否长久化?

不是长久化,我的项目从新运行,数据又复原初始状态

面试题:如何实现v-model操作vuex流程

利用表单元素的value 和input事件实现的

<input type="text" :value="count" @input="changeHandler">
  methods:{
      changeHandler(e){
          this.$store.dispatch('updateCount',e.target.value)
      }
  },
  computed:{
      //数组外面书写的是state右侧对象的K,将仓库数据作为组件实例的数据!!!!
      ...mapState(['count','hobby']),
      ...mapGetters(['total'])
  },

过渡动画成果

步骤:

第一步: 元素或者组件必须要用到v-if 或 v-show

显示:称之为进入状态

暗藏:称之为来到状态

第二部: 外层用transition全局组件包裹

第三部:写css

  1. v-enter:定义进入过渡的开始状态。在元素被插入之前失效,在元素被插入之后的下一帧移除。
  2. v-enter-active:定义进入过渡失效时的状态。在整个进入过渡的阶段中利用,在元素被插入之前失效,在过渡/动画实现之后移除。这个类能够被用来定义进入过渡的过程工夫,提早和曲线函数。
  3. v-enter-to2.1.8 版及以上定义进入过渡的完结状态。在元素被插入之后下一帧失效 (与此同时 v-enter 被移除),在过渡/动画实现之后移除。
  4. v-leave:定义来到过渡的开始状态。在来到过渡被触发时立即失效,下一帧被移除。
  5. v-leave-active:定义来到过渡失效时的状态。在整个来到过渡的阶段中利用,在来到过渡被触发时立即失效,在过渡/动画实现之后移除。这个类能够被用来定义来到过渡的过程工夫,提早和曲线函数。
  6. v-leave-to2.1.8 版及以上定义来到过渡的完结状态。在来到过渡被触发之后下一帧失效 (与此同时 v-leave 被删除),在过渡/动画实现之后移除。
/**进入阶段:**/
/**进入开始阶段:**/
/**进入定义动画阶段:**/
/**进入完结阶段:**/

脚手架中如何应用less?

第一步:npm i less less-loader –save

第二部:

<style scoped lang="less"></style>

在less中申明变量

<style scoped lang="less">
@color:red;
  .box{
    width: 400px;
    height: 200px;
    background: blue;
    h3{
      color:@color;
    }
  }
  .v-enter{
    opacity: 0;
  }
  .v-enter-active{
    transition: opacity 2.5s;
  }
  .v-enter-to{
     opacity: 1;
  }
</style>

Vue-router

后端路由的概念

后盾语言:Java、PHP、python、C++等等,在后盾当中他们也存在路由的概念。
K:即为地址栏的URL。
V:对应的中间件。
let express = require(‘express’);
let app = express();

app.get(‘/students’,(req,res)=>{

 res.send('我是字符串');

});
app.get(“/luban”,(req,res)=>{

res.send('鲁班常常挨揍');

})
app.listen(3000);

前端路由的概念

K:url

v:相应的组件

辨别两个单词

router:路由器

route:路由

vue-router的根本应用

配路由的时候分两个区域,导航区和展示区

提醒1:当前再我的项目中,路由组件个别搁置在pages|views文件夹中

提醒2:vue-cli工具(官网团队提供工具),倡议组件的名字【两个单词:首字母大写】,
如果eslint校验工具敞开,组件名字能够是一个字母【首字母大写即可】!!!

留神

Vue框架自身只是提供外围语法【指令、生命周期、计算属性、监听】。Vue框架本身是没有路由能力的。

vue-router最新的版本4【vue-router@4版本在vue-cli5】当中跑不起来。
装置vue-router插件的时候,升高版本,装置3版本。

须要装置插件npm i --save vue-router@3

步骤

第一步:配置我的项目路由

当前我的项目配置路由,须要在src/router文件夹中,在router文件夹下新建index.js

//配置路由
//引入vue-router插件:通过打印查看,引入进来的VueRouter构造函数
//vue根底学习构造函数:Vue、VueComponent、Vuex.Store、VueRouter
import VueRouter from 'vue-router';
import Vue from 'vue';
//装置插件
Vue.use(VueRouter);
//引入路由组件
import Home from '@/pages/Home';
import About from '@/pages/About';

//配置我的项目的路由
//通过VueRouter【路由器】类,创立了一个VueRouter类的一个实例!!!
//对外裸露
export default new VueRouter({
    //配置项的K是没有磋商的余地[route:路由]
    routes: [
        {
            //path设置路由的K,path有的属性值务必都是小写的(设置path右侧V的时候,别忘记反斜杠)
            path: "/home",
            //component设置路由的V,一个K对应一个V
            component: Home
        },
        {
            path: '/about',
            component: About,
            children: [
                {
                    //第一种写法:门路书写全面,把上一级的门路带上
                    // /home/news      news 
                    path: 'news',
                    component: News
                },
                {
                    //第二种写法:起一个子路由的名字即可【后面页不须要带/】
                    // /home/message    message
                    path: 'message',//相当于->/home/message
                    component: Messaage,
                    children: [
                        {
                            //命名路由,给路由起一个名字
                            name:"erha",
                            //动静路由务必传递两个params参数
                            path: 'detail/:id/:name',
                            component:Detail
                        }
                    ]
                }
            ]
        }
    ]
});

第二步:在main.js中引入、注册路由

import Vue from 'vue'
import App from './App.vue'

//引入路由,并且注册路由
import router from '@/router';
new Vue({
  //注册路由:通过配置项router设置【K:不能瞎写、不能胡写、不能乱写】
  //注册路由这行代码作用:注册路由性能,能够给全副VC实例身上增加$router|$route属性
  router,
  render: h => h(App),
}).$mount('#app')

第三步:应用

<!-- 导航区域 -->
  <div class="col-xs-2 col-xs-offset-2">
    <!-- 导航链接:能够设置K的数值,导航链接通过【vue-router插件提供的】全局组件router-link实现-->
    <!-- 导航链接:务必要有to属性 -->
    <router-link class="list-group-item" to="/about">About</router-link>
    <router-link class="list-group-item" to="/home">Home</router-link>
  </div>
  <!-- 展示区:展现的内容 home|about路由组件-->
  <!-- 路由组件进口的中央:路由组件在哪里展现 -->
  <!-- 
    展现区域:展现路由组件的区域(中央),router-view,它也是Vue-router提供的一个全局组件
    它的作用是:路由组件的进口的中央的设置,说白了,就是路由组件在哪里展会
  -->
   <router-view></router-view>

vue-router细节钻研

第一问:路由组件与非路由组件在应用的时候有什么区别?

非路由组件
定义->xxx.vue
注册->components注册
应用->组件标签的模式应用

<div>
  <TodoFooter></TodoFooter>
</div>

路由组件:在应用的时候
基本看不见双标签|单标签,都是在router文件夹外面应用【组件名字】

第二问:router|route区别?
router:路由器【router文件:对外裸露的VueRouter类的实例,路由器】
route:路由,一个路由器能够治理多个路由

第三问:入口文件,注册路由器作用?
注册router作用:注册后全副VC身上都会领有$router|$route属性

第四问:router-link|router-view。
router-link|router-view是全局组件:在任意VC外面都能够间接应用【vue-router提供的全局组件】
router-link:申明式导航链接,能够批改K,务必要有to属性!!!
router-view:路由组件进口中央设置
肯定要留神一件事件:路由组件切换的时候,每一次路由组件的mounted都会再一次执行。
因为每一次路由的切换,都会导致上一次的路由组件被销毁重建!!!!

第五问:keep-alive全局组件有什么作用?
在我的项目中路由组件切换的时候:相应的路由组件会被销毁重建。
Vue框架中,提供了一个全局组件kepp-alive。这个组件的作用是能够缓存路由组件!!!

<keep-alive :include="['home','about']">
  <router-view></router-view>
</keep-alive>

第六问、路由传递参数有几种形式?
Vue框架反对路由传递参数:路由传递参数有两种,query参数,params参数?
query参数:上面这种写法
<router-link to="/home/message/detail?a=1&b=烤鸭">申明式导航链接:query参数</router-link>

params参数:上面这种写法
<router-link to="/home/message/detail/10/容嬷嬷">申明式导航链接:params参数</router-link>

query参数:不是门路当中一部分 ?k=v&k=v
params参数:算作门路当中一部分,params参数肯定要将路由的配置改成path:'detail/:id/:name'

配置路由的时候上面这种写法代表含意
代表你的Detail路由组件务必传递params参数。
path: ‘detail/:id/:name’,

编程式导航
在vue-router插件中,导航有两种模式。
第一种即为申明式导航router-link标签。
第二种即为编程式导航,任意标签都能够作为导航链接。

goDetail(item) {
  //能够通过VC的$router[路由器],实现路由的跳转!!!
  //VC身上的$router属性,本质它的属性值即为VueRouter类的实例。
  //VueRouter.prototype原型对象的身上有push|replace办法,他们能够实现路由的跳转!!

  //编程式导航:跳转到Detail
  //编程式导航:第一种写法【纯纯的字符串写法,这种写法当前不会用了】 query|params参数都能够
  //this.$router.push("/home/message/detail?a="+item.a+"&b="+item.b);

  //编程式导航:第二种写法【不罕用】,模板字符串写法
  //this.$router.push(`/home/message/detail?a=${item.a}&b=${item.b}`);

  //第三种写法:对象写法【很重要:下面两种写法你能够遗记】
  //书写配置对象
  //传递query参数:path:设置的跳转门路  query
  //this.$router.push({path: "/home/message/detail",query:{a:item.a,b:item.b}});

  //传递params参数:记住豪哥交给你们的顺口溜,两个P犯相【不行】!!!!
  //编程式导航:路由跳转传递params参数,务必给路由命名【2个P犯相】
  this.$router.replace({name:'erha',params:{id:item.a,name:item.b}})

  //传递query|传递params
  //书写逻辑的
  // if (item.id > 1) {
  //   this.$router.push({
  //     name: "erha",
  //     query: { a: 1, b: 2 },
  //     params: { id: 4, name: 5 },
  //   });
  // }
}

编程式导航与申明式导航有啥区别?
雷同中央:都能实现路由的跳转以及传递参数【query、params】

不同的中央:编程式导航能够书写业务逻辑、申明式导航就是一个破标签,点击就跳转了,没有书写判断中央!!!

vc身上的$route和$router的区别是什么?

$route:与路由相干【路由的URL、query参数、params都都能够获取到】
$router:push|replace,实现编程式导航路由跳转!!!

push与replace区别?
push模式:能够记录历史记录
replace:不会记录历史记录

vue-router路由的模式有几种?

hash:hash模式【门路当中带有#】
history:历史模式【门路当中不带#】

面试题:vue的路由模式有几种?有什么区别?

两种模式:hash模式、history模式!

区别:
1:眼睛能看到,hash模式门路携带#,history模式门路当中不须要携带#
2:history模式下我的项目,在打包的时候上线,须要与后盾紧密配合【nginx】,如果于后盾配合不好经常出现404。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理