专业的编程技术博客社区

网站首页 > 博客文章 正文

「前端Vue学习系列」三、Vue进阶篇

baijin 2024-10-09 07:57:37 博客文章 8 ℃ 0 评论

Hi,大家好,我是希留。

上篇文章带大家了解了Vue的一些基础用法,仅仅掌握一些基础的用法是不够的,还需要有更深入的了解,所以今天的文章咱们来聊聊Vue的进阶篇,废话不多说,开始燥起来!

一、组件

组件(Component)是 Vue.js 最强大的功能之一。它可以扩展 HTML 元素,封装可重用的代码。

组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树:


为了能在模板中使用,这些组件必须先注册以便 Vue 能够识别。这里有两种组件的注册类型:全局注册局部注册

在注册一个组件的时候,我们始终需要给它一个名字。而定义组件名的方式有两种:kebab-case(短横线分隔命名)PascalCase(首字母大写命名)

使用短横线分隔命名定义一个组件时,例如:'my-component-name',则必须在引用这个自定义元素时使用短横线分隔,例如 <my-component-name>。当使用首字母大写命名定义一个组件时,例如:'MyComponentName'你在引用这个自定义元素时两种命名法都可以使用。即<my-component-name><MyComponentName> 都是可接受的。

1.1 局部组件

使用局部注册的组件就叫局部组件,示例如下(代码接上篇例子,如有需要,可私信我)

<template>
  <div class="hello">
    ...
		<!--使用组件-->
    <Navbar></Navbar>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
    //定义局部组件,这里可以定义多个局部组件
  components: {
    //组件的名字
    'Navbar': {
      //组件的内容
      template: '<ul><li>首页</li><li>学员管理</li></ul>'
    }
  },
  ...
}
</script>


可看到页面已渲染出数据,说明组件注册成功。

1.2 全局组件

使用Vue.component创建的组件就叫全局组件,它们在注册之后可以在任何新创建的 Vue 根实例 (new Vue) 的模板中使用。

Vue.component('component-a', { /* ... */ })
Vue.component('component-b', { /* ... */ })
Vue.component('component-c', { /* ... */ })

new Vue({ el: '#app' })
<div id="app">
  <component-a></component-a>
  <component-b></component-b>
  <component-c></component-c>
</div>

二、自定义指令

除了默认设置的核心指令( v-model 和 v-show ), Vue 也允许注册自定义指令。也分为全局注册局部注册

示例代码如下:

// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
  // 当被绑定的元素插入到 DOM 中时……
  inserted: function (el) {
    // 聚焦元素
    el.focus()
  }
})
<template>
  <div class="hello">
    ...
		<input v-focus />
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
   // 注册局部自定义指令
  directives: {
    focus: {
      // 指令的定义
      inserted: function (el) {
       // 聚焦元素
        el.focus()
      }
    },
  ...
}
</script>

实现效果如下,输入框自动获取到了焦点。

Vue 提供了自定义指令的5个钩子函数:

  • bind:指令第一次绑定到元素时调用,只执行一次。在这里可以进行一次性的初始化设置。
  • inserted:被绑定的元素,插入到父节点的 DOM 中时调用(仅保证父节点的存在)。
  • update:组件更新时调用。
  • componentUpdated:组件与子组件更新时调用。
  • unbind:指令与元素解绑时调用,只执行一次。

三、Vue实例的生命周期

每个 Vue 实例从创建、数据初始化、挂载、更新、销毁的过程,就是所谓的生命周期,同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。

比如 created 钩子可以用来在一个实例被创建之后执行代码,也有一些其它的钩子,在实例生命周期的不同阶段被调用,如 mountedupdateddestroyed生命周期钩子的 this 上下文指向调用它的 Vue 实例。不要在选项 property 或回调上使用箭头函数,因为箭头函数并没有 this。

官方的图示如下,可以看到各钩子函数执行的时机。

代码示例如下:

<template>
  <div class="hello">
    ...
		<button @click="update">update</button>
    <h3 id="h3">{{ message }}</h3>

  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
     ...
      message: '床前明月光'
    }
  },
    methods: {
    ...
    show() {
      console.log('执行show方法')
    },
      update() {
    this.message = '玻璃好上霜'
    }
  },
   //===创建时的四个事件
 
    beforeCreate() { // 第一个被执行的钩子方法:实例被创建出来之前执行
    
      // beforeCreate执行时,data 和 methods 中的 数据都还没有没初始化
    console.log(this.message) //undefined
    this.show() //TypeError: this.show is not a function
   
  },
  created() { // 第二个被执行的钩子方法
    // created执行时,data 和 methods 都已经被初始化好了!
    // 如果要调用 methods 中的方法,或者操作 data 中的数据,最早,只能在 created 中操作
    console.log(this.message) //床前明月光
    this.show() //执行show方法
    
  },
  beforeMount() { // 第三个被执行的钩子方法
     // beforeMount执行时,模板已经在内存中编辑完成了,尚未被渲染到页面中
    console.log(document.getElementById('h3').innerText) //{{ message }}
   
  },
  mounted() { // 第四个被执行的钩子方法
    console.log(document.getElementById('h3').innerText) //床前明月光
    // 内存中的模板已经渲染到页面,用户已经可以看见内容
  },
    
//===运行中的两个事件
  beforeUpdate() { // 数据更新的前一刻
    console.log('界面显示的内容:' + document.getElementById('h3').innerText)
    console.log('data 中的 message 数据是:' + this.message)
    // beforeUpdate执行时,内存中的数据已更新,但是页面尚未被渲染
  },
  updated() {
    console.log('界面显示的内容:' + document.getElementById('h3').innerText)
    console.log('data 中的 message 数据是:' + this.message)
    // updated执行时,内存中的数据已更新,并且页面已经被渲染
  }
}
</script>

四、路由

路由就是允许我们通过不同的 URL 访问不同的内容。Vue Router 是Vue.js的官方路由器它与 Vue.js 核心深度集成,使使用 Vue.js 构建单页应用程序变得轻而易举。

Vue.js 路由需要载入 vue-router 库

代码示例如下:

1、先导入vue-router库,编写路由

import Vue from 'vue'
//导入vue-router库
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import HelloRouter from '@/components/HelloRouter'

//使用vue.use来注册使用Router插件
Vue.use(Router)

// 注意:在路径上加上‘/’表示从根目录开始跳转,  不加‘/’表示从当前页面进行跳转
export default new Router({
  routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld
    },
    {
      path: '/router',
      name: 'HelloRouter',
      component: HelloRouter
    },
  ]
})

2、使用路由跳转

<template>
  <div id="app">
    <img src="./assets/logo.png">

    <p>
      <!-- 使用 router-link 组件来导航. -->
      <!-- 通过传入 `to` 属性指定链接. -->
      <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
      <router-link to="/">首页</router-link>
      <router-link to="/router">路由跳转</router-link>
    </p>
    <!-- 路由出口 -->
    <!-- 路由匹配到的组件将渲染在这里 -->
    <router-view></router-view>
  </div>
</template>

实现效果如下,可看到点击对应位置可进行跳转。

五、状态管理

由于状态零散地分布在许多组件和组件之间的交互中,大型应用复杂度也经常逐渐增长。为了解决这个问题,Vue 提供 vuex。

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

Vuex 可以帮助我们管理共享状态,但同时也附带了更多的概念和框架,如果您不打算开发大型单页应用,Vuex 可能是繁琐冗余的,所以需要视项目的复杂度情况而酌情使用。

Vuex包含5个核心概念:State、Getters、Mutation、Actions、Modules

(1)State

单一状态树。Vuex 使用单一状态树,用一个对象就包含了全部的应用层级状态,每个应用将仅仅包含一个 store 实例。

(2)Getters

Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。

(3)Mutations

更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler),所以mutation 必须是同步函数。

(4)Actions

Action 类似于 mutation,不同在于:

  • Action 提交的是 mutation,而不是直接变更状态。
  • Action 可以包含任意异步操作。

(5)Modules

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块。

代码示例如下:

1、先新建一个store目录,编写store.js文件

import Vue from 'vue'
import Vuex from 'vuex'

//使用vue.use来注册使用Vuex插件
Vue.use(Vuex)

export default new Vuex.Store({
  //要设置的全局访问的state对象
  state: {
    //要设置的初始属性值
    count: 0,
  },

  //实时监听state值的变化(最新状态)
  getters: {
    getCount(state) {
      return state.count
    },
  },

  mutations: {

    addCount(state, num) {
      state.count = state.count + num
    },

    delCount(state, num) {
      state.count = state.count - num
    },

  },
})

2、在main.js里面挂载store


3、在页面上使用

<template>
  <div class="hello">
    ...

    <h3>我是从state上获取到的count:{{this.$store.state.count}}</h3>
    <h3>我是从getters上获取到的count:{{this.$store.getters.getCount}}</h3>
    <h3>我是从...mapState上获取到的count:{{count1}}</h3>
    <h3>我是从...mapGetters上获取到的count:{{getCount}}</h3>

    <!--修改 count 值的操作部分-->
    <button @click="add">+</button>
    <button @click="del">-</button>

  </div>
</template>
<script>
  //引入axios
  import axios from 'axios'
  //使用vuex的辅助函数,需要引入
  import {mapState, mapGetters, mapActions} from 'vuex'

export default {
  name: 'HelloWorld',
  ...
    add() {
      this.$store.commit('addCount',1)
    },

    del() {
      this.$store.commit('delCount',1)
    }
  },

 computed: {
      // 通过配合 ... 拓展符号
   ...mapState({
     count1: state => state.count
   }),
   ...mapGetters(['getCount'])
  },

}
</script>

实现效果如下:

使用vuex需要注意的地方是:js是运行在内存中的,当页面刷新时,页面会重新加载vue实例,vuex里面的数据就会被重新赋值。解决思路:将state对象存入到sessionStorage/localStorage中。

六、axios

axios是独立于vue的一个项目,基于promise用于浏览器和node.js的http客户端,有如下用途

  • 在浏览器中可以帮助我们完成 ajax请求的发送
  • 在node.js中可以向远程接口发送请求

代码示例如下:

<script>
  //引入axios
  import axios from 'axios'

export default {
  name: 'HelloWorld',
 
  methods: {
 
    getAnswer() {
      var vm = this
      //发送get请求
      axios.get('https://yesno.wtf/api')
        .then(function (response) {
          vm.answer = _.capitalize(response.data.answer)
        })
        .catch(function (error) {
          vm.answer = '网找不到API接口. ' + error
        })
    },
    updateAnswer(){
      // 发起一个post请求
      axios({
        method: 'post',
        url: 'http://localhost:8082/admin/edu/teacher/' + this.teacher.teacherId,
        data: this.teacher
      }).then(function (response) {
        console.log(response)
        console.log('修改成功')
      }).catch(function (error) {
        console.log(error)
      })
    },
  },

}
</script>

七、总结

好了,以上就是今天要讲的内容,本文大致介绍了Vue的生命周期、组件、自定义指令以及一些工具库的使用,相信大家对Vue有了更深一步的认识了,学会了这些基本就可以进行项目的实操了,通过真实的项目再加深自己的使用和理解,才能在工作当中游刃有余。

感谢大家的阅读,如若有不足之处,还请多多包涵,欢迎评论区留下独到的见解,感谢[玫瑰]

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表