VUE 学习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
export default{
name: 'hello',
data(){
return{
message: "111"
}
},
methods:{
fun1(event){
//在事件中,读取data的数据。需要通过this
//event 为dom原生event
this.message = "222"
}
}
}

1、模板语法

文本插值

支持单个js表达式

在textarea中不支持,使用v-model

1.1 原始HTML

渲染标签

v-html

不能修改属性

v-bind

修改属性 可以简写成 :

1
2
3
4
<div>{{text}}</div>
<div v-html = "text"> </div>
<div v-bind:id = "id"></div>
<div :id = "id"></div>

2、列表渲染

v-for

1
2
3
<ul>
<li v-for = "item in items" :key = "item.id">{{item}} </li>
</ul>
2.1 维护状态

就地策略

通过key比对每个数据

3、事件处理

v-on / @

1
<button @click = "fun1"> </button>

4、表单输入绑定

v-model 双向绑定数据

v-model是语法糖 可以解构为

1
<input :value = "value" @input = "value = $event.target.value " />
  • .lazy

    在change后获取

  • .trim

    去掉首尾空格

  • .number

    自动转换为数字

5、computed计算属性

是一个属性,封装一个计算过程

6、watch监听函数

当数据修改就会执行

7、生命周期

  • 创建
  • 挂载
  • 更新
  • 销毁

8、组件基础

三大组成部分

  • 结构

    只有一个根元素(vue2)

  • 样式

    默认全局样式

    使用scoped设置局部样式

  • 逻辑

    el 根实例独有

    data是一个函数

    其他配置项一致

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<template>
<div>
</div>
</template>

<script>
export default {
data(){
return {
xxx: xxx
}
}
}
</script>

<style>
</style>
8.1 组件化开发与根组件
8.2 局部组件和全局组件
8.3 组件样式
  • 默认的style样式,会作用于全局

  • 加上scoped属性的style样式,只会作用于当前组件

  • scoped原理

    • 当前组件内标签都被添加data-v-hash值的属性
    • css选择器都被添加[data-v-hash值]的属性选择器
8.4 data是一个函数

一个组件的dta选项必须是一个函数。保证每个组件实例,维护独立的一份数据对象。

每次创建新的组件实例,都会新执行一次data函数,得到一个新对象。

9、组件通信

组件数据是独立的,无法直接使用其他组件的数据

  • 父子关系
  • 非父子关系
9.1 父子关系
  • 父传子

    props

    数组和对象必须使用工厂模式进行返回

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <!-- 父组件-->
    <Son :title = "myTitle"></Son>

    <!-- 子组件-->
    <div>
    我是{{title}}
    </div>
    <script>
    export default{
    props:['title']
    }
    </script>


  • 子传父 自定义事件

    $emit

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    <!-- 子组件-->
    <div>
    我是{{title}}
    <button @click="handleClick">22</button>
    </div>
    <script>
    export default{
    props:['title']
    methods:{
    handleClick(){
    this.$emit('changeTitle', xxx)
    }
    }
    }
    </script>

    <!-- 父组件-->

    <Son :title = "myTitle" @changeTitle = 'changeFn'></Son>

    <script>
    export default {
    data(){
    return {
    myTitle: xxx
    }
    },
    methods:{
    changeFn(newTitle){
    this.myTitle = newTitle
    }
    }
    }
    </script>
9.2 prop

prop定义:组件上注册的一些自定义组件

prop作用:向子组件传递数据

可以传递任意数量,任意类型的数据

props校验

  • 作用:为组件的prop指定验证要求,不符合要求,控制台就会有错误提示,帮助开发者,快速发现错误
  • 语法
    • 类型校验
    • 非空校验
    • 默认值
    • 自定义校验
9.3 非父子关系
  • provide & inject
    • 跨层级共享数据
    • 简单数据非响应式
    • 复杂类型响应式
  • eventbus
    • 创建一个都能访问到的事件总线(空VUE实例)
    • 接收方监听事件总线的事件
    • 发送方触发事件总线的事件
9.4 通用解决方案-Vuex

状态管理工具

管理组件之间的数据交互,提供一个集中式的管理方式,任何组件都可以按照指定的方式读取和改变数据

优点:

  • 共同维护一份数据,数据集中化管理
  • 响应式变化
  • 操作简洁

通过{{$stroe.state.xxx}} 引用仓库中的数据

可以通过计算属性和mapState来简化获取数据的写法

Vuex遵循单向数据流,组件中不能直接修改仓库的数据

通过mutations修改state数据, mutations必须是同步的

在mutations中封装修改数据的方法

通过this.$store.commit('方法名')调用mutations中封装的方法

可以通过mapMutations简化写法

通过actions处理异步操作

在actions中封装方法

页面中用dispatch调用actions中的方法

可以通过mapActions简化写法

getters

除了state之外,有时我们还需要从state中派生出一些状态,这些状态是依赖state的,此时会用到getters

可以通过store访问

也可以通过mapGetters映射

10、v-model

v-modelz本质上是一个语法糖。例如应用在输入框上,就是value属性和input事件的合写。

10.1 表单类组件封装
  • 父传子 数据应该由父组件传递过来,v-model 拆解绑定数据
  • 子传父: 监听输入,子传父传值给父组件修改
10.2 v-model简化

父组件用v-model绑定

子组件用value接收

事件用input触发

11、.sync修饰符

可以实现子组件和父组件的双向绑定

prop属性名可以自定义,非固定为value

事件用updata:属性名触发

12、ref 和 $refs

用于获取dom元素或者组件实例

特点: 查找范围 当前组件内

使用:

  • 目标标签添加ref = “refName”
  • 通过 this.$refs.refName
  • 如果是组件,可以通过this.$refs.refName.组件内方法() 调用组件内方法

13、Vue异步更新、$nextTick

Vue是异步更新的,为了减少dom的操作

所以一些连续的动作会出现问题,比如出现一个输入框并获取焦点

this.$nextTick(函数体) 函数会在更新dom后再执行

14、自定义指令

自己定义的指令,可以封装一些dom操作

  • 全局注册

  • 局部注册

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    <!-- 全局注册-->
    Vue.directive('指令名', {
    inserted(el, binding){
    //具体内容
    }
    })
    <!-- 局部注册-->
    directives: {
    指令名: {
    <!-- 元素被添加进页面-->
    inserted(el, binding){
    //具体内容
    },
    <!-- 指令的数据变化之后-->
    updata(el, binding){

    }
    }
    }

    可以通过等号的形式为指令绑定具体的参数值

    通过binding.value 在代码中获取参数值

15、插槽

让组件内部的一些结构支持自定义

默认插槽

使用:

  • 在需要定制的地方通过<slot></slot>占位
  • 在使用组件时在组件标签内填入内容

后备内容

  • <slot></slot> 中设置默认内容

具名插槽

一个组件内有多个结构需要自定义

<slot name = ‘name’></slot>

<template v-slot:name></template>

简写

<template #name></template>

作用域插槽

定义插槽时,可以同时传值

  1. 给slot标签添加属性

<slot name = ‘name’ :id = "item.id" msg = "msg"></slot>

  1. 将所有属性作为一个对象传递
  2. 通过template接收 默认插槽的名字为default

<template #name = "obj"></template>

16、单页面应用程序

所有功能在一个html页面上实现

优点:

  • 按需更新性能高
  • 开发效率高
  • 用户体验好

缺点:

  • 学习成本高
  • 首屏加载慢 (按需加载)
  • SEO差 搜索引擎优化差

17、路由 Vue Router

管理页面之间的关系,完成单页面的应用

路径与组件之间的映射关系

步骤:

  • 下载

    yarn add vue-router@3.6.5

  • 引入

    import VueRouter from 'vue-router'

  • 注册 插件初始化

    Vue.use(VueRouter)

  • 创建路由对象

    const router = new VueRouter()

  • 注入

    1
    2
    3
    4
    new Vue({
    render: h => h(App),
    router
    }).$mount('#app')
  • 创建需要的组件,配置路由规则

  • 配置导航,配置路由出口(路径匹配的组件显示的位置)

17.1 声明式导航

<router-link to = ''></router-link>

router-link 会自动给当前导航添加了两个高亮类名

router-link-active 模糊匹配,/my /my/a /my/b

router-link-exact-active 精确匹配 /my

可以定制类名

1
2
3
4
5
const router = new VueRouter({
routes:[],
linkActiveClass: 'active', //router-link-active
linkExactActiveClass: 'exact-active', //router-link-exact-active
})
17.2 声明式导航-传参
  • 查询参数传参(适合多个参数)

    to = "/path?参数名=值"

    $route.query.参数名

  • 动态路由传参

    path: '/search/:id?' 加问号可以不带参数

    $route.params.参数名

17.3 重定向

匹配到前面的 跳转到后面

path: '/', redirect: '/home'

17.4 404

当路径找不到匹配时,给个提示页面

配在路由最后

path: '*', component: NotFound

17.5 模式设置
  • hash路由(默认)
  • history路由(常用)
17.6 编程式导航
  • path路径跳转

    this.$router.push('路由路径')

    完整写法(更适合传参)

    this.$router.push({path: '', query:{}})

  • 通过命名路由跳转

    this.$router.push({name: ''})

VUE3 新特性

六大亮点

  • Performance :性能更强
  • 将无用模块剪辑,仅打包需要的
  • 组合api !
  • Fragment Teleport Suspense
  • 更优秀的TS支持
  • 暴露了自定义渲染API
ref/reactive
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import { ref } from "vue" 
export default{
name: 'hello',

props:{
msg: String
}
// 组合api
// 没有this
setup(props, ctx){
console.log(props.msg)
const message = ref("222")
const names = reactive({
list:[1,2,3]
})

function clickFun(){
//需要用value
message.value = "333"
}

return {
message
names
}
}
}

在setup中可以使用生命周期函数,在前面加一个on,

优势:可以使用多个

provide/Inject

只能从父组件往子组件传 不限层级

父用 provide(key, value)

子用 value = inject(key)