大学生自学一个月Vue笔记,微瑕(第一部分)

185 阅读13分钟

Vue学习笔记

学习的尚硅谷的网课

Vue是什么

Vue是用于构建用户渐进式框架,其特点有

  1. 组件化模式:提高复用率,让代码更好维护
  2. 声明式编码:无需直接操作DOM
  3. 虚拟DOM和Diff算法

容器和Vue实例的关系是1对1的,真实开发中只有一个Vue实例,配合着组件进行使用

双向绑定:一般用于表单元素上,#重要概念-Vue#​v-model:value​可以简写为v-model​,因为v-model​默认收集的就是value值

可以使用el​或者$mount(' ')​进行挂载容器,$mount(' ')​会更为灵活

data的两种写法:对象式和函数式,在组件中使用必须使用函数式

数据代理

Object.defineProperty() - JavaScript | MDN (mozilla.org)

Object.definProperty()​方法会直接在对象上定义一个新属性,或者修改已有的属性,并返回此对象

参数:(对象,’属性名',要定义或修改的属性描述符「对象」),默认状态下,通过此方法定义的对象属性不可枚举,如果想要进行枚举,就要在第三个对象参数中添加 enumerable:true​,默认属性值是不可进行修改的,使用writable:true​解除修改限制,默认属性值不可以进行删除,使用configurable:true​解除删除限制

如果我们想让对象的某个值随着外部变量的变化而变化该怎么办呢?

​
我们希望 student 对象中的 age 属性跟随着外部的 number 变量的变化进行变化
let number = 20;
const student = {
    name:'张三',
    sex:'男'
}
Object.defineProperty(student,'age',{
//利用此方法的getter,getter会在获取这个这个对象属性的行为发生时,通过gettert返回出去
    get(){
        return number;
    },
//利用此方法的setter,setter会在修改这个对象的属性的行为发生时,调用set里面的方法,被修改的值会成为setter的第一个参数,如果想要
// age 跟随这 外部变量 number 变化,则在set里面将 value 的值赋值给 number
    set(value){
        number = value;
    }
})

数据代理

定义:通过一个对象中的变化去修改另一个对象中的变化,叫做数据代理

下面代码就是通过 obj 和 obj2 数据实现了代理

        const obj = {x:100}
        const obj2 = {y:200}
​
        Object.defineProperty(obj2,'x',{
            get(){
                return obj.x;
            },
            set(value){
                obj.x = value;
            }
        })
​

Vue中的数据代理

Vue的数据是响应式的,是利用了数据劫持和数据代理进行写的,这边我们只讨论数据代理,我们新建了一个 Vue 实例vm 我们在vm的 data 对象中定义的属性,会在vm本身生成一个相同的属性,data对象中的数据存放在了 vm._data​ 这个属性中,他们属性的修改和获取都会使得双方的数据发生改变,但是要实现响应式变化,就要进行数据劫持,监听数据的变化,这边不讨论

        const vm = new Vue({
            data:{
                name:"白德培",
                adress:'山东省'
            }
        }).$mount('#app')

键盘事件与修饰符

键盘事件有两种:keydown​ :按键按下就触发 和 keyup​:按键按下抬起后触发

在vue中,可以通过v-on绑定键盘事件后跟事件修饰符进行检测,vue中为常用的按键起了别名,这些内置的别名可以兼容不同的规范

  • .enter

  • .tab​:tab比较特殊,因为tab本身就拥有切换元素的功能,所以在使用tab的时候,使用keydown​事件居多

  • .delete​ (捕获“删除”和“退格”键)

  • .esc

  • .space

  • .up

  • .down

  • .left

  • .right

  • 系统修饰符:在使用系统修饰符时,如果是keyup​事件,只会在按住修饰符的时候按下其他任意键进行触发。使用keydown​时则不会,使用链式修饰符可以指定按键,比如@keyup.ctrl.y='方法'​,只有按下ctrl+y的时候才会触发方法

    • .shift
    • .meta
    • .alt
    • .ctrl

当然除了这些别名也可以写按键的 key 值

但是如果是像CapsLock​这种按键,在事件修饰符中应该写成 caps-lock

你还可以通过全局 config.keyCodes​ 对象自定义按键修饰符别名:Vue.config.keyCodes.f1 = 112​,在使用时就可以

修饰符

修饰符可以连续写

.stop​:阻止冒泡行为

.once​:事件只触发一次

.prevent​​:阻止默认行为

v-model​的修饰符:.number​ 以数字类型进行存储

计算属性

类型:{ [key: string]: Function | { get: Function, set: Function } }

计算属性也是根据数据代理去修改的,也可以设置自己的 setter 和 getter, 但是计算属性更多的时候只是用于显示,如果想要单独设置set也是可以的,只不过要写成对象形式,就像数据代理那样,,如果直接写成函数形式,默认就是getter

计算属性只有在数据更新的时候才会进行重新计算

侦听器

watch​ 使用与变量名重名的函数或者对象或者计算属性进行定义

//假设要监听 isHot 属性的变化,是个Booleanwatch:{
    isHot:{
        handler(newData,oldData){
            //handler会做为 isHot 发生变化时执行的函数,他的两个参数会记录下来变更前和变更后数值
        },
        immediate: Boolean, //immediate 翻译为立即,默认值为false,如果为true,则在程序启动时调用一次handler
    }
​
}

也可以使用vm.$watch('变量...',{配置项})​进行数据侦听

Vue默认是可以检测到多层级的数据改变的,但是Vue提供的watch中是检测不到多层级数据改变的

watch中的属性是简写的,比如watch:{ isHot:{ } }​,isHot是以字符串的形式存在的,如果有个number​对象中的属性a​,要对这个a​进行侦听的话,就要写为watch:{ 'number.a':{ } }

如果number​对象拥有多个属性,现在要对number​这个对象进行侦听,对象中任意一个属性发生变化就会触发侦听器,就要使用深度侦听

   numbers:{
    deep:true,
    handler(newData,oldData){
    console.log(``);
        }
    }

但是这侦听会失去具体的数值变化,他只会提示你这个对象的变化,但是不会提示你对象属性值的具体变化

当侦听器不需要立即执行功能和深度侦听功能时,可以简写为函数的形式

//实例中创建watch形式
watch:{
    isHot(newData,oldData){
           console.log(newData,oldData)
        },
    }
}
//调用API形式
vm.$watch('isHot',function(newData,oldData){console.log(newData,oldData)})

watch和computed的区别

  1. 计算属性能完成的事情,watch都可以完成
  2. watch能完成的功能,计算属性不一定能完成,例如 watch可以进行异步操作

绑定Class和Style

绑定class和style都可以使用:字符串写法、对象写法、数组写法、数组中对象写法、计算属性写法

原文链接1

Class

对象语法

<style>
.active {
color: red;
}
.active-font {
font-size: 2em;
}
</style>
<body>
 <div id="app">
  <span :class="{
active:isactive,
'active-font':isactiveFont}">
这是用来测试classstyle绑定的文字
​
 </span>
</div>
​
const App =new Vue({
 el:'#app',
 data:{
     isactive:true,
     isactiveFont:true,
 },
 computed:{
​
 },
 component:{},
});
​

使用对象进行添加的时候,有短横杠的类使用 ''​包起来,比如上面的active-font​类,在写的时候使用'active-font'

绑定的数据对象不必内联定义在模板里:

<div v-bind:class="classObject"></div>
data: {
classObject: {
 active: true,
 'text-danger': false
}
}

也可以绑定一个计算属性

<div v-bind:class="classObject"></div>
data: {
isActive: true,
error: null
},
computed: {
classObject: function () {
 return {
   active: this.isActive && !this.error,
   'text-danger': this.error && this.error.type === 'fatal'
 }
}
}

数组语法

我们可以把一个数组传给 v-bind:class​,以应用一个 class 列表:

<div v-bind:class="[activeClass, errorClass]"></div>
data: {
activeClass: 'active',
errorClass: 'text-danger'
}

如果你也想根据条件切换列表中的 class,可以用三元表达式:

<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>

这样写将始终添加 errorClass​,但是只有在 isActive​ 是 truthy(真值)[1]^^ 时才添加 activeClass​。

不过,当有多个条件 class 时这样写有些繁琐。所以在数组语法中也可以使用对象语法:

<div v-bind:class="[{ active: isActive }, errorClass]"></div>

收集表单数据

常用的表单元素有

input                    输入框
input type='radio'       单选框,name要相同
input type='checkbox'    多选框,name要相同,需要使用数组接受value值
select->option           下拉菜单
textarea                 文本域

过滤器

使用filters:{}​进行表示,过滤器中使用函数标识,在使用中{{ time | getformattime }}​,通过管道符进行连接,可以连接多个过滤器,顺着管道向下传参,最终这个插值模板中会显示过滤器返回的值,过滤器的第一个参数始终是使用的变量

v-cloak属性

cloak:翻译隐藏,v-cloak​属性在加载Vue实例的时候会自动移除,为了防止js阻塞造成的未渲染,在css中使用属性选择器选择所有的带有v-cloak​属性的元素,让他们不显示,当Vue加载完成后,自动移除v-cloak​属性

v-once属性

放在标签里面,没有值,使用了v-once​的标签如果用了插值,那么这个标签显示的值就是插值的第一个值,之后不会变化

v-pre属性

放在标签中的属性,使用了v-pre​的标签不会被Vue解析,加快了Vue解析的过程

自定义指令

在Vue实例中使用directives​进行配置,自定义指令什么时候会执行呢?

  1. 在成功绑定到元素的时候会执行,这时候元素可能并未被解析到页面上
  2. 在元素所在模板被解析的时候会执行

自定义指令函数式

写法简单,但是不能处理细节

    <div id="app">
        <h1 v-big="adress"></h1>
    </div>
     <script>
​
        new Vue({
            data:{
                adress:'理塘'
            },
            directives:{
                // 自定义指定-函数式
                big(element,binding){
                    element.innerText = binding.value+'丁真'
                }
            }
        }).$mount('#app')

自定义指令对象式

写法复杂,但是能处理细节

相对于函数式,多出来几个固定方法,类似于生命周期

directives:{
    fbind:{
        bind(){},        //绑定时调用
        inserted(){},    //插入完成后调用
        update(){}       //数据所在的模板重新被解析时调用
​
    }
}

组件化编程

组件是不能绑定元素的!!!!!

VueComponent构造函数

Vue组件的本质是一个名为VueComponent​的构造函数,是Vue.extend({ })​生成的,VueComponent​是负责创造更多的组件模板,

每当写入标签时,就相当于 new 了一个VueComponent​的实例对象,所以复用的组件数据是不影响的

每次调用Vue.extend({ })​都会生成一个新的VueComponent

VueComponent和Vue在原型链上的关系

复习:原型和原型链2

Vue手动将VueComponent​的原型对象指向了Vue​的原型对象,这样就能让组件的实例对象去使用Vue​原型对象上的方法和属性

组件名命名规范

如果组件是一个单词组成 1.使用首字母小写 school 2.使用首字母大写 School (个人推荐)

如果组件由多个单词组成 1.短横杠写法 ,全小写 my-school 2.首字母大写 MySchool (需要Vue脚手架的支持才能使这种名字的标签解析)

标签的写法 1.成对出现<school> </school>​ 2.自闭和标签 <school/>(这种写法在非脚手架中,不会对这个自闭和标签后的标签进行解析)

非单文件组件:一个文件中包含了多个组件

组件只能在Vue的实例中去使用

使用Vue.extend({ })​​创建组件,组件不能去挂载容器,组件中的data只能采用函数式去定义,组件只有注册过才能使用

创建组件可以简写为: const 变量名 = {配置项}​,在Vue实例中如果使用这个变量作为组件,那么Vue会在注册组件的时候自动的将这个对象变量转化为组件

在Vue实例中的compoents​对象中去注册组件

这种方式属于局部注册组件
new Vue({
    components:{
        自定义组件名:组件实例名,   //也可以直接写组件实例的名字,因为这是非单文件的组件
    }
})

全局注册组件:使用 Vue.component('自定义组件名',组件实例名)​进行全局注册组件

name​属性可以决定在开发者工具中显示的组件名字

可以在组件或者Vue实例的$children​属性中看到子组件

单文件组件:一个文件中只包含一个组件

遇到的问题

vue根目录下的index.html中的id="app"与src目录下的App.vue中的id="app"为什么不会冲突_RotatingBlock的博客-CSDN博客

Vue 的单文件组件 (即 *.vue​ 文件,英文 Single-File Component,简称 SFC) 是一种特殊的文件格式,使我们能够将一个 Vue 组件的模板、逻辑与样式封装在单个文件中,使用 SFC 必须使用构建工具

在使用脚手架工具后,public文件夹下index.html​文件的说明

#🎨Question-Vue:#​​App.vue​​中的<div id='app'>​​和index.html​​中的<div id='app'>​​有什么区别 可去本标题开头查看 遇到的问题中的他人回答,以下是我的总结

Vue组件一定要有一个根元素 div

首先要明确一个问题,App.vue​是根组件不是Vue的实例化对象, App.vue也是个组件,只不过是最顶层的组件,在他的上面就是vm,即Vue的实例对象,在「main.js」​中我们引入了Vue库,然后去 new 了一个Vue实例对象,通过使用$mount​挂载到了「public」​下「index.html」​中的 app 容器中,这个 app 的容器的作用就是用来绑定元素根路径的,而App.vue中的app容器,是用来想元素根路径去注入内容的,实际被解析出来的只有App.vue的<div id='app'>​,而作为index.html​中的app只是作为一个解析入口,实际上不会被解析

​​

关于「main.js」​中的render函数是什么东西

「main.js」​中引入的Vue,其实是一个阉割版的Vue,这个Vue只保留了Vue的核心功能,去掉了一些模板渲染功能,没有了模板渲染功能,就不能写template​,所以需要借助render​函数接受到的createElement​函数进行创造元素

Vue中关于render的使用

//这是main.js中的语句
new Vue({
  render: h => h(App),
}).$mount('#root')
​

render是一个函数,他接受一个createElement​的函数参数,通过像这个createElement​传入组件并返回,可以快速的渲染元素

render(createElement){
    return createElement('标签类型',<标签内容>), //这是createElement一种用法,比如下一行
    return createElement('h1','这是我渲染的h1标签'),  //如果使用这种方式,就会在页面上渲染出一个h1标签,并且有内容
    return createElement(组件名),  //如果使用这种方式,就会直接解析组件中的template模板
}
因为render函数只有一个参数,并且只返回一个简单的表达式,就可以使用箭头函数简写为
render: h => h(App) 

修改CLI的默认配置#🎨Question-Vue:#​

像主入口什么的都是可以改的,官方提供了CLI的配置全局CLI配置参考

使用 vue inspect > output.js​可以查看到Vue脚手架的默认配置,但可能会出现编码乱码问题,另存为utf-8

在与「package.json」​同级目录下新建「vue.config.js」​文件,这个文件中的内容应该严格遵守文档要求来写

// vue.config.js
const { defineConfig } = require('@vue/cli-service')
​
module.exports = defineConfig({
  // 选项
})

剩下的就看文档改吧

ref API

ref​ 被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs​ 对象上。

有些时候会不可避免的对DOM进行手动操作,使用 ref 可以获取都页面上的某个DOM 元素。而且可以获取到组件,使用 ref 获取到的组件,是组件实例对象,而使用id获取的组件,获取的是组件中的DOM对象

1.在标签中使用ref ='自定义名'
<p ref="p">hello</p>
​
2.在组件上使用ref
<child-component ref="child"></child-component>

props API

props的值是单向传递的,只能从父组件向子组件进行传递,不能在子组件去修改props属性的值

props的三种写法

​
数组式
props:['name','age','sex']
​
对象式可以指定数据类型
props:{
    name:String,
    age:Number,
    sex:String
}
​
对象式可以指定数据类型和默认值
props:{
    name:{ 
        type:String,
        default:'默认名字'
    }
}

通过传入对象Vue自动结构赋值3

传入一个对象所有的属性

如果你想要将一个对象的所有 property 都作为 prop 传入,你可以使用不带参数的 v-bind​ (取代 v-bind:prop-name​)。例如,对于一个给定的对象 post​:

|

post: {
id: 1,
title: 'My Journey with Vue'
}

下面的模板:

<blog-post v-bind="post"></blog-post>

等价于:

<blog-post
v-bind:id="post.id"
v-bind:title="post.title"
></blog-post>

Prop是单向下行绑定,父级的更新会向下流动到子组件中,prop可以添加验证机制,判断传的值是否是正确的类型

mixin混入

为了提高复用性,使用 mixin 可以使得多个组件使用同一个配置,mixin文件可以配置vc中所有的配置项,像一个另类的类

使用方法 1.首先新建一个js文件 2.在js中写入混入的配置,假设有多个组件需要使用同一个方法,比如弹窗提示你点击了这里 3.导出一个配置项 4.在需要使用mixin文件的组件中导入mixin文件 5.在配置项中使用mixins​项进行使用例如 mixins:[mixin]

// mixin.js
export const mixin =  {
    methods:{
        alertInfo(){
            alert('你点击了我')
        },
    }
}
//=============================================================
在组件中使用mixin//Student.vue组件
<script>
    import { mixin } from './mixin.js'
  
    export default {
        mixins:[mixin]
<script>

可以在「main.js」​文件中,可以进行全局引用mixin,但是要在创建Vue实例之前使用,使用Vue.mixin(mixin对象名)​进行全局注册mixin

插件 install

插件 — Vue.js (vuejs.org)

使用插件需要使用一个包含install​方法的一个对象,或者直接导出一个install​方法,install​方法的第一个参数是Vue​,第二个以后的参数是插件使用者自己传入的数据

插件常用于开发全局功能

通过全局方法 Vue.use()​ 使用插件。它需要在你调用 new Vue()​ 启动应用之前完成:

插件文件
export default {
    install(Vue) {
        console.log('这是插件');
​
        // 定义全局的过滤器
        Vue.filter('mySlice', function (value) {
            // 返回 value 的前四位
            return value.slice(0, 4);
        })
        // 定义全局指令
        Vue.directive('fbind', {
            bind() { },        //绑定时调用
            inserted() { },    //插入完成后调用
            update() { }       //数据所在的模板重新被解析时调用
​
        })
        // 定义全局方法,定义在原型对象上
        Vue.prototype.$printPl = function () {
            alert('这是定义在插件里面的全局方法');
        }
​
    }
}
在 main.js 中引入并使用插件
​
import Vue from 'vue'
import App from './App.vue'
// 引入插件
import Pulgin from './assets/tools/install.js'
Vue.config.productionTip = false;
// 使用插件
Vue.use(Pulgin);
​
// 使用插件要在创建Vue实例之前
new Vue({
  render: h => h(App),
​
}).$mount('#root')
​

组件自定义事件

自定义事件适用于 子组件==>父组件 传递数据

Vue的自定义事件是给组件用的,使用this.$emit(‘事件名’,数据)​进行触发事件

自定义事件组件交互4

自定义事件组件交互

props​是父组件向子组件传递数据,自定义事件可以向父组件进行数据传递,关键词:emit,翻译:发出

假如一个表单中的输入数据要传递给父组件的H1标签进行显示,首先对这个表单的submit事件进行监听,回调函数采用自定义函数,自定义函数内这样写:this.$emit("自定义事件名",this.<数据>)​,在父组件的子组件引用标签内加入一个事件监听,监听的事件名为字组件中自定义的事件名,回调函数接受,回调函数的第一个参数接受的就是子组件汇总传递过来的数据,在在这个函数中将本地的变量重新赋值,在通过模板语法动态的显示H1标签

在子组件的25行,使用了$emit​进行向父组件的传值

App.vue
​
<template>
<img alt="Vue logo" src="./assets/logo.png">
<h1>{{resdata}}</h1>
<MycomponentVue @resData='getResdata'/></template><script>
import MycomponentVue from
'./components/Mycomponent.vue';
​
export default {
name: 'App',
data(){
 return {
   resdata:''
 }
},
components: {
 MycomponentVue
},
methods:{
 getResdata(data){
   this.resdata = data;
 }
}
}
</script>
<style>
</style>
子组件
​
<template>
 <h1>props</h1>
 <p>{{ title }}</p>
 <form @submit.prevent="sendMainData">
     <input v-model="tdata"  type="text">
     <p>{{ tdata }}</p>
     <button>点击我发送数据到主文件的H1</button>
 </form></template><script>export default {
 name:'conponent1',
 data(){
     return {
         tdata:'',
     }
 },
 methods:{
     sendMainData(){
         this.$emit('resData',this.tdata)
      }
}
}
</script>
<style scoped>
</style>

灵活性更强的写法

一般我们就使用上面的写法进行添加事件,但是如果有延时的需求的话,就可以使用生命周期钩子函数配合ref​进行定义

App.vue
​
<Student ref='student'/>//引入组件并建立ref对象mounted(){
//在渲染完成时做的事情//通过this.$refs拿到组件的ref对象,并用$on添加事件
//通过这样的方可以添加延时器
    setTimeout(function(){
        this.$refs.student.$on('事件名',事件触发的方法)
        //如果指向触发一次事件,就使用以下代码
        this.$refs.student.$once('事件名',事件触发的方法)
    },3000)
}
//this的指向问题this.$refs.student.$once('事件名',事件触发的方法)中,事件触发的方法可以写为匿名函数,
this.$refs.student.$once('事件名',function(){
    console.log(this);//匿名函数中的this指向的是 触发这个事件 的组件实例,而不是父组件,
    如果使用了箭头函数,这个代码写在哪,this就指向哪
})

解绑自定义事件

this.$off('事件名')​:解绑一个自定义事件

this.$off(['事件名1','事件名2',.....])​:解绑多个自定义事件

this.$off()​:解绑全部的自定义事件

this.$destory()​:销毁当前组件,在销毁组件的时候会自动解绑组件上所有的自定义事件

给组件使用原生DOM事件

#重要概念-Vue#​使用@原生事件.native进行修饰,例如<Student @click.native = 'show' />

全局事件总线#重要概念-Vue#​

可以实现任意组件中的数据通信,写法有很多,最标准的写法是利用生命周期

全局事件不是程序员写好的,而是一种依照现有的特性进行了融合,更像是一种设计模式

使用方法:在main.js​中创建一个组件,然后把这个组件挂载到Vue.prototype​上,因为他是一个组件,所以他可以使用Vue原型上面的$on、$emit、$once​等方法,这个组件就相当于一个中转站,我们也可以直接把vm实例当做这个中转站,标准写法就是把vm当做中转

beforeCreate​生命周期函数中写入将自身添加到Vue原型​上,一般命名为$bus​,生命周期钩子函数中的this​就是这个组件的实例

main.js
new Vue({
  render: h => h(App),
  beforeCreate(){
    Vue.prototype.$bus= this;//安装全局事件总线
  }
}).$mount('#app')

再结合上面灵活性更强的写法5中提到的this指向问题,使用匿名函数作为事件触发函数时,this指向的是触发事件的组件,而使用箭头函数时,this指向的是当前组件,所以通过箭头函数就能实现任意两个组件之间的数据通信

用完了事件,如果用不到了,不要忘记解绑事件

本地存储

存储

localStorage:​使用localStorage.setItem('键','值')​进行存储,键值对都是字符串

因为本地存储使用的都是字符串,在传入的时候如果不是字符串类型的会自动调用toString​方法,在存储对象的时候,就需要使用JSON.stringify(对象)​方法,将对象转化为JSON字符串进行存储

读取

使用localStorage.getItem(键名)​进行读取数据,如果读取的是一个对象,那么需要使用JSON.parse()​进行解析,解析成对象

删除

使用localStorage.removeItem(键名)​进行删除

清空本地存储

使用localStorage.clear()​进行清空本地存储

sessionStorage

这种存储方式的API和localStorage​​的API完全一直,区别在于sessionStorage​​的存储是临时的

Vue动画和过渡

transition​标签在Vue中不会被解析为真实DOM,只是用来提供添加动画的标签

在Vue提供了 <transition> </transition>​ 进行快捷的添加动画效果,<transition-group> </transition>​标签能写多个标签,transition内的标签都要有key属性

要添加动画效果首先要自己写好动画,然后新建两个类,一个是进入、一个退出,如果transition标签没有name属性,那么会找到CSS中的 v-enter-active​ 和 v-leave-active​ 样式进行添加,如果transition标签有nama属性, 那么会去找<name>-enter-active​ 和 <name>-leave-active​ 样式进行添加

在一开始就进行动画展示:向transition标签添加 appear​属性并设置为真,可以简写为 appear​,如下

    <transition appear>
      <h1 v-show="isshow" id="showh1">展示界面</h1>
    </transition>

动画效果定义如下

.v-enter-active {
  animation: showdonghua 1s linear;
}
.v-leave-active {
  animation: showdonghua 1s reverse;
}
​
@keyframes showdonghua {
  from {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(0px);
  }
}

过渡(懒得写了,自己去看文档吧)

配置代理

跨域:协议、地址、端口号有一个不一致就是跨域

解决方案:1.cors解决,通过后端发送一个文件标识来解决跨域,这是真正意义上的跨域

2.jsonp,用的不多

3.代理服务器(重点)

使用Vue-cli配置

配置参考 | Vue CLI (vuejs.org)

在vue.config.js文件添加以下配置

使用这种方法只能配置一个代理

module.exports = {
  devServer: {
    //proxy的字符串是需要请求到的服务器
    proxy: 'http://localhost:4000'
  }
}

更详细的配置方式

这种方式可以写多个

目标:本机是8080端口,需要向5050端口的服务器请求student数据

//组件
axios.get('http://localhost:8080/tag/student')//向代理服务器去请求
.then(response=>{},error=>{});
​
//vue.config.js文件
module.exports = {
  devServer: {
    proxy: {
      '/tag': {//这个是请求前缀
        target: 'http://localhost:5050',//这个是代理转发的目标服务器
        pathRewrite:{'^/tag',''},//这个是重写路径,是一个对象,第一个是正则,第二个是匹配后重写为啥
        ws: true,
        changeOrigin: true//如果为true,代理服务器会以目标服务器的端口进行通信,这里就是5050,默认就是true
      },
    }
  }
}

Vue插槽

默认插槽

使用成对标签显示组件,然后在组件标签中间写入dom,在组件里面写<slot></slot>​定义插槽的位置

具名插槽

当使用多个插槽时,需要对插槽进行命名,通过name属性进行命名,在组件标签中的dom添加一个slot属性。通过slot='name'​对插槽进行索引

//组件文件
<template>
<div>
  <h1>这是插槽</h1>
  <slot name="test">哈哈</slot>
</div>
</template>
​
//App.vue
  <Sl>
    <h1 slot="test">狠狠的放入</h1>
    <h2 slot="test">h2狠狠放入</h2>
  </Sl>
//可以为多个DOM指定同一个插槽,也可以使用一个div进行插槽
如果不想使用div包裹进行插槽,可以使用<template>标签进行包裹, 
    ***(template标签不会被解析出真实DOM)* **
    并且在<template>标签内添加`slot='name'`​或者`v-slot:name`​, 
    **注意!** :`v-slot:name`​只能写在<template>标签内