【前端】Vue2.x 快速入门

探索vue2框架的世界:关于vue2.x的性能优化和常见的白屏原因 在本篇文章中,博主总结了一些常见的vue2框架性能优化方法和项目启动出现白屏的原因,还望走过路过的同行和大神们点赞关注,多多指教,用你们发财的小手给予博主大大的鼓励 阅读详情

Vue2.x 快速入门

快速且全量的Vue2.x入门参考,快来看看吧!

前言

最近发现身边的大佬都非常卷,个个都是全栈。作为后端渣渣,势必要走出舒适区,向大佬们学习全栈了。其中重要的一环便是前端技术栈。对于前端还没入门的我,决定从Vue2.x开始学习。

这篇博客是我看B站吴悠老师的视频做的笔记,吴悠老师讲得非常好,既有效率,又非常全面,视频链接在文末,非常感谢吴悠老师!

前提

  • 了解过 HTML 、 CSS、 JavaScript 基础三件套
  • 了解 Node.js, 会用 npm 、yarn 等工具对前端项目进行管理

学习目标

  • 快速学习 Vue2.x 特性
  • 快速学习 Vue2.x 相关语法,接下来能逐渐熟练使用并逐步拥有全栈的能力
  • 学习Vue2.x 为后续 Vue3.x、 React 等框架打下基础

1. Vue 项目创建

1.1 Script 标签引入

标签引入Vue,就可以直接使用了:

CDN方式

	<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>

vue.js
我们也可以直接从官网上下载 vue.js 或 vue.min.js

官网vue.js下载页面

	<!-- 引入Vue.js -->
    <script src="../public/vue.min.js"></script>

1.2 Vue-Cli 创建项目

首先保证自己本地/服务器有node。推荐使用nvm去管理我们的node。

安装 Vue 脚手架

  • 卸载已有的脚手架
npm uninstall vue-cli -g

出现以下类似结果即为成功

up to date in 80ms
  • 安装脚手架
npm install -g @vue/cli
  • 查看vue cli 版本
vue -V

# 或者使用
vue --version
  • 创建项目
    在目标文件夹,cmd 键入:
vue create [projectname]

例如,当前项目名是:

vue create kcl2024_background_front_end

之后会进入如下选择界面。

选择版本

Vue CLI v5.0.8
? Please pick a preset: (Use arrow keys)
> Default ([Vue 3] babel, eslint)
  Default ([Vue 2] babel, eslint)
  Manually select features

选择我们需要的版本,默认3、2或自定义。
接下来执行,根据提示选择,然后等待执行即可。

  • 尝试启动
    本地启动vue cli 创建的项目有如下几种方式,读者按需选用:

进入项目文件夹:

npm run serve

打包并启动:

npm run build

npm i serve -g

serve dist

ui方式:

vue ui

2. Vue2.x 语法

以下,跟着参考教程的步伐,我们快速了解一下 Vue2.x 的语法吧

2.1 插值表达式与响应式数据

响应式数据
响应式数据是一种机制,是指在数据发生变化后,更新依赖这些数据的部分,允许数据绑定和试图更新的自动化,为我们编写代码时省略DOM操作,提升开发效率。

插值表达式
使用此处示例的语法结构,就可用插值表达式将响应式数据渲染,如{{ data_name }}

举例
下面列举一个例子,使用插值表达式就能将title和content响应式数据渲染:

<div id="app">
        <!-- 插值表达式 -->
        <h1>{{ title }}</h1>
        <p>{{ content }}</p>
</div>
<script>
        // 创建Vue实例
        const vm = new Vue({
            // 1. 响应式数据与插值表达式
            // el : vue 实例的一个配置属性,指定了 Vue 实例要渲染的位置,可以是 CSS 选择器、HTML 元素或者是 HTMLElement 实例。
            el: '#app',
            data () {
                return {
                    title: '这是标题',
                    content: '这是内容'
                }
            },
        })
</script>

其中,插值表达式里也可以调用运算、方法等,例如:

<div id="app">
        <!-- 插值表达式 -->
        <h1>{{ title }}</h1>
        <p>{{ content }}</p>
        <!-- 自定义方法 -->
        <p>{{ description() }}</p>
</div>
<script>
        // 创建Vue实例
        const vm = new Vue({
            el: '#app',
            data () {
                return {
                    title: '这是标题',
                    content: '这是内容'
                }
            },
            // 方法,和data属性并列
            methods: {
                // 自定义方法
                description () {
                    return '标题:' + this.title + ',内容:' + this.content
                }
            },
        })
</script>

2.2 计算属性

<!-- 引入Vue.js -->
<script src="../public/vue.min.js"></script>
<div id="app">
        <!-- 对比计算属性与普通方法 -->
        <p>{{ computedTest }}</p>
        <p>{{ computedTest }}</p>
        <p>{{ computedTest }}</p>
        <p>{{ computedCompare() }}</p>
        <p>{{ computedCompare() }}</p>
        <p>{{ computedCompare() }}</p>
</div>
<script>
        // 创建Vue实例
        const vm = new Vue({
            el: '#app',
            data () {
                return {
                    title: '这是标题',
                    content: '这是内容'
                }
            },
            // 方法,和data属性并列
            methods: {
                computedCompare () {
                    console.log('methods方法被访问了')
                    return '这是methods方法的输出'
                }
            },
            // 2. 计算属性,可以缓存一些复杂的逻辑,避免每次调用都重复计算
            computed: {
                // 计算属性的 getter 函数返回一个值,这个值会根据它的依赖跟踪依赖的响应式数据,并自动更新
                // 计算属性的 setter 函数会在计算属性的依赖发生变化时调用,并传入新值作为参数
                computedTest () {
                    console.log('计算属性被访问了')
                    return '这是计算属性的输出'
                }
            }
        })
</script>

说明
计算属性只会在计算属性里面的响应式数据变动了之后再重新计算,如果数据没变就直接使用缓存的上次计算结果,提升了性能。因此在上述例子里我们可以从我们举例的log中去发现该例子的计算属性调用次数确实比methods调用次数要少。

另外,计算属性是属性,因此在调用的时候不需要像方法一样调用,而是使用属性的方式调用即可。

2.3 侦听器

侦听器是 Vue 给我们开放的一个功能,其目的是在我们对响应式数据进行操作的时候,可以做一些其它操作,方便我们对程序进行拓展。

举例

<div id="app">
        <!-- 插值表达式 -->
        <h1>{{ title }}</h1>
</div>
<script>
	const vm = new Vue({
            // 1. 响应式数据与插值表达式
            // el : vue 实例的一个配置属性,指定了 Vue 实例要渲染的位置,可以是 CSS 选择器、HTML 元素或者是 HTMLElement 实例。
            el: '#app',
            data () {
                return {
                    title: '这是标题',
                    content: '这是内容'
                }
            },
            watch: {
                // 监听器,可以监听数据的变化,并自动执行一些操作
                title (newVal, oldVal) {
                    console.log('监听器被访问了')
                    console.log('标题被修改了,新值:' + newVal + ',旧值:' + oldVal)
                }
            }
</script>

我们可以在f12控制台对上述例子的title进行修改,然后观察输出的值。

2.4 指令

这一小节介绍常见的Vue指令,也就是我们常见的v-for等。

内容指令
内容指令会覆盖掉标签里的内容。

<div id="app">
        <!-- 指令 -->
        <p v-text="title">此内容会被覆盖</p>
        <p v-text="htmlContent">此内容会被覆盖</p>
        <p v-html="htmlContent">此内容会被覆盖</p>
</div>
<script>
        // 创建Vue实例
        const vm = new Vue({
            // 1. 响应式数据与插值表达式
            // el : vue 实例的一个配置属性,指定了 Vue 实例要渲染的位置,可以是 CSS 选择器、HTML 元素或者是 HTMLElement 实例。
            el: '#app',
            data () {
                return {
                    title: '这是标题',
                    content: '这是内容',
                    htmlContent: '这是一个span标签:<span>这是内容,此标签会被v-html指令渲染</span>'
                }
            }
        })
</script>

渲染指令

  • v-for 循环:
    举例:
<!--    渲染指令    -->
<p v-for="item in arr">循环arr:{{item}}}</p>
<p v-for="(value, key) in obj">循环obj:{{key}}:{{value}}</p>
<p v-for="(value, key, index) in obj">循环arr:{{key}} : {{value}} : {{index}}</p>

data () {
          return {
                  arr: ['one', 'two', 'three'],
                  obj: {
                          name: '张三',
                          age: 20,
                          job: '前端工程师'
                    }
                 }
           },
  • v-if 与 v-show:
    举例:
<p v-if="bool">v-if指令渲染</p>
<p v-if="!bool">v-if指令不会渲染</p>
<p v-show="bool">v-show指令渲染</p>
<p v-show="!bool">v-show指令不会渲染</p>
    
data(){
	bool: true
}

注意,v-if 会决定元素是否销毁。一般在不需要销毁元素的场景,我们多数使用 v-show 来决定元素的显示。

属性指令

  • 属性绑定
    举例:
<!--    属性指令    -->
<p v-bind:title="title">v-bind指令绑定title属性</p>
<p :title="title">简写v-bind指令绑定title属性</p>

v-bind 还可以绑定 class、style等,例如:

<!--    属性指令 class    -->
<p v-bind:class="{ active: isActive }">v-bind指令绑定class属性</p>
<p :class="{ active: isActive }">简写v-bind指令绑定class属性</p>
<!--    样式指令    -->
<p v-bind:style="{ color: activeColor }">v-bind指令绑定style属性</p>
<p :style="{ color: activeColor }">简写v-bind指令绑定style属性</p>

事件指令
举例:

<!--    事件指令    -->
<button v-on:click="computedCompare">按钮触发事件</button>
<button @click="computedCompare">按钮触发事件</button>

表单指令
表单指令主要用于实现双向数据绑定。
举例:

<!--    表单指令:v-model, 双向数据绑定    -->
<input type="text" v-model="inoutValue">
<p>{{ inoutValue }}</p>

data () {
         return {
             inoutValue:'输入内容'
         }
},

修饰符
我们可以采用一些修饰符,来对我们的数据做一些处理。
举例:

<input type="text" v-model="inputValue">
<p>{{ inputValue }}</p>
<input type="text" v-model.trim="inputValue">

这个例子列举的trim是将两端空格去掉,读者可以参考着试一试。

3. Vue组件化开发

3.1 Vue Cli 项目结构

首先打开我们用Vue Cli创建的项目:
01

以下列举我们需要重点关注的项目结构:

  • dist: build后的文件,服务器里运行的是dist
  • node_modules: 所需依赖文件,npm install 的文件
  • public:保存一些不需要参与编译的资源
  • src:
    • assets: 参与编译的一些静态资源
    • components:自定义组件
    • router:路由
    • store: vuex 相关

3.2 Vue 文件结构

一般来说一个 Vue 的一个结构有三部分: template、script 和 style
例如HelloWorld.vue:

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <p>
      For a guide and recipes on how to configure / customize this project,<br>
      check out the
      <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
    </p>
    <h3>Installed CLI Plugins</h3>
    <ul>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router" target="_blank" rel="noopener">router</a></li>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex" target="_blank" rel="noopener">vuex</a></li>
    </ul>
    <h3>Essential Links</h3>
    <ul>
      <li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
      <li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
      <li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
      <li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
      <li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
    </ul>
    <h3>Ecosystem</h3>
    <ul>
      <li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
      <li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
      <li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
      <li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
      <li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

3.3 组件通信

组件化开发指的是一个vue页面可以由多个、存在父子关系的组件组成。这一小节介绍父子通信。

3.3.1 父组件传给子组件

例如,我们刚创建出来的Vue默认页面中,HelloWorld.vue是 HomeView.vue的子组件。

子组件中,通过<script>标签内的 props参数接收由父组件传递的参数,其中,props值的key是传递值的名字,value是接收类型,例如:

HomeView.vue

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png">
    <HelloWorld
        msg="Welcome to Your Vue.js App"
        count="5"
    />
  </div>
</template>

HelloWorld.vue

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <h1>Count: {{ count }}</h1>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  // 接收父组件传递的 msg、count 属性
  props: {
    msg: String,
    count: Number
  }
}
</script>

其中,props也可以一个key定义接收多个类型的值,同时,可以有默认值,举个例子:

HomeView.vue

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png">
    <HelloWorld
        msg="Welcome to Your Vue.js App"
        count="5"
        more="This is more text"
    />
  </div>
</template>

HelloWorld.vue

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <h1>Count: {{ count }}</h1>
    <h3>More: {{ more }}</h3>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  // 接收父组件传递的 msg、count 属性
  props: {
    msg: String,
    count: Number,
    more: {
      // 类型
      type: [Object, Array, String, Number],
      // 是否必填, 决定这个属性是否必须传递给组件
      required: true,
      // 默认值
      default: 100
    }
  }
}
</script>

执行效果
02

3.3.2 子组件传给父组件

使用自定义事件的方式将值传递给父组件,以下举例:

我们先在子组件定义一个数据,并给一个触发事件的按钮:
HelloWorld.vue

<template>
  <div class="hello">
    <button @click="increment">按钮</button>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  // 接收父组件传递的 msg、count 属性
  props: {
    childData: Number
  },
  data() {
    return {
      childDataCount:0
    }
  },
  methods: {
    increment() {
      this.childDataCount++
      // 触发父组件的 increment 事件,自定义事件
      this.$emit('increment', this.childDataCount)
    }
  }
}
</script>

接着,我们在父组件之间调用子组件的自定义事件,用于接收:

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png">
    <h1>父组件中接收到的数据: {{ childData }}</h1>
    <HelloWorld
        :childData="childData"
        @increment="handleClick"
    />
  </div>
</template>

<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'

export default {
  name: 'HomeView',
  components: {
    HelloWorld
  },
  data() {
    return {
      childData: 10
    }
  },
  methods: {
    // 子组件向父组件传递的数据
    handleClick(dataFromChild) {
      this.childData = dataFromChild
    }
  }
}
</script>

3.4 插槽

使用插槽可以让我们实现一些相同组件的一些不同显示,而不在组件中传参实现。

3.4.1 默认插槽

我们想让我们自定义的内容在组件标签内显示:

HomeView.vue

<template>
  <div class="home">
    <SoltDemo> 内容1 </SoltDemo>
    <SoltDemo> 内容2 </SoltDemo>
    <SoltDemo> </SoltDemo>
  </div>
</template>

SoltDemo.vue

<template>
  <div>
    <slot> Default slot content </slot>
  </div>
</template>

示例执行结果
03

3.4.2 具名插槽

我们在定义插槽时可以指定name,然后通过#号或者v-slot让组件使用:

SoltDemo.vue

<template>
  <div>
    <slot> Default slot content </slot>
    <slot name="header"> Header slot content </slot>
  </div>
</template>

HomeView.vue

<template>
  <div class="home">
    <SoltDemo>
      <template #header>
        header插槽内容1
      </template>
    </SoltDemo>
    <SoltDemo>
      内容2
      <template v-slot:header>
        header插槽内容2
      </template>
    </SoltDemo>
    <SoltDemo>  </SoltDemo>
  </div>
</template>

3.4.3 作用域插槽

我们可以给插槽绑定一个数据作为作用域插槽,调用方式我们直接如下举例:

SlotDemo.vue

<script>
export default {
  name: 'SlotDemo',
  data() {
    return {
      slotData :0
    }
  }
}
</script>

<template>
  <div>
    <slot> Default slot content </slot>
    <slot name="header"> Header slot content </slot>
    <slot name="footer" :slotData="slotData"> Footer slot content </slot>
  </div>
</template>

HomeView.vue

<template>
  <div class="home">
    <SoltDemo>
      <template #header>
        header插槽内容1
      </template>
    </SoltDemo>
    <SoltDemo>
      内容2
      <template v-slot:header>
        header插槽内容2
      </template>
      <template v-slot:footer = "slotDataObj">
        {{slotDataObj}}
      </template>
    </SoltDemo>
    <SoltDemo>  </SoltDemo>
    <SoltDemo>
      <template #header>
        header插槽内容3
      </template>
      <template #footer = "slotData">
        {{slotData.slotData}}
      </template>
    </SoltDemo>
    <SoltDemo>
      <template #header>
        header插槽内容4
      </template>
      <template #footer ={slotData}>
        {{slotData}}
      </template>
    </SoltDemo>
  </div>
</template>

值得注意的是,作用域插槽使用方式有多种,参考上述例子。其中,直接在template中 = "xxx"的方式获取的是一个对象。

4. 路由

路由用于Vue单页面跳转,是我们日后开发要常接触的部分。

4.1 基本结构与使用方式

基本结构
我们用脚手架进行项目生成时,可以选择手动选择功能,然后选择路由。当我们选择了路由后,生成的Vue项目中就会有一个router文件夹。这个文件夹下会有一个index.js文件:

import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    path: '/about',
    name: 'about',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
  }
]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

export default router

基本使用方式
路由index.js文件定义了基本的路由使用方式,即在routes中加入如:

{
    path: '/',
    name: 'home',
    component: HomeView
}

这样的组件信息配置。其中,component可以直接写组件名,同时要import相应的这个组件;或者直接使用箭头函数import这个组件。

练习
了解了基本用法后,我们可以模仿一个出来:

LearnView.vue:

<template>
  <h1>This is a component for learning</h1>
</template>

<script>
export default {
  name: 'LearnView'
}
</script>

index.js:

import LearnView from '../views/LearnView.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    path: '/about',
    name: 'about',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
  },
  {
    path: '/learn',
    name: 'learn',
    component: LearnView
  }
]

_App.vue_新增如下:

<router-link to="/learn">for learning</router-link>

效果:
04

4.2 动态路由

我们实际的项目,url后可能会拼接一个id等字符来显示特定某个对象的信息,例如商品详情等。这种url拼接动态参数的方式称为动态路由。

实现动态路由要以下步骤:

冒号拼接参数名
index.js:

{
    path: '/item/:id',
    name: 'item',
    component: () => import('../views/ItemView.vue'),
    props:true
}

同时要注意,要加一行props=true来接收动态参数。

props传参
itemView.vue:

<script>
export default {
  name: 'ItemView',
  props: [
    'id'
  ]
}
</script>

<template>
  <div class="item-view">
    <h1>Item View</h1>
    <p>item id: {{ id }}</p>
  </div>
</template>

params传参或路径传参
App.vue:

<router-link :to="{ name: 'item', params: { id: 123 } }"> item </router-link>

效果:
05

同时我们观察url,参数已经拼在url末尾。

4.3 嵌套路由

嵌套路由的步骤如下:

设置children子组件列表
index.js:

{
    path: '/children/:id',
    name: 'children',
    children: [
      {
        path: 'child1',
        name: 'child1',
        component: () => import('../views/Child1View.vue')
      },
      {
        path: 'child2',
        name: 'child2',
        component: () => import( '../views/Child2View.vue')
      }
    ],
    component: () => import(/* webpackChunkName: "children" */ '../views/ChildrenView.vue'),
    props: true
}

嵌套链接:
ChildrenView.vue

<template>
  <div>
    <h1>Children View</h1>
    <router-link to="/child1">儿子1</router-link>
    <br>
    <router-link to="/child2">儿子2</router-link>
    <router-view/>
  </div>
</template>

被嵌套的组件及接下来的调用过程略,效果:
06

4.3 编程式路由

编程式路由允许由我们编码指定跳转。例如,当业务状态发生变更时,跳转道指定页面。

如:
Child1View

export default {
  name: 'Child1View',
  created () {
    setTimeout(() => {
      this.$router.push({ name: 'home' })
    }, 3000)
  }
}

其中,这个例子created函数是一个生命周期函数,具体会在下文生命周期小节有介绍。

4.4 路由守卫

在Vue2中,可以使用全局的路由守卫来监控和响应路由的导航。

我们简单举个例子,在路由_index.js_下添加如下:

// 全局前置守卫
router.beforeEach((to, from, next) => {
  console.log('router.beforeEach', to, from)
  next()
})

这个路由守卫输出了页面跳转的路径。但不要忘了next()。

这里只介绍了基本用法。一般来说,路由守卫可以做一些逻辑处理,如身份验证、权限校验、加载数据等。

5. VueX

VueX 状态管理,是一种统一是数据存储方式,是解决多层级组件传值的一种有效手段。

我们在使用脚手架创建Vue项目时就可以选择引入VueX。项目创建后,src目录下会有一个store文件夹,这个文件夹下也有一个_index.js_文件。

其基本结构如下:

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

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
  },
  getters: {
  },
  mutations: {
  },
  actions: {
  },
  modules: {
  }
})

我们需要注意的是,从 state 到 modules 提供了5个功能,下面逐一介绍。

5.1 state 数据存储

state 可以理解为在一个地方存数据,然后所有组件都可访问。

举例
index.js:

 state () {
    return {
      status: 'loading'
    }
 }

访问方式:
Cild1View.vue:

export default {
  name: 'Child1View',
  created () {
    console.log(this.$store.state.status)
  }
}

5.2 mutations 数据修改

如果我们的VueX全局变量需要修改,则可在mutations进行。

举例
index.js:

state () {
    return {
      testMutation: 0
    }
  },
mutations: {
    testChangeValue (state, value) {
      // 返回 + 1 的值
      state.testMutation = value + 1
    }
}

调用方式:
Cild1View.vue:

export default {
  name: 'Child1View',
  created () {
    this.handler()
    console.log(this.$store.state.status)
  },
  methods: {
    handler () {
      console.log(this.$store.commit('testChangeValue', 1))
    }
  }
}

控制台输出,即可查看结果。

同时,在上面介绍的Demo练习例子中,我们不难发现,VueX中的数据都是在state中拿的,使用过程中需要遵循使用方式,即“state.xxx”这种方式去调用。

5.3 actions 异步处理

VueX中actions的作用是提供异步处理。
和mutations类似,都是方法处理,只不过是异步。因此以下复用了部分上一小节举的例子。

举例
index.js:

actions: {
    testAction (store, payload) {
      store.commit('testChangeValue', payload)
    }
  }

调用方式也和mutations类似,注意是使用store的dispatch调用:

console.log(this.$store.dispatch('testAction', 2))

5.4 getters 缓存

getters 提供了 类似于计算属性的缓存。只要getters中的值没有变化,就只执行一次,提高程序效率。

举例
index.js:

testGetters (state) {
      console.log('testGetters executed', state.status)
      return state.status.length
}

测试示例:
Cild1View.vue:

export default {
  name: 'Child1View',
  methods: {
    handler () {
      console.log(this.$store.getters.testGetters)
      console.log(this.$store.getters.testGetters)
      console.log(this.$store.getters.testGetters)
      console.log(this.$store.getters.testGetters)
    }
  }
}

这里示例调用了好几次,但是在控制台输出不难发现console.log('testGetters executed', state.status)只调用了一次。

5.5 modules 模块

在 Vuex 中,模块(modules)是一种将 store 分割成更小的、更专注的部分的方式。每个模块可以包含自己的 state、mutations、actions、getters,甚至是嵌套子模块。这种结构使得 Vuex store 可以保持清晰和组织良好,特别是在大型应用中。

举例
index.js:

 modules: {
    myModule: {
      state: {
        myModuleStatus: 'inactive',
        myModuleCounter: 0
      },
      getters: {
        myModuleStatusLength: (state) => {
          console.log('myModuleStatusLength executed', state.myModuleStatus);
          return state.myModuleStatus.length;
        }
      },
      mutations: {
        incrementCounter (state) {
          state.myModuleCounter++;
          console.log('myModuleCounter', state.myModuleCounter);
        }
      },
      actions: {
        incrementAction ({ commit }) {
          commit('incrementCounter');
        }
      },
      modules: {
        // 可以继续嵌套子模块,在开发中一般会单独建一个文件,用来管理多个模块之间的数据状态
      }
    }

使用示例:

this.$store.commit('myModule/incrementCounter')
      this.$store.dispatch('myModule/incrementAction')

6. Vue2 生命周期

概念
Vue 2 的生命周期钩子是指在 Vue 实例从创建到销毁的过程中,Vue 提供的一系列特殊的函数,这些函数在实例生命周期的不同阶段被自动调用。以下是 Vue 2 生命周期钩子的列表及其说明:

  • beforeCreate:在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。此时,组件实例的 data 和 methods 已经被定义,但是 data 的响应式属性尚未被设置,$el 属性也还未创建。

  • created:在实例创建完成后被立即调用。此时,实例已完成数据观测,属性和方法的运算,watch/event 事件回调。但是,挂载阶段还没开始,$el 属性目前还不可见。

  • beforeMount:在挂载开始之前被调用:相关的 render 函数首次被调用。此时,$el 还未被渲染,data 仍然是响应式的。

  • mounted:在实例被挂载后调用,此时可以访问到 e l 属性,表示 D O M 已经被渲染。如果根实例挂载到了文档内, el 属性,表示 DOM 已经被渲染。如果根实例挂载到了文档内, el属性,表示DOM已经被渲染。如果根实例挂载到了文档内,el 也在文档内可访问。

  • beforeUpdate:在数据变化时,DOM 重新渲染之前调用,此时可以在这个钩子中进一步地更改状态,这不会触发重绘。

  • updated:在由于数据更改导致的虚拟 DOM 重新渲染和打补丁之后调用。此时可以执行依赖于 DOM 的操作。

  • beforeDestroy:在实例销毁之前调用。在这一步,实例仍然完全可用。

  • destroyed:在实例销毁之后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

  • activated 和 deactivated:这两个钩子只在 keep-alive 组件中使用。activated 在组件被激活时调用,deactivated 在组件被停用时调用。

  • errorCaptured:当捕获一个来自子孙组件的错误时被调用。它有三个参数:错误对象、发生错误的组件实例和错误来源。

这些生命周期钩子可以被用来执行一些特定的操作,比如数据获取、事件监听、清理工作等。每个钩子函数都可以在组件选项中被定义,并且会在相应的生命周期阶段被调用。

简单举例
例如,我们可以将生命周期函数在我们项目的main.js中各做一个简单的输出:
main.js

new Vue({
  router,
  store,
  render: h => h(App),
  beforeCreate () {
    console.log('beforeCreate: Vue 实例被创建,但数据观测和事件/侦听器还未被设置')
  },
  created () {
    console.log('created: Vue 实例已创建,data() 和 methods 已可用')
  },
  beforeMount () {
    console.log('beforeMount: Vue 实例即将被挂载,$el 属性还不可用')
  },
  mounted () {
    console.log('mounted: Vue 实例已经挂载到DOM,$el 属性已可用')
  },
  beforeUpdate () {
    console.log('beforeUpdate: Vue 实例数据更新,DOM 重新渲染之前')
  },
  updated () {
    console.log('updated: Vue 实例数据更新,DOM 重新渲染完成')
  },
  beforeDestroy () {
    console.log('beforeDestroy: Vue 实例销毁之前')
  },
  destroyed () {
    console.log('destroyed: Vue 实例销毁完成')
  }
}).$mount('#app')

7. 总结

我们从基本使用的层面,从Vue2.x 项目创建开始,结合一些Demo,学习了 Vue2.x的基本语法,然后学习了组件化开发中的父子组件传值。之后,我们接着学习日常开发中需要常接触的路由配置,以及可以解决多层级组件传值麻烦的全局状态管理器VueX,最后再介绍了面试常见与日后进一步了解框架所需的Vue2.x生命周期函数。

掌握基本语法是基础,组件化开发的思路是重要思想,路由、VueX也是实际开发中常接触的东西。

本文的示例都只是些Demo,要进一步了解、学习前端,还得找些项目练习、实战。

Vue2.x 是学习前端框架开发的一个良好台阶,可以为后续 Vue3.x、React等框架打下一定的基础。持续学习,共同进步!

参考教程

Vue2.x核心技术与实战(一) Vue是什么?Vue是一个用于构建用户界面的渐进式 框架。 阅读详情

相关推荐

小程序uView2.X框架upload组件上传方法总结+避坑

相信很多人写小程序会用到uView框架,总体感觉还算OK吧,只能这么说,肯定也会遇到图片视频上传,如果用到这个upload组件相信你,肯定遇到各种各样的问题,这是我个人总结的单图片和多图片上传方法.2.3 上传成功的回调 主要是是上传的是一个json格式 一定要进行处理 JSON.parse(res.data).path,2.2上传之前做的事情,比如 限制格式 限制大小 这点比较麻烦 ,里面注释写的比较详细。3.上传前限制 大小 图片 格式 里面注释写的很详细。1.需要修改这个属性。

shi15926lei的博客 1万+

Vue2.x

Vue2.x入门,涵盖大部分知识点

l_537的博客 944

JeecgBoot低代码开发—Vue3版前端入门教程

改完之后,必须修改前端映射地址。如何修改后台项目路径。改为自己的如何改呢?

优快云_Admin0的博客 3959

【vue】vue2.x详解大全

1、vue.js的安装 方式一:直接CDN引入 <!-- 开发环境版本,包含了有帮助的命令行警告 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <!-- 生产环境版本,优化了尺寸和速度 --> <script src="https://cdn.jsdelivr.net/npm/vue"></script> 方式二:下载和引入 方式

zhangankang的博客 1813

别再手动巡检了!vRealize Operations Manager 8.x 自动化报告配置全攻略(附模板下载)

本文详细介绍了如何利用vRealize Operations Manager 8.x实现自动化巡检报告配置,大幅提升虚拟化运维效率。通过模板定制、智能调度和自动分发等功能,帮助运维团队告别手动生成报告的繁琐工作,实现90%以上的时间节省。文章还提供了实用的配置技巧和最佳实践,助力企业构建高效的自动化报告系统。

weixin_33806859的博客 298

麒麟桌面操作系统QT开发环境搭建

麒麟操作系统安装Qt

因为热爱,所以坚持,记录工作中的乐趣 9275

VUE学习(一)、基于简单js引入的Vue快速入门——简单实例使用

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

醉瑾_的博客 2633

【scratch音乐课】天空之城:音符与节拍、消息与链表

scratch是一个非常小巧的青少年编程工具,自带程序编写语句,积木式语句非常直观、易用,可创作数学、科学、音乐、绘画等方面作品。本文用scratch“演奏”一首大家非常熟悉的《天空之城》,并向大家介绍一些基本乐理知识,以及scratch中消息、链表的使用。

★·°立芯;︶︵︶ 1万+

iView 2.x 终极指南:从零开始掌握Vue.js企业级UI组件库

iView是一个基于Vue.js 2.0构建的高质量UI组件库,专为开发企业级中后台系统而生。这个功能丰富的工具包提供了超过50个精心设计的组件,涵盖表单、导航、数据展示等核心场景,让前端开发变得更加高效和专业。 ## 🎯 项目概览与核心价值 iView 2.x版本在原有的1.x基础上进行了全面升级,不仅优化了组件性能,还增加了更多实用功能。作为一款成熟的企业级UI解决方案,它已经在阿里巴巴

gitblog_00296的博客 847

继电保护整定值计算软件_「全套69份」整定值计算与设计方案

【全套69份】整定值计算与设计方案,输电线路、变压器、发电机、电容器、母线保护等下载方式见文末内容预览:10kV高压电机保护原理及整定计算35kV环网运行线路继电保护整定计算方案分析35KV以下继电保护及三段式电流保护整定计算110 kv电网计算机整定计算新方案220kV两相式电铁牵引站供电线路的短路故障计算及其保护整定原则分析220kV周潮线接地距离保护整定计算特殊方案750 kV变压器保护配置...

weixin_30825953的博客 5018

数学建模预测模型——回归分析预测

作为预测模型的大块头,回归分析预测绝对是比较常用的预测模型的一种,下面是对该模型的学习,欢迎大家指正😊。

everything is possible,anything is OK. 1万+

如何快速上手ddBuy:Vue电商项目架构解析与开发环境搭建

ddBuy是一个基于Vue全家桶+Vant构建的大型单页面电商项目,提供完整的电商功能实现方案。本文将帮助新手开发者快速理解项目架构并完成开发环境搭建,轻松开启Vue电商项目开发之旅。 ## 项目架构概览:Vue全家桶的完美实践 ddBuy采用现代化前端架构,基于Vue 2.x生态系统构建,核心技术栈包括Vue、Vuex、Vue Router和Vant UI组件库。项目整体结构清晰,模块化程度

gitblog_00706的博客 761

433MHz无线通信避坑指南:如何解决信号干扰和误码问题

本文深入探讨433MHz无线通信中的信号干扰和误码问题,提供从射频前端设计到协议优化的全链路解决方案。通过天线匹配、电源噪声抑制、曼彻斯特编码改进及实时频点切换等技术,显著提升通信稳定性和距离。适合智能家居和工业无线控制系统的开发者参考。

weixin_29288313的博客 419

前端最新Vue2+Vue3基础入门到实战项目全套教程,自学前端vue就选黑马程序员,一套全通关!笔记

-- 兼容:给不支持js的浏览器一个提示 --><noscript>-- Vue所管理的容器:将来创建结构动态渲染这个容器 -->-- 工程化开发模式中:这里不再直接编写模板语法,通过 App.vue这个文件 提供结构渲染 --></div>

m0_58537749的博客 870

Python爬虫实战:利用Scrapy+Playwright高效爬取TED演讲数据

在当今信息爆炸的时代,TED演讲作为全球知名的思想传播平台,汇聚了各领域顶尖人才的精彩分享。对于数据分析师、研究人员或内容创作者来说,获取TED演讲的完整数据集具有重要价值。本文将详细介绍如何使用Python中最先进的爬虫技术组合——Scrapy框架配合Playwright浏览器自动化工具,高效爬取TED演讲的完整数据。传统爬虫技术在处理现代动态网页时面临诸多挑战,而本文将展示如何利用最新工具解决这些问题。

2201_76125261的博客 206

【数据集】3D-GloBFP:全球首个三维建筑轮廓数据集

【数据集】3D-GloBFP:全球首个三维建筑轮廓数据集

WW、forever的博客 1691

学习Vue2.x这一篇就够了

目录第一章 Vue2.x快速入门1.1、Vue2.x官网1.2、Vue2.x介绍1.3、Vue2.x特点1.4、Vue2.x入门1.5、Vue2.x实例1.5.1、el1.5.2、data1.5.3、methods1.5.4、watch1.5.5、computed第二章 Vue2.x指令指南2.1、模板语法2.1.1、插值2.1.1.1、text2.1.1.2、html2.1.1.3、attribute2.1.1.4、expression2.1.2、指令2.1.2.1、参数2.1.2.2、动态参数2.1.2

轻松的小希 3万+

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Vue前端+快速入门【详解】

1.MVVM思想原始HTML+CSS+JavaScript开发存在的问题:操作麻烦,耦合性强为了实现html标签与数据的解耦,前端开发中提供了MVVM思想:即Model-View-ViewModel:Model: 数据模型,指要展示到页面上的数据。在web开发中通常从服务端获取到数据,再把这些数据展示出来View: 视图,用于展示数据的各种html标签ViewModel: 视图模型控制中心,负责把Model数据显示到View里,也负责从View里收集数据到Model里。Vue框架就承担了这个角色。

qq_1424674116的博客 4208

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

大前端快速入门

博主要去安心考研了 奥里给 这里整理了下自己的学习笔记和练习

代码哈士奇的博客 8755

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

VueJS 概述与快速入门

Vue.js是一个构建数据驱动的 web 界面的渐进式框架。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。它不仅易于上手,还便于与第三方库或既有项目整合。 官网:https://cn.vuejs.org/ <!-- 开发环境版本,包含了有帮助的命令行警告 --> <script src="https://cdn...

少营营的博客 990

Vue基础——VueJS是什么、Vue的优缺点、vue2和vue3的模板区别、MVVM数据双向绑定、Vue的安装和使用、Vue模板语法-文本渲染、常用的vue的指令

Vue基础——VueJS是什么、Vue的优缺点、vue2和vue3的模板区别、MVVM数据双向绑定、Vue的安装和使用、Vue模板语法-文本渲染、常用的vue的指令

ranran0306的博客 9723

推荐:Vue.js 官方文档日语版项目 - vuejs/jp.vuejs.org

推荐:Vue.js 官方文档日语版项目 - vuejs/jp.vuejs.org 在这个飞速发展的前端世界里,拥有清晰、详尽的文档是至关重要的。Vue.js,作为一款轻量级但功能强大的渐进式框架,其官方文档一直是开发者的重要学习资源。现在,对于日语使用者来说,有一个绝佳的机会,那就是参与并使用由社区维护的 vuejs/jp.vuejs.org 项目,它提供了 Vue.js 2.x 版本的日语文档。...

gitblog_00009的博客 1182

vue快速入门

vue快速入门

weixin_74009895的博客 1736

《Vue.js 3.x 快速入门》一篇万字文章教会你什么是Vue3

定义页面和渲染视图是 Vue.js 开发中的基础且。

FFNCL的博客 1407

【优质书籍推荐】Vue.js 3.x+Element Plus从入门到精通

本文深入讲解了全栈开发巨作:《Vue.js 3.x+Element Plus从入门到精通(视频教学版)》,希望能对学习Vue.js+Element Plus框架的同学们有所帮助。 文章目录 1. 前言 2. 书籍推荐 2.1 内容简介 2.2 本书作者 2.3 本书目录 2.4 适合读者 3. 购买链接

weixin_43178406的博客 5万+

《Vue.js 3.x快速入门》简介

#好书推荐##好书奇遇季#Vue入门书《Vue.js 3.x快速入门》,京东当当天猫都有发售。定价69元,打折一下更便宜。本书第1版《Vue.js快速入门》销售一万多册。与传统的Web应用不同,单页应用在近几年发展迅猛。我们发现Vue.js框架入门特别快,稍微有一定Webpack 开发经验的程序员在一周内就可以上手做项目,认真学习的话一个月就可以达到快速开发项目的水平,两三个月就可以达到熟练使用Vuex、自己编写Component的水平。这么快的上手速度,使用其他框架是不可想象的。本书起源于作者公司的员工培

夏天又到了的专栏 3114
上一篇: 【前端】一文快速回顾 Html+CSS+JS
下一篇: 【杂谈】产品经理Mysql查询入门
CoderSharry
博客等级 码龄4年 515粉丝 69原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值