【前端面考面试官系列】入门Vue全家桶

(给达达前端加星标,提升前端技能)

【前端面考面试官系列】入门Vue全家桶_第1张图片

面试官问:Vue如何安装的呢?

达达回答:Vue的安装可以从两个方面进行安装,第一种是CDN引入,第二种是NPM安装。

CDN引入


NPM安装

npm install vue

面试官问,如何创建Vue项目?

达达写下代码:

创建项目




    
    Vue入门之Helloworld
    
    


    
    
{{message}}

【前端面考面试官系列】入门Vue全家桶_第2张图片

输出的结果:

hello Vue!

面试官问:v-if和v-show的区别是?

达达回答:

内部指令

v-if用于显示与隐藏的元素

达达前端

v-else,v-if不是它,就是它v-else

达达前端

v-show

你好

v-else-if

A
B
C
Not A/B/C

v-if和v-show的区别是:

v-if用于元素的被销毁和重建,使用这个指令开销较为高,在运行过程中,尽量用在很少改变时的情况下使用。v-if元素销毁和存在

v-show的用法,这个指令的使用开销较小,在常频繁地切换使用

面试官问:内部指令的用法有哪些,怎么用呢?

达达回答:好,慢慢讲述。

v-for的用法


  • {{item}}

对象遍历


  • {{ index }}. {{ key }} - {{ value }}

v-text的出现为了解决{{xx}}这个取值的问题,当网络很慢的情况下,或者是运行时出错的情况下,页面显示为{{xxx}}。

{{ message }}

v-html指令是用于输出html代码


v-on的用法

// html
{{count}}
加 // JS data:{ count: 1 }, methods: { add() { this.count++; } }

缩写

v-model的用法,model都需要在data中声明初始值:

data: {
    count: 1,
}

input的用法


textarea


checkbox









状态:{{status}}

radio









性别:{{sex}}

select




Selected: {{ selected }}

v-bind方法

// html



// js
data: {    
    imgSrc:''
}

缩写


v-pre方法,用这个指令可以直接跳过vue的编译,直接输出原始值,如果在标签中加入v-pre就不会输出vue中的data值。

{{message}}

v-cloak可以在vue渲染时指定的整个dom后才进行显示,必须和css样式一起用

// css
[v-cloak] {
    display: none;
}


// html
{{message}}

v-once只能显示一次,第一次渲染的值就不会改变了

{{message}}

面试官问:你知道Vue生命周期吗?

达达回答:

new Vue() 实例化对象,init events & lifecycle 初始化,事件和生命周期

beforeCreate组件实例刚被创建,还没有实例化之前,执行一些初始化的操作,可以制作加载动画

init injections & reactivity 初始化,依赖注入和校验

created组件实例创建完成,属性已经绑定,但是dom还没有生成,$el属性还不存在,页面未被展示,结束加载动画,发起异步网络请求

has"el" option? no 判断是否存在el属性,如果有,则继续编译,如果没有,则停止编译,生命周期结束,知道在该vue实例上调用vm.$mount(el),即被唤醒继续执行编译,如果注释掉“el”,等程序到create就停止了

判断是否有template,如果有,则将其编译成render函数,如果没有,则将外部的HTML作为模板编译,template中的模板优先级高于outer html 的优先级。

yes的路线,compile template into render function

如果tremplate中组件的话,执行render方法渲染组件内容

compile el's outerhtml as template

beforeMount,完成虚拟dom配置,模板已经被编译,把data里面的数据和模板生成html,此时还没有挂载html到页面上

create vm.$el and replace "el" with it,给vue实例对象添加$el成员,并且替换掉挂载的dom元素

mounted,用上面编译好的html内容替换el属性指向dom对象,方法结束后,dom结构完成,页面显示出来,发起网络请求

Mounted,when data changes,beforeUpdate,当vue发现data中的数据发生了改变,会触发对应组件的重新渲染,一般在组件发生更新之前,调用这个函数,页面还不会展示修改的内容,但虚拟dom已经配置修改

virtual dom re-render and patch,重新渲染虚拟dom并通过diff算法对比vonde节点差异更新真实dom,updated,组件更新后,此方法执行后,修改后的页面展现出来,即为view重新渲染,数据更新

when wm.$destroy() is called,beforeDestroy,组件实例销毁前调用,实例仍然完全可用

teardown watchers, child components and event listeners 拆卸观察者,子组件,事件监听者

destroyed,在vue实例销毁后调用,实例指示的所有东西都会被解除绑定,所有的事件监听都会被移除,所有的子实例都会被销毁

【前端面考面试官系列】入门Vue全家桶_第3张图片

面试官问:在vue中常用的语句有哪些

达达回答:好的,请认真听讲

computed计算属性,用于对原数据进行修改

computed: {
    newPrice () {
        return '¥' + this.price + '元';
    }
}

methods方法属性,用于绑定方法

methods:{
    add (num) {
        this.count += num;
    }
}

watch数据变化监听器

watch: {
    question(val, oldVal) {
        console.log('new: %s, old: %s', val, oldVal);
    }
}

filters 过滤器

filters: {
    filterA(value) {
        return value.toUpperCase();
    }
}

mixins用于减少代码污染,减少代码量,实现代码重用

var addLog={
    updated:function(){
        console.log("数据放生变化,变化成"+this.count+".");
    }
}


var app = new Vue({
    el:'#app',
    data:{
        count: 100
    },
    // 混入
    mixins: [addLog]
})

extends用于扩展,对构造器进行扩展

var extendObj ={
    created: function(){
        console.log("我是");
    }
}


var app = new Vue({
    el:'#app',
    data:{
    },
    // 扩展
    extends: extendObj
})

面试官问,你知道哪些实例事件吗?

达达回答,vue有实例属性,实例方法,实例事件

$on接收两个参数,第一个参数是调用时的事件名称,第二个参数是一个匿名方法


app.$on('reduce',function(){
    console.log('执行了reduce()');
    this.count--;
});


app.$once('reduceOnce',function(){
    console.log('只执行一次的方法');
    this.count--;
});


function off(){
    console.log('关闭事件');
    app.$off('reduce');
}


function reduce() {
    // 事件调用
    console.log('emit事件调用');
    app.$emit('reduce');
}

面试官问:你知道自定义指令吗

达达回答:知道吧




    
    Vue入门之自定义指令
    


{{num}}
function unbindApp() { app.$destroy(); } // 自定义指令 Vue.directive("test",{     //被绑定 bind:function (el, binding, vnode) { console.log("1-bind 被绑定"); console.log("el:",el); console.log("binding:",binding); console.log("vnode:",vnode); el.style.color = binding.value; },     //被插入 inserted:function (el, binding, vnode) { console.log("2-inserted 被插入"); },     //更新 update:function (el, binding, vnode) { console.log("3-update 更新"); },     //更新完成 componentUpdated:function (el, binding, vnode) { console.log("4-componentUpdated 更新完成"); },     //解绑 unbind:function (el, binding, vnode) { console.log("5-unbind 解绑"); } }); var app = new Vue({ el:'#app', data:{ num: 123, color:'red' } })

面试官问:你用过组件吗?

达达回答,用过的

组件全局注册

Vue.component('button-counter', {
    data: function () {
        return {
            count: 0
        }
    },
    template: '全局组件: {{ count }}'
});


new Vue({
    el: '#app'
});



组件局部注册

new Vue({
    el: '#app',
    components:{
        "button-inner":{
            data: function() {
                return {
                    inner: 0
                }
            },
            template: '局部组件: {{ inner }}'
        }
    }
});



props属性传值

new Vue({
        el: '#app',
        components:{
            "button-props":{
                template:`
                
参数1: {{ da }}:---参数2: {{fromHere}}
`, props:['da', 'fromHere'] } } }); // html使用 props中需要驼峰取值

父子组件

// 子组件
var city = {
    template:`
dada
` } // 父组件 var parent = { template: `

dadada!

`, components:{ "city": city } } // 实例化 new Vue({ el: '#app', // 定义局部组件 components:{ // 组件注册 "parent": parent } }); // html使用

面试官:你了解模板吗?

达达回答:还好

面试问:你了解插槽不?

达达回答:插槽就是slot,是组件的一块Hmtl模板

             123     

具名插槽slot,具名插槽可以在一个组件中出现n次

             123         456     

作用域插槽slot

    

面试官问:你用过vue-cli吗?说一说

达达回答:好的

vue-cli安装,第一用npm安装

npm -v

vue-cli安装

npm install vue-cli -g

vue -V


-g代表全局安装,然后查看版本

初始化项目

用vue init命令来初始化项目


vue init  


init:表示要用vue-cli来初始化项目


:表示模板名称


vue-cli官方提供的5种模板


webpack


webpack-simple


browserify


browserify-simple


simple


:标识项目名称,用户根据自己的项目来起名字。

【前端面考面试官系列】入门Vue全家桶_第4张图片

项目初始化

vue init webpack my-vue-demo

Project name:项目名称


Project description:项目描述


Author:作者


Install vue-router? 是否安装vue的路由插件,需要安装,选择Y


Use ESLint to lint your code? 是否用ESLint来限制你的代码错误和风格。不需要输入n,需要选择y


setup unit tests with Karma + Mocha? 是否需要安装单元测试工具


Setup e2e tests with Nightwatch? 是否安装e2e来进行用户行为模拟测试

运行项目

npm run dev


npm run build

面试官问:你了解vue-router吗?说一说

达达回答,嗯,了解。

【前端面考面试官系列】入门Vue全家桶_第5张图片

安装

npm install vue-router --save

核心文件

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'


// Vue全局使用Router
Vue.use(Router)


export default new Router({
  routes: [                //配置路由,这里是个数组
    {                        //每一个链接都是一个对象
      path: '/',            //链接路径
      name: 'HelloWorld',        //路由名称,
      component: HelloWorld     //对应的组件模板
    }
  ]
})

使用

import Vue from 'vue'
import App from './App'
import router from './router'


Vue.config.productionTip = false


new Vue({
  el: '#app',
  router, // 注入框架中
  components: { App },
  template: ''
})

页面跳转

[显示字段]


导航 : 首页 hello

编程式导航

this.$router.push('/xxx')





export default {
    name: 'app',
    methods: {
        goHome(){
            this.$router.push('/home');
        }
    }
}


//  同于 history.back()
this.$router.go(-1)
// 同于 history.forward()
this.$router.go(1)

路由嵌套








子页面













路由配置

import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/components/Home'
import One from '@/components/One' 
import Two from '@/components/Two'


Vue.use(Router)


export default new Router({
    routes: [
    {
        path: '/', // 默认页面重定向到主页
        redirect: '/home'
    },
    {
        path: '/home', // 主页路由
        name: 'Home',
        component: Home,
        children:[ // 嵌套子路由
            {
                path:'one', // 子页面1
                component:One
            },
            {
                path:'two', // 子页面2
                component:Two
            },
        ]
    }
    ]
})

路由传递参数


dada


子页面

{
    path:'one', // 子页面
    name: 'one', // 路由名称-命名路由
    component:One
}

{{$route.params.username}}

url中传递参数

{
    path:'/home/two/:id/:name', // 子页面
    component:Two
},

ID:{{ $route.params.id}}

名称:{{ $route.params.name}}

子页面

编程式导航带参数

{
    path:'/home/three', // 子页面
    name: 'three',
    component:Three
}

ID:{{ $route.params.id}}

名称:{{ $route.params.name}}

页面-params传参


// script
methods: {
    toThreePage() {
        this.$router.push(
        {
        name: 'three', 
        params: {
        id: 1, 
        name: 'dada'
        }
        }
        )
    }
}

query传参数

{
    path:'/home/three', // 子页面
    name: 'three',
    component:Three
}

ID:{{ $route.query.id}}

名称:{{ $route.query.name}}

页面-params传参


methods: {
    toThreePage() {
        this.$router.push(
        {path: '/home/three', query: {id: 1, name: 'da'}}
        )
    }
}

命名路由

{
    path: 'one', // 子页面
    name: 'one', // 路由名称-命名路由
    component: One // 页面组件
}

// template跳转调用
子页面


// router.push函数跳转调用
router.push({ name: 'user'}})

import Vue from 'vue'
import Router from 'vue-router'
// 创建页面组件
const Header = { template: '
Header
' } const Left = { template: '
Left
' } const Right = { template: '
Right
' } Vue.use(Router) export default new Router({ routes: [ { path: '/', // 主页路由 components: { default: Header, a: Left, b: Right } } ] })

重定向

export default new Router({
    routes: [
    {
        path: '/', // 默认页面重定向到主页
        redirect: '/home' // 重定向
    },
    {
        path: '/home', // 主页路由
        component: Home,
        children:[ // 嵌套子路由
            {
                path:'/home/two/:id/:name', // 子页面
                component:Two
            },
            {
                path:'/home/three/:id/:name', // 子页面
                name: 'three', // 路由名称-命名路由
                redirect: '/home/two/:id/:name' // 重定向-传递参数
            },
        ]
    }
    ]
})

首页 | 
子页面  |

子页面

redirect: '/home' // 重定向-不带参数

redirect: '/home/two/:id/:name' // 重定向-传递参数

别名

{
    path:'/one', // 子页面
    component:One,
    alias: '/oneother'
}

子页面1

【前端面考面试官系列】入门Vue全家桶_第6张图片

过渡动画


    

【前端面考面试官系列】入门Vue全家桶_第7张图片

.fade-enter-active {
    transition: opacity .5s;
}


.fade-enter {
    opacity: 0;
}


.fade-leave {
    opacity: 1;
}


.fade-leave-active {
    opacity:0;
    transition: opacity .5s;
}

mode模式

export default new Router({
    mode: 'history', //mode模式
    routes: [...]
})

【前端面考面试官系列】入门Vue全家桶_第8张图片

404

// 404
{
    path: '*',
    component: () => import('@/components/404')
}

路由钩子,第一全局钩子,第二,路由单独钩子,第三,组件内钩子

const router = new VueRouter({ ... })


// 全局路由拦截-进入页面前执行
router.beforeEach((to, from, next) => {
    next();
});


router.afterEach(() => {
 
});


export default router;

【前端面考面试官系列】入门Vue全家桶_第9张图片

路由单独钩子

{
    path:'/home/one', // 子页面
        component: One,
   
        beforeEnter: (to, from, next) => {
        console.log('进入前执行');
            next();
        }
}

组件内钩子


路由

import Home from '@/components/Home'
{
        path: '/home',
        component: Home
}

【前端面考面试官系列】入门Vue全家桶_第10张图片

面试官问:你了解vuex是什么吗?要不也说说

达达回答:好的。

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

单向数据流

【前端面考面试官系列】入门Vue全家桶_第11张图片

【前端面考面试官系列】入门Vue全家桶_第12张图片

【前端面考面试官系列】入门Vue全家桶_第13张图片

vuex的核心

【前端面考面试官系列】入门Vue全家桶_第14张图片

安装

npm install vuex --save

使用

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state = {
    count: 1
}
const mutations = {
    DA(state, n) {
        state.count += n;
    }
}
const getters = {
    count: function(state){
        return state.count;
    }
}
const actions ={
    // 触发mutations中相应的方法-一般小写
    add ({commit}, data) {
        commit('DA', data)
    }
}


const store = new Vuex.Store({
    state,
    mutations,
    getters,
    actions
});


export default store;

{{ $store.state.count }}

computed: {
    count() {
        return this.$store.state.count;
    }
}

computed: mapState({
    // es5写法
    count: function (state) {
         return state.count;
     },
    // es6写法
    count: state => state.count
})

数组获取
computed: mapState(['count'])

computed: mapState({
    count: 'count'
})

+
const mutations = {
    // 状态变更函数
    DA(state) {
        state.count++;
    }
}

每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块,从上至下进行同样方式的分割。

// 模块A
const moduleA = {
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}


// 模块B
const moduleB = {
  state: { ... },
  mutations: { ... },
  actions: { ... }
}


// 组装
const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})


// 取值
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态

面试官最后一问:你了解axios吗?

达达回答:嗯,用过。

Axios 是基于 promise 的 HTTP 库,用在浏览器和 node.js 中。就是前端最火最简单的一个http请求解决方案。

安装

npm install vuex --save

【前端面考面试官系列】入门Vue全家桶_第15张图片

代码封装

import fetch from '@/util/fetch'
const TMPURL = ''; // url地址
const params = {}; // 参数
fetch.post(TMPURL + '/login/login', params);

import axios from 'axios';
const httpService = axios.create({
    baseURL: process.env.BASE_API, // 需自定义
    // 请求超时时间
    timeout: 3000 
});


// request拦截器
httpService.interceptors.request.use(
    config => {
        // 加入token
        if (true) { 
            config.headers['User-Token'] = '';
        }
        return config;
    }, 
    error => 
        Promise.reject(error);
    }
)


// respone拦截器
httpService.interceptors.response.use(
    response => {
        const res = response.data;
        if (res.statuscode != 1) {
            return Promise.reject({
                status: res.statuscode,
                message: res.message
            });
        } else {
            return response.data;
        }
    },


    error => {
         if (error && error.response) {
            switch (error.response.status) {
                case 400:
                    error.message = '错误请求';
                    break;
                case 401:
                    error.message = '未授权,请重新登录';
                    break;
                case 403:
                    error.message = '拒绝访问';
                    break;
                case 404:
                    error.message = '请求错误,未找到该资源';
                    break;
                case 405:
                    error.message = '请求方法未允许';
                    break;
                case 408:
                    error.message = '请求超时';
                    break;
                case 500:
                    error.message = '服务器端出错';
                    break;
                case 501:
                    error.message = '网络未实现';
                    break;
                case 502:
                    error.message = '网络错误';
                    break;
                case 503:
                    error.message = '服务不可用';
                    break;
                case 504:
                    error.message = '网络超时';
                    break;
                case 505:
                    error.message = 'http版本不支持该请求';
                    break;
                default:
                    error.message = `未知错误${error.response.status}`;
            }
        } else {
            error.message = "连接到服务器失败";
        }
        return Promise.reject(error);
    }
)
/*
 *  get请求
 *  url:请求地址
 *  params:参数
 * */
export function get(url, params = {}) {
    return new Promise((resolve, reject) => {
        httpService({
            url: url,
            method: 'get',
            params: params
        }).then(response => {
            resolve(response);
        }).catch(error => {
            reject(error);
        });
    });
}


/*
 *  post请求
 *  url:请求地址
 *  params:参数
 * */
export function post(url, params = {}) {
    return new Promise((resolve, reject) => {
        httpService({
            url: url,
            method: 'post',
            data: params
        }).then(response => {
            resolve(response);
        }).catch(error => {
            reject(error);
        });
    });
}


/*
 *  文件上传
 *  url:请求地址
 *  params:参数
 * */
export function fileUpload(url, params = {}) {
    return new Promise((resolve, reject) => {
        httpService({
            url: url,
            method: 'post',
            data: params,
            headers: { 'Content-Type': 'multipart/form-data' }
        }).then(response => {
            resolve(response);
        }).catch(error => {
            reject(error);
        });
    });
}


export default {
    get,
    post,
    fileUpload
}

推荐系列

【前端面考面试官系列】入门Vue全家桶_第16张图片

推荐阅读  点击标题可跳转

【面试Vue全家桶】vue前端交互模式-es7的语法结构?async/await

【面试需要-Vue全家桶】一文带你看透Vue前端路由

【面试需要】掌握JavaScript中的this,call,apply的原理

2019年的每一天日更只为等待她的出现,好好过余生,庆余年 | 掘金年度征文

进来就是一家人【达达前端技术社群⑥】

觉得本文对你有帮助?请分享给更多人

关注「达达前端」加星标,提升前端技能

在博客平台里,未来的路还很长,也希望自己以后的文章大家能多多支持,多多批评指正,我们一起进步,一起走花路。

非常感谢读者能看到这里,如果这个文章写得还不错,觉得「达达」我有点东西的话,觉得我能够坚持的学习,觉得此人可以交朋友的话, 求点赞,求关注,求分享,对暖男我来说真的

非常有用!

感谢阅读,原创不易,喜欢就点个[在看] or [转发朋友圈],这是我写作最大的动力。

意见反馈

若本号内容有做得不到位的地方(比如:涉及版权或其他问题),请及时联系我们进行整改即可,会在第一时间进行处理。

这是一个有质量,有态度的公众号

点关注,有好运

【前端面考面试官系列】入门Vue全家桶_第17张图片

好文章,我在看❤️

你可能感兴趣的:(前端,vue.js,javascript,html5,css3)