vue2学习笔记

58 阅读8分钟

vue是一个用于 构建用户界面渐进式 框架


1.vue指令

v-前缀,Vue会根据不同的指令实现不同的功能

  1. v-html:设置元素的innerHTML

  2. v-if和v-show:控制元素显示隐藏

    区别:v-show是控制display:none来实现显示隐藏的,适合频繁切换显示隐藏的场景

  3. v-if是创建/删除DOM元素来实现显示隐藏的,适合初始状态就确定显示隐藏的场景

  4. v-else和v-else-if:v-if的多分支结构,v-else必须紧贴着v-if或v-else-if,中间不能间隔其他元素,注释除外

  5. v-on(简写 @):绑定事件

    内联语句

    绑定事件处理函数

  6. v-bind(简写 :):动态设置HTML属性

  7. v-for:

    循环渲染标签元素 v-for="(item, index) in list"

    key属性:唯一标识 :key="item.id"

  8. v-model:主要用于表单元素的双向数据绑定 v-model="vue 变量"

2.指令修饰符

  1. 按键修饰符:

    键盘事件 @keyup @keydown

    .enter表示按下enter键

    <input @keyup.enter="login" v-model="username" type="text">
    methods:{
        login() {}
    }
    
  2. v-model修饰符:

    <input  v-model.trim ="username" type="text">
    <input  v-model.number ="username" type="text">
    
  3. 事件修饰符:

    @事件名.stop 阻止冒泡

    @事件名.prevent 阻止默认行为

3.动态class

  1. 设置对象:是否应用该类名

    :class="{class1:true/false}"
    
  2. 设置数组:一次性设置多个类名

    :class="[class1,class2]"
    

4.动态style

:style="{css属性名:css属性值}"

5.v-model用于其他表单元素

文本框:value

复选框:绑定数据是boolean--checked,绑定的数据是数组--将value添加到数组

单选框:value

下拉框:value

文本域:value

6.computed计算属性

依赖现有数据进行计算得出结果,必须同步计算结果,因为计算属性必须要有返回值

特性:带缓存,在第一次使用该属性时进行计算,计算后将结果缓存起来,后面如果还有其他地方用到,会直接从缓存中取值,不会再次计算。如果依赖的数据更新,也会重新计算,然后重复上述操作。

简单写法:

computed:{
    计算属性名(){
        一段代码逻辑(计算逻辑)
        return 结果
    }
}

完整写法:

computed:{
    计算属性名: {
        //get方法就是简单写法的函数
        get() {
            一段代码逻辑(计算逻辑)
            return 结果
        },
        //设置,当修改这个计算属性时,set函数会自动执行,并将新值作为参数传递过来
        set(修改的值) {
             一段代码逻辑(修改逻辑)
        }
    }
}

7.watch侦听器

监视数据变化,执行一些 业务逻辑异步操作

简单写法:

  1. 监视数据:

    watch:{
        数据名(newValue,oldValue) {
            //函数会在数据被修改自动执行
    }
    
  2. 监视对象的属性:

    watch:{
    	'obj.属性名'(newValue,oldValue) {
           //函数会在数据被修改自动执行
    }
    

完整写法:

watch: {
  对象名: {
	deep:true,//开启深度侦听
	immediate:true,//立即执行一次
	handler(newValue,oldValue){
		//函数会在数据被修改自动执行
	}
   }
 }

8.生命周期

  1. 概念:Vue实例从创建到销毁的过程

  2. 钩子函数:

    (1)创建:

    beforeCreat

    created:发请求,初始化渲染

    (2)挂载:

    beforeMount

    mounted:操作DOM

    (3)更新:

    beforeUpdate

    updated

    (4)销毁:

    beforeDestory

    destoryed

9.工程化开发

  1. 脚手架

    重要文件:

    main.js:引入App.vue,基于App.vue创建元素,将元素挂载到#app盒子中

    App.vue:根组件

    index.html:项目唯一网页

  2. 组件化:便于复用和维护

    组件的使用:

    局部注册:

    创建组件:创建一个.vue文件

    引入组件:import 变量名 from ‘路径’

    注册组件:compontents:{ 组件名:组件对象 }

    使用组件:<组件名></组件名>

    全局注册

    创建组件:创建一个.vue文件

    引入组件:import 变量名 from ‘路径’

    注册组件:在main.js中 Vue.compontents('组件名':组件对象)

    使用组件:<组件名></组件名>

10.组件通信

props和emit

11.v-model原理

v-model 可以实现数据的双向绑定,它的本质是一个语法糖,也就是v-bind和v-on的结合使用,v-bind负责将数据传递给表单控件,而v-on则监听控件的输入事件,以确保数据可以实时反映在Vue实例上。

  1. v-model局限性:

    据名必须叫value

    2.事件名必须叫input
    
    3.一个标签只能使用一次v-model
    
  2. 解决v-model的局限性

    使用.sync修饰符 本质就是:属性名和@update:属性名的合写

12.组件封装使用

Element-ui: 组件 | Element

$ref.name 获取名为name的dom元素

$nextTick 是将回调函数延迟在下一次dom更新数据后调用,简单的理解是:当数据更新了,在dom中渲染后,自动执行该函数

13.自定义指令

(自定义指令也是一种封装思想的体现,将一段DOM操作封装到自定义指令中)

  • bind:指令第一次绑定到元素时,仅执行一次;
  • inserted:指令绑定元素并插入到父节点时,执行一次;
  • update:指令所在的组件更新时,可能会执行多次;
  • componentUpdated:指令所在的组件和它的子组件更新时,可能会执行多次;
  • unbind:指令和元素解绑时,仅执行一次。
  1. 全局注册

    语法:

    Vue.directive('指令名',{
    	inserted(el) {
    		el.focus()
    	}
    })
    
  2. 局部注册

    directives: {
        color: {
          //inserted 会在元素插入到 DOM 时执行
          //1.参数1,指定绑定的元素对象
          //2.参数2,指令相关的值
          inserted(el, binding) {
            el.style.color = binding.value
          }
        }
      }
    

14.插槽

当组件内某一部分结构不确定,需要自定义时使用插槽技术。

  1. 默认插槽使用方法:

    1. 在子组件使用slot标签占位
    2. 在使用组件时,传入具体标签内容插入
  2. 插槽的默认值:默认值(后备内容)

    . 具名插槽 :

    1. slot占位,给name属性起名字来区分
    2. template配合v-slot:插槽名 分发内容

    v-slot:name <====> #name

  3. 作用域插槽:

    作用:可以给插槽上绑定数据,供将来使用组件时使用

    步骤:

    1. 给slot标签,以添加属性的方式传值
    2. 所有属性都会被收集到一个对象中
    3. template中,通过‘#插槽名=“obj”’接受

15.路由

概念:

  1. 单页应用程序--SPA(Single Page Application):将所有功能在一个HTML页面中实现 (1)优点:性能高,用户体验好,开发效率高

    (2)缺点:首页加载慢,学习成本高,不利于SEO

  2. 路由:路径和组件的映射关系

16.声明式导航

router-link本质是a标签

作用:

  1. 可以实现跳转并自动添加#
  2. 实现导航高亮,会自动添加类名

导航高亮:

  1. router-link-active 模糊匹配
  2. router-link-exact-active 精确匹配

自定义高亮类名:在创建VueRouter对象时传入配置

  1. linkActiveClass
  2. linkExactActiveClass

*传参:

  1. query传参

    <router-link to="/路径?参数名1=参数值1&参数名2=参数值2"></router-link>
    

    接收$route.query.参数名

  2. 动态路由传参(配置路由参数)

    { path:'/路径/:参数名', component: 组件对象 }
    
    <router-link to="/路径/参数值"></router-link>
    

    接收$route.params.参数名

重定向:{ path: '/', redirect: '/home' }

404页面:{ path: '*', component: 组件对象 }

路由模式(在创建VueRouter对象时传入配置):

  1. hash:默认模式,路径有#
  2. history:路径没有#,但需要后端支持

17.编程式导航

使用js进行路由跳转

  1. path跳转语法:

    this.$router.push('路径')		
    this.$router.push({path:'路径'})
    
  1. name跳转语法:

    先给路由加上name:'name',再

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

路由传参:

  1. path

    (1) path + query 传参

    (手动拼接)

    this.$router.push('路径?参数名=参数值')
    

    (官方的API传参)

    this.$router.push({
    	path:'/path',
    	query:{
    		参数名=参数值
    	}
    })
    

    使用this.$route.query.参数名接收

    (2) path + 动态路由传参(先配置路由参数)

    this.$router.push(`/path/${this.words}`)
    

    使用this.$route.params.参数名接收

  2. name(需要提前配置name)

    (1) name + query 传参

    (手动拼接)

    this.$router.push('路径?参数名=参数值')
    

    (官方的API传参)

    this.$router.push({
    	name:'name',
    	query:{
    		参数名=参数值
    	}
    })
    

    使用this.$route.query.参数名接收

    (2) name + 动态路由传参(先配置路由参数)

    this.$router.push({
    	name:'name',
    	params:{
    		参数名=参数值
    	}
    })
    

    使用this.$route.params.参数名接收

18.Vuex

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

  1. 核心成员1: state

    作用: 存放数据

    1. data 是组件内的数据

    2. state 是 Vuex 的数据, 供所有组件访问

      访问方式: 方式1: 直接访问 store 对象 1.1 组件内: this.$store.state.count 1.2 非组件内: 先引入当前的 store 对象, store.state.count 方式2: 使用辅助函数 mapState 2.1 按需导入 mapState 2.2 调用 mapState 传入想映射的数据, 在 computed 中展开结果

    const store = new Vuex.Store({
      strict: true,//严格模式
      state: {
        count: 100,
        title: '大标题',
        list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
      },
    
  2. 核心成员2: mutations

    作用: 唯一操作 state 的途径,不能操作异步任务

    用法: mutations 就是一个对象, 里面可以定义很多函数, 在函数内操作 state

    1. 定义 mutations 函数
    2. 在组件中使用 this.$store.commit('函数名',变量)
    mutations: {
        // 所有的 mutations 函数第一个参数永远都是 state
        // 第二个参数永远都是 payload (载荷), commit 提交时携带的参数
        // mutations 的函数只有这两个参数, 如果需要携带多个参数怎么办? 传对象或数组
        addCount (state, n) {
          state.count += n
        },
        setCount (state, count) {
          state.count = count
        }
      },
    
  3. 核心成员3: actions

    作用: 专做异步任务,主要用于响应组件中的动作,通过commit()来触发mutation中函数的调用,间接更新state,不是必须存在的。

    在组件中使用 this.$store.dispatch('函数名',变量)

    actions: {
        // actions 函数的第一个参数永远都是 context 对象, 简化版的 store 对象, 它里面也有 commit 方法
        // 同样也有载荷 payload, 用法同 mutations
        setCountAsync (context, n) {
          setTimeout(() => {
            context.commit('setCount', n)
          }, 2000)
        }
      },
    
  1. 核心成员4: getters

    作用: Vuex 里的计算属性, 供所有组件访问的计算属性

    getters: {
        // 所有的 getters 第一个参数永远都是 state
        // 必须要有返回值
        filterList (state) {
          return state.list.filter(item => item > 5)
        }
      }
    

19.核心成员5: modules

  1. 为什么要使用modules ?

    *答:Vuex 是单一状态树,所有的数据都会存在一个 state 中,将来项目业务越来越多,store 的内容会越来越重,导致无法维护,所以最好的办法就是按照业务拆分成不同的模块来分别维护管理,每个模块都有自己的 state/mutations/actions/getters。

*1.建子模块的文件,默认导出一个对象,对象中需要具备 state/mutations/actions/getters 成员 *2.在 store/index.js 中使用 modules:{ 模块名:模块对象 } 注册子模块 *问题:默认情况下子模块所有 mutations/actions/getters 中的函数都挂载到全局,依然没有起到隔离的作用 *解决:开启命名空间namespaced:true *开启命名空间后,四个核心成员的使用方式发生了变化:

  • state

    1. 直接访问(不方便):this.$store.state.user.userInfo.name

    2. 辅助函数(推荐):

      按需引入辅助函数 import { mapstate } from 'vuex' 在 computed 中调用并展开结果 ...mapstate('模块名',['要映射的数据’])

  • mutations

    1. 直接调用:this.$store.commit('模块名/函数名')

    2. 辅助函数

      按需引入辅助函数 import { mapMutations } from 'vuex 在 methods 中调用并展开结果 ...mapMutations('模块名',['要映射的函数'])

  • actions

    1. 直接调用:this.$store.dispatch('模块名/函数名')

    2. 辅助函数

      按需引入辅助函数 import { mapActions } from 'vuex 在 methods 中调用并展开结果 ...mapActions('模块名',['要映射的函数’])

  • getters

    1. 直接访间(不方便):this.$store.getters['模块名/getter名']

    2. 辅助函数(推荐):

      按需引入辅助函数 import { mapGetters } from 'vuex

      在 computed 中调用并展开结果...mapGetters('模块名',['要映射的数据'])