你真的会用Vue-cli脚手架和Element-ui进行项目创建吗?

文章目录

  • 前言
    • 1. Vue的生命周期
      • 名词解释
        • beforeCreate(创建前)
        • created(创建后)
        • beforeMount(载入前)
        • mounted(载入后)
        • beforeUpdate(更新前)
        • updated(更新后)
        • beforeDestroy(销毁前)
        • destroyed(销毁后)
      • Q & A
        • 1.什么是vue生命周期?
        • 2.vue生命周期的作用是什么?
        • 3.vue生命周期总共有几个阶段?
        • 4.第一次页面加载会触发哪几个钩子?
        • 5.DOM渲染在哪个周期中就已经完成?
    • 2. Vue的优点
      • 低耦合
      • 可重用性
      • 独立开发
      • 可测试
    • 3. Vue组件间的参数传递
      • 1.父组件与子组件传值
      • 2.非父子组件间的数据传递,兄弟组件传值
    • 4. 路由之间跳转
    • 5. Vue如何自定义一个过滤器
    • 6. Vue中v-for的key值的作用
    • 7. vue-router是用来做什么的
    • 8. vue.cli中怎样使用自定义的组件
    • 9. 如何从零写出一个Vue路由
      • 1. 在components目录中创建文件,如图:
      • 2. 在router.js中进行全局路由信息的定义
        • 1.首先进行vue和cue-router的导入
        • 2. 在需要用到的页面中进行导入
        • 3. 注册VueRouter
        • 4. 编写路由信息
        • 5.导出模块
    • 10. Vue-router钩子函数
    • 11. Vue实现数据双向绑定的原理:Object.defineProperty()
        • js实现简单的双向绑定
    • 12. ElementUI是怎么做表单验证的
      • 进行用户表单的验证
        • ```model ```绑定表单数据
        • 通过```prop```取表单数值
        • 通过编写```ref```进行后台API验证
        • 根据```rules```进行表单内容验证
    • 13. vue-router怎么重定向页面?
    • 14. ajax、fetch、axios三者区别
    • 15. 如何使css只在当前组件起作用
      • 参考资料

前言

此篇博客为之前使用vue-elementui-webpack-vuecli进行的项目相关知识的总结,即个人的项目实战学习笔记,经查阅相关资料以及自我总结得出此篇文章。(如有错误之处,请大佬指出,共同学习研究)
项目源码地址:点击链接

1. Vue的生命周期

你真的会用Vue-cli脚手架和Element-ui进行项目创建吗?_第1张图片

图片来自:Vue.js生命周期

名词解释

beforeCreate(创建前)

在数据观测和初始化事件还未开始

created(创建后)

完成数据观测,属性和方法的运算,初始化事件,$el属性还没有显示出来

beforeMount(载入前)

在挂载开始之前被调用,相关的render函数首次被调用。实例已完成以下的配置:编译模板,把data里面的数据和模板生成html。注意此时还没有挂载html到页面上。

mounted(载入后)

在el 被新创建的 vm.$el替换,并挂载到实例上去之后调用。实例已完成以下的配置:用上面编译好的html内容替换el属性指向的DOM对象。完成模板中的html渲染到html页面中。此过程中进行ajax交互。

beforeUpdate(更新前)

在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前。可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程。

updated(更新后)

在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用。

beforeDestroy(销毁前)

在实例销毁之前调用。实例仍然完全可用。

destroyed(销毁后)

在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。

Q & A

1.什么是vue生命周期?

答: Vue 实例从创建到销毁的过程,就是生命周期。从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、销毁等一系列过程,称之为 Vue 的生命周期。

2.vue生命周期的作用是什么?

答:它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑。

3.vue生命周期总共有几个阶段?

答:它可以总共分为8个阶段:创建前/后, 载入前/后,更新前/后,销毁前/销毁后。

4.第一次页面加载会触发哪几个钩子?

答:会触发 下面这几个beforeCreate, created, beforeMount, mounted 。

5.DOM渲染在哪个周期中就已经完成?

答:DOM 渲染在 mounted 中就已经完成了。

2. Vue的优点

低耦合

视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。

可重用性

你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。

独立开发

开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计。

可测试

界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。

3. Vue组件间的参数传递

1.父组件与子组件传值

父组件传给子组件:子组件通过props方法接受数据;
子组件传给父组件$emit方法传递参数

2.非父子组件间的数据传递,兄弟组件传值

eventBus,就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。项目比较小时,用这个比较合适。

4. 路由之间跳转

声明式(标签跳转) 编程式( js跳转)

5. Vue如何自定义一个过滤器

html部分代码

<el-table-column label="创建时间" prop="add_time" width="140px">
       <template slot-scope="scope">
         {{scope.row.add_time | dateFormat}}
       template>
el-table-column>

在此次项目中,html页面中使用element-ui组件和template进行操作,使用|进行调用过滤器。其中add_time为后台进行传递。

data() {
   return {
     // 查询参数对象
     queryInfo: {
       query: '',
       pagenum: 1,
       pagesize: 10
     },
     // 商品列表  从后台获得
     goodslist: [],
     total: 0
   }
 }

在全局进行过滤器的定义

Vue.filter('dateFormat', function (originVal) {
 const dt = new Date(originVal)		//获取数据

 const y = dt.getFullYear()
 const m = (dt.getMonth() + 1 + '').padStart(2, '0')	//不足两位,进行补0
 const d = (dt.getDate() + '').padStart(2, '0')

 const hh = (dt.getHours() + '').padStart(2, '0')
 const mm = (dt.getMinutes() + '').padStart(2, '0')
 const ss = (dt.getSeconds() + '').padStart(2, '0')

 return `${y}-${m}-${d} ${hh}:${mm}:${ss}`			//返回结果
})

过滤器接收表达式的值 (scope.row.add_time) 作为第一个参数。dateFormat过滤器将会收到 msg的值作为第一个参数。

6. Vue中v-for的key值的作用

当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。key的作用主要是为了高效的更新虚拟DOM。

7. vue-router是用来做什么的

vue-router路由,通俗来讲主要是来实现页面的跳转,通过设置不同的path,向服务器发送的不同的请求,获取不同的资源。
主要组件:router-viewrouter-link

8. vue.cli中怎样使用自定义的组件

你真的会用Vue-cli脚手架和Element-ui进行项目创建吗?_第2张图片

9. 如何从零写出一个Vue路由

在此次项目中,由于使用的是全局定义。

1. 在components目录中创建文件,如图:

你真的会用Vue-cli脚手架和Element-ui进行项目创建吗?_第3张图片

2. 在router.js中进行全局路由信息的定义

摘取部分(以goods文件夹目录下为例)

1.首先进行vue和cue-router的导入

import Vue from 'vue'
import VueRouter from 'vue-router'

2. 在需要用到的页面中进行导入

// import Cate from './components/goods/Cate.vue'
const Cate = () => import(/* webpackChunkName: "Cate_Params" */ './components/goods/Cate.vue')
// import Params from './components/goods/Params.vue'
const Params = () => import(/* webpackChunkName: "Cate_Params" */ './components/goods/Params.vue')

// import GoodsList from './components/goods/List.vue'
const GoodsList = () => import(/* webpackChunkName: "GoodsList_Add" */ './components/goods/List.vue')
// import Add from './components/goods/Add.vue'
const Add = () => import(/* webpackChunkName: "GoodsList_Add" */ './components/goods/Add.vue')

3. 注册VueRouter

Vue.use(VueRouter)

4. 编写路由信息

const router = new VueRouter({
  routes: [
    {
      path: '/',
      redirect: '/login'
    },
    {
      path: '/login',
      component: Login
    },
    {
      path: '/home',
      component: Home,
      redirect: '/welcome',
      children: [
        {
          path: '/welcome',
          component: Welcome
        },
        ......

5.导出模块

export default router

10. Vue-router钩子函数

首页可以控制导航跳转,beforeEachafterEach等,一般用于页面title的修改。一些需要登录才能调整页面的重定向功能。

beforeEach主要有3个参数tofromnext

toroute即将进入的目标路由对象,

fromroute当前导航正要离开的路由

next:function一定要调用该方法resolve这个钩子。执行效果依赖next方法的调用参数。可以控制网页的跳转。

全局的:beforeEach、beforeResolve、afterEach
路由的:beforeEnter
组件的:beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave

例如,项目中使用到的:

// 挂载路由导航守卫
router.beforeEach((to, from, next) => {
  // to 将要访问的路径
  // from 代表从哪个路径跳转而来
  // next 是一个函数,表示放行
  //     next()  放行    next('/login')  强制跳转

  if (to.path === '/login' || to.path === '/') return next()
  // 如果用户访问非登录路径,则判断有无登录凭证token
  const loginToken = sessionStorage.getItem('token')
  // 没有token,直接跳转登录页面
  if (!loginToken) return next('/login')
  // 有token,放行
  next()
})

11. Vue实现数据双向绑定的原理:Object.defineProperty()

vue实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的settergetter,在数据变动时发布消息给订阅者,触发相应监听回调。当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty将它们转为getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。

vue的数据双向绑定 将MVVM作为数据绑定的入口,整合ObserverCompileWatcher三者,通过Observer来监听自己的model的数据变化,通过Compile来解析编译模板指令(vue中是用来解析 {{}}),最终利用watcher搭起observerCompile之间的通信桥梁,达到数据变化 —>视图更新;视图交互变化(input)—>数据model变更双向绑定效果。

js实现简单的双向绑定

<body>
    <div id="app">
    <input type="text" id="txt">
    <p id="show">p>
div>
body>
<script type="text/javascript">
    var obj = {}
    Object.defineProperty(obj, 'txt', {
        get: function () {
            return obj
        },
        set: function (newValue) {
            document.getElementById('txt').value = newValue
            document.getElementById('show').innerHTML = newValue
        }
    })
    document.addEventListener('keyup', function (e) {
        obj.txt = e.target.value
    })
script>

12. ElementUI是怎么做表单验证的

在此项目中的实例:

进行用户表单的验证

html - demo:

 
    <el-dialog title="添加用户信息" :visible.sync="addDialogVisible" width="50%" @close="addDialogClosed">
      
      <el-form :model="addForm" :rules="addFormRules" ref="addFormRef" label-width="70px">
        <el-form-item label="用户名" prop="username">
          <el-input v-model="addForm.username">el-input>
        el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input v-model="addForm.password" type="password">el-input>
        el-form-item>
        <el-form-item label="邮箱" prop="email">
          <el-input v-model="addForm.email">el-input>
        el-form-item>
        <el-form-item label="手机号" prop="mobile">
          <el-input v-model="addForm.mobile">el-input>
        el-form-item>
      el-form>
      
      <span slot="footer" class="dialog-footer">
        <el-button @click="addDialogVisible = false">取 消el-button>
        <el-button type="primary" @click="addUser">确 定el-button>
      span>
    el-dialog>

model绑定表单数据

通过调用后台接口和数据库,获取数据(editForm):

const { data: res } = await this.$http.get('users/' + id)
if (res.meta.status !== 200) {
     return this.$message.error('查询用户信息失败!')
   }

   this.editForm = res.data		//获取数据

通过prop取表单数值

如下代码:

<el-table-column label="姓名" prop="username">el-table-column>
<el-table-column label="邮箱" prop="email">el-table-column>
<el-table-column label="电话" prop="mobile">el-table-column>
<el-table-column label="角色" prop="role_name">el-table-column>

通过编写ref进行后台API验证

this.$refs.addFormRef.validate(async valid => {
        // console.log(valid)
        if (!valid) return
        // 可以发起添加用户的网络请求
        const { data: res } = await this.$http.post('users', this.addForm)
        if (res.meta.status !== 201) {
          this.$message.error('添加用户信息失败')
        } else {
          this.$message.success('添加用户信息成功')
        }
        // 隐藏添加用户的对话框
        this.addDialogVisible = false
        // 刷新用户列表
        this.getUserList()
      })
    }

根据rules进行表单内容验证

项目中的rulesaddFormRules,例如以下代码(其中checkMobilecheckEmail为自己编写的验证方法):

// 添加表单验证规则对象
      addFormRules: {
        username: [
          { required: true, message: '请输入用户名', trigger: 'blur' },
          {
            min: 3,
            max: 10,
            message: '用户名的长度在3~10个字符之间',
            trigger: 'blur'
          }
        ],
        password: [
          { required: true, message: '请输入密码', trigger: 'blur' },
          {
            min: 6,
            max: 15,
            message: '用户名的长度在6~15个字符之间',
            trigger: 'blur'
          }
        ],
        email: [
          { required: true, message: '请输入邮箱', trigger: 'blur' },
          { validator: checkEmail, trigger: 'blur' }
        ],
        mobile: [
          { required: true, message: '请输入手机号', trigger: 'blur' },
          { validator: checkMobile, trigger: 'blur' }
        ]
      }

13. vue-router怎么重定向页面?

export default {
   path: '',
   name: '',
   meta: {  //元信息(非必填)
      icon: '',  //路由图标
      title: '',   //路由名称
      light: '',    //高亮显示那个路由name
      show: true,   //是否显示
   },
   redirect: {   
      name: '',    //重定向,指向哪个路由的name
   },
   component: '',    //当前路由时要显示的组件
   children: [],    //嵌套子路由
}

项目中实际应用:
你真的会用Vue-cli脚手架和Element-ui进行项目创建吗?_第4张图片

14. ajax、fetch、axios三者区别

ajax是最早出现发送后端请求的技术,属于原生js范畴,核心是使用XMLHttpRequest对象,使用较多并有先后顺序的话,容易产生回调地狱。

fetch号称可以代替ajax的技术,是基于ES6中的Promise对象设计的,参数和jQuery中的ajax类似,它并不是对ajax进一步封装,它属于原生js范畴。没有使用XMLHttpRequest对象。

axios不是原生js,使用时需要对其进行安装,客户端和服务器端都可以使用,可以在请求和相应阶段进行拦截,基于Promise对象。

15. 如何使css只在当前组件起作用

在style标签中写入scoped即可 例如:

<style lang="less" scoped>style>

参考资料

Vue面试中,经常会被问到的面试题/Vue知识点整理(来源:简书)
vue 248个知识点(面试题)为你保驾护航(来源:掘金)

你可能感兴趣的:(Vue.js学习)