Vue2+3基础

第一个Vue程序

如何导入?

使用script进行Vue全局设置:

 指定Vue实例挂载的位置

, Vue和js一样,都需要在script里写

第一步创建vue实例

1.为什么要new vue(),直接调用Vue不行吗?

  不行,因为如果直接调用Vue()会报如下错误:

 2.关于vue构造函数:options

  options翻译为多个选项

Vue框架要求这个options参数必须是一个纯粹的js对象:{ }

在{ }对象中才能大量编写Key:value键值对

 

一个Key:value就是一个配置项,通过options参数给Vue实例指定多个配置项

3.关于template配置项:

template翻译为模板,用来指定模板语句,模板语句是一个字符串形式的:‘ ’

什么是模板语句?

  Vue框架自己制定了一些具有特殊含义的特殊符号,有自己的语法规则,模板语句可以是一个纯粹的HTML代码,也可以是HTML+Vue,

  template后边的模板语句会被Vue框架的编译器进行编译,转化为浏览器认识的HTML代码。

const myVue = new Vue({
    template:'<h1>Hello! Vue!!</h1>'
})
myVue.$mount('#app')

 

 z在浏览器当中可以看到,没有div,只有模板语句,他是直接将id为app 的div替换成HTML语句的!

 2.模板语句的数据来源

1.谁可以给模板语句提供数据支持呢?data选项

2.data选项的数据类型是什么?Object |Function(对象或者函数),也就是说,可以是数组。

 

 

3.data配置项专业叫法:Vue实例的数据对象(data实际上是整个Vue实例提供数据来源的)

4.如果data是对象,对象必须是纯粹的对象(含有0个或多个Key:value键值对)

5.data数据如何动态插入到模板语句中?

{{ }},这是Vue自己搞的一套语法,称为模板语法中的插值语法(胡子语法)

{{data的key}}

换行用 ` 或者+,注意:在{这里不能有字符包括空格{ }这里不能有字符包括空格}

 3.template的配置项解释

1.template后边指定的是模板语句,但是模板语句只能有一个根节点,想多写加个div在div里边写

 

2.只要data中的数据发生变化,模板语句一定会重新编译。

3.可以不用template写模板语句,可以直接写在HTML里,这样挂载位置的元素也不会被替换。

关于¥mount(‘#app’)

在Vue中有一个el配置项

el的作用和¥mount()作用一样,都可以实现对Vue实例对象的挂载

el : '#app'  ==  myvue.$mount('#app')

Vue的一夫一妻制

一个Vue实例只能接管一个容器,1对1

 Vue核心技术(重点)

模板语法之插值语法{{}}

{{主要研究这里可以写什么?}}
1.在data中声明的变量、函数等都可以
2.常量都可以
3.只要是合法的JS表达式都可以

4.模板表达式都被放在沙盒中,如下能使用

 模板语法之指令

指令语法:

1.什么是指令语法?有什么作用?

2.Vue框架中的所有指令都是v-开头

3.插值是写在标签体当中的,指令写在HTML的标签属性上。

 4.指令语法规则:

  指令的完整语法格式:

    <Html标签 v-指令名:参数=“JS表达式”></Html标签>

  注意指令表达式中不能再添加一个{{}}

不是所有的指令都需要参数和表达式

5.v-once 指令

  作用:使用该指令后标签只渲染一次,所有子节点及元素都视为静态内容跳过,不会更新。

6.v-if="表达式"指令

作用:表达式的执行结果是一个布尔类型true/false,T成立,F不成立

7.v-bind指令

作用:用来使得某个属性的值成为动态效果

语法格式:v-bind参数="表达式"   /  :参数=“表达式”

 来说说话bind像的model

v-bind和v-model都可以完成数据的动态绑定

v-bind是单项的数据绑定,可以用在任何标签上

v-model是双向的数据绑定,只能用在表单类元素上:input,select,textarea,这种和用户交互的标签上。

v-bind和v-model的简写方式:

bind  v-bind:参数="表达式"  简写  :参数=“表达式”

model  v-model:value="表达式"  简写  v-model=“表达式”

 用v-model交互,bind不交互,以下是v-model,如果是bind,即使左边改变右边也不变

 MVVM架构思想

 将Model和View视图分离开,当View变化后,VM核心自动去更新Model,不需要自己写DOM的js代码。开发效率提高

 认识VM

vue框架也收到MVVM思想启发,创建的Vue实例一般用vm命名

通过vm实例可以访问那些属性?

带$的是公开属性,一般程序员使用

带_的是私有属性,供Vue框架底层使用

通过vm也可以访问Vue实例对象原型对象上的属性:vm.$delete

为什么Vm可以获取到msg?

 因为数据代理机制

数据代理机制基于object.defineProperty() 

 数据代理机制就是用一个临时对象去间接访问对象,达到直接访问的效果。

 数据代理不会给$和_做代理,怕出错

 data可以是对象,也可以是函数,学到组件就知道了

 配置项enumerable,configurable

 vue事件绑定,需要在Method里写回调函数才能调用

 没加占位符

 

 加了

 this

 method方法没有做数据代理,就是用变量代替

 事件修饰符

@wheel是鼠标滚轮滑动

@keydown键盘按下不弹起发生

@keyup键盘按下并谈起发生

网站里边输入用户名密码回车自动获取id和ps就是用keyup事件所传的event对象的键值判断是否等于回车13自动登录的。

 按键修饰符

 

常用的有修饰符,不常用的想用只能自定义了,或者直接在后边.key,就上边是说的根据获取的键值去判断是否是想要的目标值ASII

 反转字符串

 

使用Vue原有属性经过一系列运算得到一个新的属性,叫做计算属性。

data对象当中的属性可以叫做Vue的原有属性。

语法格式
    computed : {

    计算属性1:{

    set(val){}

    get(val){}

    }

  }

    

 

 

简写就是

  computed:{

  计算属性(){

  return ?

  }

}

作用:代码复用,容易维护,效率高

计算属性简写格式和方法格式一样

 watch监听

watch:{

}

属性简写

 

可以监视多个属性,用哪个监视哪个名字

immediate:true 立即执行

immediate: 其值是true或false,确认是否以当前的初始值执行handler的函数.

有一个固定的方法:handler(newValue,oldValue){}

如何获取new和old?

可以使用v-model指令双向绑定,用哪个就绑定哪个watch里的属性

 

this还是当前Vue实例。

如果该函数是箭头函数this就是window对象。

深度监视:当监视的属性里有很多属性要监视时,可以使用deep:true属性,就顶如(a.*)

handler:用来获取之前数据和现在改完数据

 后期想添加监视怎么办?

 和直接写有什么区别?

一个是一开始作为属性写到对象中,一个是后期通过调用api实现

当只调用handler属性时,可以直接简写,handler就像number的有参构造一样

后期监视简写

 箭头函数()=>{}默认是找上级的this,但是不简写function()本身是window就不行

在Vue里加强了class和style

 

 class绑定之字符串形式

v-bind不仅能绑定字符串,还可以绑定对象或者数组,所以.class样式可以与bind连用,实现动静结合

 可以用true还是false选择用哪个JS样式

已经变成Vue的形状了,悲

条件渲染 

关于v-if、v-else、v-else-if指令,就像后端的ifelse一样,成立立即执行。

 v-show

也是页面上看不见,但是在F12后台可以看见代码,而v-if=false是不会看见代码,真正的隐形

v-show是修改了CSS样式的display数值达到的隐形,还是会加载,而v-if不会加载

 template标签,起到一个占位符的作用,不会出现在页面上,也不会影响页面结构

 v-for遍历

格式  

 可以实现动态列表

遍历对象属性

按照属性顺序读取

遍历字符串

按照拆分的字母和下标,s 0 、j 1

遍历指定的次数

和字符串差不多

按照数组元素和数组元素下标 1 0 、2 1

虚拟Dom机制和diff算法:

虚拟Dom是先将数据虚拟储存,当修改后会更新一个新的Dom与旧的用Diff算法去对比两个之间的差别,只有差别的地方才会重新部署,没有的不改变,提高执行效率

 

 必须将key设置成主键,不然后边默认key是数组元素下标index,会导致列表错乱,

placeholder

 filter过滤器

 列表排序小技巧:可以鼠标单击触发修改data里的变量值,当赋值时,vm里会重新部署一遍,进而触发当type=1时的计算属性函数可以使用过滤器来完成

 两个单选按钮在同一name下才能实现单选

 

 model.类型转换number

 删除前后空格

lazy延迟加载,等鼠标光标离开后才加载

 这种指令不能在from表单上,会出现xss攻击,导致cookie泄露

 v-clock

为了解决vue.js加载不出来导致页面vue代码不执行,页面显示源码的情况,出现了v-clock

解决方法,在头里加一个CSS样式,里边将display设置成none

 []代表所有标签

 v-once

只在开始执行一次,后边直接成为静态内容

 v-pre

不在vue编译,提高编译效率

 自定义指令

函数式

 对象式

 响应式与数据劫持

 

什么叫做响应式,你写的数据能在页面上直接展示出来,或者更改一个数据,和这个数据有关的都叫做响应式。

数据劫持:其实就是set方法。

  Vue生命周期

四个周期,八个钩子

 

  

 从创建vm.$el后才有真实Dom

       

 data改变就继续调用两个钩子,改变一次调用一次

 这里的卸载销毁实际上是解绑Vue实例所有的监视器,自定义监听器,子组件等等。Vue实例还在

虽然beforeDestroy里监视器处于激活状态,但是不能用,内存中已经卸载了

 

 

 

 

 组件

组件就是用来提高代码复用率的。

三部曲:创建组件、注册组件、使用组件

 

第一步创建组件,使用template实现模块化,在组件中,data必须是对象,且return返回一个对象

Vue当中可以使用自闭合标签的,但前提必须在脚手架环境中使用

全局注册

 

 

 组件嵌套

注册的组件如果组件名和对象名一致可以简写

 app : app

 嵌套哪个组件就把组件名写到哪个组件下

Vm与Vc

vm包含vc,vc全称是VueComponent,Vue组件,是专门用来写组件的

vm和vc的原型对象是一个,所以能够互相访问,像共用一个父类,为了实现代码复用

重点:

 

导入导出

import,export,添加export以便其他文件能够导入他们 

导出方式

 单文件组件模型

 导入

这里的X1是标签名,也就是说在template里边定义模板的X1标签名

 脚手架

使用脚手架是为了浏览器能够认识.Vue文件,脚手架能够自动将VUe文件翻译成浏览器能够认识到Css,html,js代码

 

 Vue配置项

 render

 实际上是被缩写成这样的

原代码

 props配置项

当想更改属性值时,组件标签可以直接在标签内更改Value。像Html一样

 有三种更改方式

 props里还可以定义默认值default,添加必要性,必要性意思为不能为空

当想获取的值是数字或者其他值时,可以用V-bind标签,因为这个标签的返回值一定要是常量,对象。

props里的值不能修改,可以用个临时变量替代更改,展现数据也用那个临时变量

 父组件中获取子组件

有什么用?可以用来修改子组件值,达到目的

给组件标签加上一个ref,顶如一个id。可以用this.$ref.属性值的方式获取到

 不光组件,普通的Dom元素也可以定义id

 因为不建议做Vue里使用Dom,所以这个ref实际上就是Dom里id的替代品

 mixin混入:将组件间公共部分提取出来,不会和本身不会与同名的导入组件内函数冲突,就近原则

 特殊的是,在8个钩子函数内,在同名的情况下,先执行mixin内的,再执行函数本身的

全局混入

 混入是总结组件相同部分,实现代码复用

 install方法里边形参可以是Vue对象和数据

 scoped 关键字 局部样式

 

为了避免组件与组件之间样式名字相同造成代码替代。

在浏览器上实际在div上添加了一种编号,所以能区分开样式

 

 

自定义事件

 

 通过代码的形状形式绑定事件

 删除

 回调函数的this

 全局事件总线

 

消息的订阅与发布机制

pubsub-js

 导入库

 

 要使用箭头函数,要不没有this,因为本身没有this,使用箭头函数自动找外层的this也就是VC

 记得摧毁前将函数解除

AJAX跨域问题

 

 

 代理服务器跨域

 

代理服务器配置

 简单代理

 

 只能代理一个服务器

高级代理

 

 pathRewrite:^/api替换成‘ ’空要不地址会带/api

 

Vuex

多个组件实现资源共享

 

 

 

vuex过程,表面上还是用的vue的data,method,进行一个简单的包装,核心内容交给vuex里的store.js去搞了,store有三个对象

action对象、mutations对象、store对象
action对象处理事件逻辑,如然后将数据传输到mutations里去更新数据也就是state对象,因为state是响应式处理,整个页面包括state里的数据就会更新。达到目的

dispath是分发

context指的是action的行为动作

 

 业务逻辑简单可以跳过action,直接this.$store.commit

 

  

store对象和Vm里的data差不多

 简单数字加一了解一下Vuex过程

 

//App.vue
<template>
    <div>
        <h1>数字:{{$store.state.num}}</h1>
        <button @click="plusOne">点我加1</button>
    </div>
</template>

<script>
    export default {
        name : 'App',
        data() {
            return {
                startNum : 0
            }
        },
        methods: {
            plusOne(){
                // 这里的代码在实际开发中可能会比较复杂。
                // 业务逻辑复杂,代码比较多。
                // 如果你将这些代码放到这里的话,这些业务逻辑代码无法得到复用。
                // 无法在其他组件中使用,在其他组件中使用的时候,你还需要把这些代码再写一遍。
                //this.$store.state.num++
                // 调用vuex的API。
                // dispatch是vuex的API。调用这个方法之后,store对象中的plusOne这个action回调函数会被自动调用。
                // dispatch:分发
                // 交给plusOne这个action去处理这个事儿。
                this.$store.dispatch('plusOne', this.startNum)
            }
        },
    }
</script>
//Store.js
// 引入Vue,因为下面使用Vuex插件的时候需要Vue
import Vue from 'vue'

// 引入vuex插件
import Vuex from 'vuex'

// 使用插件
Vue.use(Vuex)

// 创建三个vuex插件的核心对象:actions对象、mutations对象、state对象
const actions = {
    // N多个action
    // 每一个action都是一个callback(回调函数)
    // 在action这种回调函数中编写复杂的业务逻辑
    // 有个原则:action是专门用来处理业务逻辑,或者说发送AJAX请求的。
    //plusOne : function(){}
    // 简写
    // context参数:context是vuex的上下文(context可以看做是store对象的缩小版)
    // value参数:传过来的数据
    plusOne(context, value){ 
        // 处理业务
        value = value + 1
        // 调用其它的action这个回调函数
        //context.dispatch('otherAction', value)
        // 业务逻辑处理完成之后,继续向下一个环节走,就轮到了数据的更新。
        // 提交上下文环境(所有的事儿都做完了,该最后一步了,更新数据了,怎么办?提交)
        context.commit('PLUS_ONE', value)
    },

    // 这里可能还会有其它的action
    // ...
    /* otherAction(context, value){        
        console.log(6666)
    } */
}
const mutations = {
    // N多个mutation
    // 每一个mutation都是一个callback(回调函数)
    // 每一个mutation这个回调函数的作用就是:更新state
    // 只要state一更新,因为是响应式的,所以页面就重新渲染了。
    // state参数:状态对象
    // value参数:上一环节传过来的数据
    PLUS_ONE(state, value){
        state.num += value
    }
}

// 等同于Vue当中的data(只不过这里我们不叫做数据,叫做状态)
// 状态对象(数据对象),已经做了响应式处理的。
const state = {
    num : 0
}

// 简写形式
export default new Vuex.Store({actions,mutations,state})


/* // 创建store对象(这个store对象是vuex插件中的老大,最核心的对象,这个对象store是用来管理actions对象、mutations对象、state对象。)
const store = new Vuex.Store({
    // 它是一个负责执行某个行为的对象
    actions : actions,
    // 它是一个负责更新的对象
    mutations : mutations,
    // 它是一个状态对象
    state : state
})

// 导出store对象(暴露之后,别人想用可以使用import进行引入)
export default store */
//main.js
import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

// 引入Vuex插件中的核心对象store
import store from './vuex/store'

new Vue({
  el : '#app',
  // 一个全新的配置项,以前没有学过:store
  // 加上这个配置项之后,vm以及所有的vc对象上都会多一个属性:$store
  // 以后通过vm.$store或者vc.$store来获取store对象。
  //store : store,
  store,
  render : h => h(App),
})

 

 Vuex配置项-getters

在Store.js里边写

 拓展运算符。。。

 拆括号,值得注意的是,拆了再加,会改变地址,不是原先那个。

可以用这种方法将相同的合并

Vuex内置对象-mapState映射State

这个对象能将State里的对象名与组件中的对象名联系起来,省去复杂的state调用

引用mapState

 实际上实现是这样的

 还记得上边的扩展...吗,他来了

 

 V-model不能使用mapGetters,因为在text里设计到改值,必须要有set方法

 mapAction和mapGetters

 上边的savesUser分别对应函数名和action里对应的函数名,也是连接作用

Vuex模块化

 在组件里想要使用state里的属性值有些变化

 需要连点bModel,在点b

 开启模块命名空间

由于在mutations里的函数可以自己去$store标签下找,没有了模块的束缚,这可能发送重名函数调用的风险。所以有了namespaced:true

 这条指令开启后,以后访问都以“模块名/函数名”来访问

 在mapaction和mapGetters等里还得加模块名参数

 路由

 实现单页面web,局部刷新,不需要跳转其他页面

路由工作原理

 

下载rout插件 

导入路由

 配置路由

 

 使用路由

路由视图,起到一个占位的作用

 

 多级路由

 子路由

  如果子路由写了‘/’,to后面不能带父路由

 query传参方式

 params方式传参

字符串形式

 

 :用来表示传递的是参数,不是路径

字符串形式和对象形式

 优化代码-props配置项,路由专属

props

 浏览器的后退和前进

和栈有关,

 

 声明式路由导航

编程式路由导航,按钮也能用

 

 路由组件的销毁

可以在Keep-alive标签添加 include=‘组件名’

什么时候被销毁?

切换时被销毁

 路由另外两个钩子

 定时器

 

 切到这个组件时激活activated切走的时候激活deactivated

 路由多两个

路由守卫

本身就是在不同时机的不同位置添加代码

守卫是在切换组件之前查权,有没有权限访问这个组件

像过滤器一样

1.全局前置路由守卫

 可以用一个布尔属性来鉴权,在对应的路由对象中使用meta属性来自定义属性

 全局后置路由守卫

在创建router后,暴露前

 前置后置

 局部守卫

 path

 component

 前端打包

详情请见p142

hash带#

#号后边是hash值,不会当做请求路径

 history

 刷新会将整个当做请求路径发送到服务器上

如何解决?

需要后端解决

在WEB-INF的web.xml里配置,当发生404报错时,自动跳转到index.html界面

 

 Vue3

 以前2是用vue-cli脚手架创建的,又开发了一个新的脚手架create-vue(vite)

 

 更新

 vite打包更快,启动服务器更快

简单回顾Vue2的响应式处理

 Proxy底层

 

 proxy底层使用了Reflect反射机制

setup中没有this

Vue3语法

setup函数

 不用像以前一样写data,methods函数了,函数里可以获取到其他属性值,eg:name和age

setup还有个返回值,必须写

 整体

 

渲染函数

 正常在setup修改属性值不会有响应式

通过Vue3内置ref函数来实现响应式

RefTmpl对象中的Value属性具有响应式,底层使用了数据代理和数据劫持机制,也就是Vue2的响应式

 

 替代品

 .value会自动调用,不需要写,只写nameRefImpl即可

ref通常比较适合基本类型,reactive适合对象

 

 reactive函数,专门用于对象类型响应式

 reactive函数,生成响应式

可以对属性的增删改响应式,对数组也可以实现响应式

 props

 props不能随便修改,不需要return

Vue3生命周期

 

 组合是在setup里写

Vue3全局事件总线

绑定

 

触发

 清楚所有事件

 解绑指定 

 计算属性computed

回顾一下Vue2

 Vue3写法

 计算属性

 watch里边是proxy

 ref数据

 同时监视多个属性

 

 感觉Vue3就是 let 函数名 = ?

watch

 如果是监听对象的话可以这么写

 一个箭头函数变化的细节影响了deep属性的启用

 只有监视对象是属性时,oldValue才能拿到

当ref包装对象时如何监听

 Vue3新增-watchEffect

 组合式,直接在setup使用

 比较像watch[数组]版,只要函数里边的内容有变化就会执行

Vue3自定义函数hook,为了实现代码复用

 导入sum函数

 自定义SUM函数

 

shallowRef

浅层次的响应式,就是没有响应式的效果,不会更改,在数据与原版没有区别

 shallowReactive

只有第一层对象有响应式,第二次以后都没有了

 readonly和shallowreadonly,深层只读,浅层只读

 响应式数据判断

 toRef和toRefs

为了使代码更加简洁,可以将对象省略比如data.counter在胡子语法里可以省略为counter,只能省略第一层

正常写不能成功建立响应式,需要以上两个函数

 toRef

 

toRefs

 

 

 研究一下Vue3中template标签如何解决可以有多个根标签的,应该是加了一个虚拟根节点吧

确实加了一个Fragment

 

 可以将一个组件发送到指定的标签位置,达到远距离传送到效果

 隔代数据传递

provide 提供 用于祖宗组件使用,实现数据传递

 

 inject注入 用于子组件,也是响应式

 有点像import和export

自定义ref

目标:输入后1秒在页面显示输入的Value

使用watch监听实现

 使用自定义ref实现
Vue3中有一个自定义ref组件,你可以使用他来实现,

说一句防抖机制,避免大量信息爆发式输出,影响影响性能

 

 

 

 好麻烦

Vue3小结-语法糖

setup可以写在script标签里,它将最外层的script标签当做以前setup的大括号  

 之前在setup外的component组件也不用写了,直接在标签里导入组件就可以了

 

posted @ 2024-09-24 20:44  22软工冷薄  阅读(19)  评论(0编辑  收藏  举报