Вопросы на фронтенд-интервью — подробное объяснение базовой части vue

Vue.js Vuex vue-router

vue

Различие основных концепций

  • Одностраничное приложение: переход по странице без перезагрузки страницы
  • Возможности Vue: двусторонняя привязка данных прогрессивного фреймворка.
    • Двусторонняя привязка данных: изменения представления автоматически обновляют данные, представление обновления данных изменяется автоматически.
    • Прогрессивный: vue vue-router маршрутизация vuex axios
    • Фреймворк: написанный вами код вызывается фреймворком (библиотека: код, который сам вызывает библиотеку)
  • декларативный

установить вью

командная команда

npm i vue

yarn add vue

Основной метод реализации Vue

var obj={}
Object.defineProperty(obj,'name',{
     value:'xhufeng',
     configurable:true,//是否可删
     writable:true,//是否可写
     enumerable:true,//是否可枚举(循环)
     set(val){
        //只要外界给name赋值,就会触发该函数
        //形参val就是外界赋予的值
     },
     get(){
        return 123
     }
  })

директива vue

Директивы являются встроенными атрибутами
v-modelРазмещено на вводе, текстовая область, выберите> вариант для достижения двусторонней привязки данных
v-textотображать соответствующий текст
v-onceСоответствующая метка отображается только один раз
v-show=布尔Можно ли отобразить, true можно отобразить, false нельзя отобразить (имеется неявное преобразование)
v-htmlОтобразить метку в значении

v-for

Перебор элементов
Может перебирать массивы, объекты, числа, строки
лучше всего добавить:key='a+i'
v-for='item in ary'

v-bind

Используется для привязки встроенных свойств сокращенно:

v-if

Контролирует, отображать ли элемент
Значение true для рендеринга элемента; false чтобы не рендерить
иv-else v-else-ifиспользовать по очереди
Вы можете использовать тег шаблона, лишних тегов не будет.

<body>
    <div id="app">
        <h1>{{name}}</h1>
        <button @click='flag=!flag'>按钮</button>
        <h2 v-show='flag'>hello</h2>
        <h2 v-show='!flag'>world</h2>
        
        <button @click='n=1'>1</button>
        <button @click='n=2'>2</button>
        <button @click='n=3'>3</button>
        <h3 v-if='n===1'>hello</h3>
        <h3 v-else-if="n===2">hahaha</h3>
        <h3 v-else>world</h3>
    </div>
</body>

</html>
<script src="./node/node_modules/vue/dist/vue.js"></script>
<script>
    let vm = new Vue({
        el: '#app',
        data: {
            name: "珠峰",
            flag:true,
            n:1
        },
        methods: {
            fn() {

            }
        }
    })
</script>
v-cloak

Необходимо использовать с css: решить проблему с отображением усов

v-pre

Пропустить компиляцию тегов и их подэлементов с помощью этой директивы и компилировать в соответствии с нативным кодом

объект

Атрибуты в данных в конечном итоге добавляются к экземпляру Свойству требуется набор для запуска обновления представления.

     let vm = new Vue({
         el: '#app',
         data: {
             name: 'liu',
             age:21,
             q:'<h1>haha</h1>',
             obj:{
                 a:123,//对于对象来说,新增一个属性不会触发视图更新,只有改变属性时才会触发视图更新
                 b:undefined,
             }
         }
     }).$mount('#app')
     //处理方式
     //1.正常写全要用到的属性;先预留要用到的属性
     //2.整个对象的重新赋值
     //3.$set()方法
     vm.$set(vm.obj,'c','456')
     //4.增加一个无关变量t,每次修改完数据之后;重置t就可以了

vue-массив

    let vm = new Vue({
        el: '#app',
        data: {
            ary: [1, 2, 3, 4]
        }
    })
    vm.ary.length--;
    //能改变原有数组,但不能触发视图更新,只有数组原型上的变异方法可以触发更新
    //数组变异方法:pop shift unshift push reverse splice sort

vue событие

<body>
    <div id="app">
        {{ary}}
        <button @click='fn'>按钮1</button>
        <button @click='fn(name,$event)'>按钮2</button>
        <!-- $event是固定写法,代表传参事件对象 -->
    </div>
</body>

</html>
<script src="./node/node_modules/vue/dist/vue.js"></script>
<script>
    //事件绑定,用v-on:事件类型=‘函数’  或者  @事件类型=‘函数’
    //函数一般是在methods中定义的
    //对应的函数一般不带小括号,默认传参事件对象e
    //当我们需要传参时,需要加小括号,小括号里写需要传的参数;当只有小括号没有传参时,为undefined
    //el data methods 都是VUE规定死的属性名 
    let vm = new Vue({
        el: '#app',
        data: {
            ary: [1, 2, 3, 4],
            name:'liu'
        },
        methods: {
            fn: function (val,e) {
                console.log(val,e,this)
            }
        }
    })
    //@kryup.13='fn'在按下回车的时候才会触发该函数
</script>

вью фильтр

Использовать фильтр глобально, использовать фильтры локально, например Глобальный фильтр следует размещать перед экземпляром, который необходимо использовать.

vue вычисляемое свойство вычисляется

  • тот же уровень, что и данные
  • Синтаксис такой же, как у методов
  • Имя вычисляемого свойства не может совпадать с именем в данных или методах.
  • Он полностью зависит от имени свойства, которое появляется в теле функции, и запускается только при первоначальной загрузке и изменении имени свойства.Это не похоже на функцию в методах, которая запускается после обновления страницы.
  • Не могу передать параметры
  • Асинхронный не может справиться
  • существует для повышения производительности

свойство прослушивания vue

  • Функция выполняется тогда и только тогда, когда отслеживаемое свойство (например, имя) изменяется
  • Может справиться с асинхронностью
  • Следующий метод записи не может отслеживать внутренние изменения эталонного типа данных.
 watch:{
            name(newV,oldV){
                clearTimeout(this.timer)
                this.timer=setTimeout(() => {
                    if (newV.length > 5) {
                        this.msg2 = '名字太长'
                    }else{
                        this.msg2 = ''
                    }
                }, 500)
            }
        }
  • Для глубокого мониторинга требуется следующий синтаксис
  • Этот глубокий мониторинг будет запускать мониторинг только тогда, когда есть свойства get и set
        watch:{
            obj:{
                handler(){
                    console.log(1111)
                },
                deep:true
             }
        }

директивыПользовательские директивы

Объект определения директивы может предоставлять следующие функции ловушек (все необязательные):

  • bind: вызывается только один раз, когда директива впервые привязывается к элементу. Здесь можно выполнить одноразовые настройки инициализации.
  • вставленный: вызывается, когда связанный элемент вставляется в родительский узел (гарантируется существование только родительского узла, но не обязательно вставленного в документ).
  • update: вызывается при обновлении VNode компонента, но может произойти до обновления его дочерних VNode. Значение инструкции может измениться, а может и не измениться. Но вы можете игнорировать ненужные обновления шаблона, сравнив значения до и после обновления (подробнее о параметрах функции хука см. ниже).
  • componentUpdated: вызывается после VNode компонента, в котором обновляются инструкция и ее дочерние VNode.
  • unbind: вызывается только один раз, когда инструкция отсоединяется от элемента.

анимация

transition
  • Оберните теги, которые необходимо анимировать, тегами перехода.
  • Может быть анимирован только на корневом элементе

transition-group
  • тег определяет тип тега внешнего элемента-обертки; если он не указан, диапазон по умолчанию
  • продолжительность определяет, как долго существует имя класса, установленное vue.

модификатор события

  • .selfСобытие запускается только при нажатии на сам элемент
  • .stopПрекратите всплывать события
  • .preventБлокировать события по умолчанию
  • .onceСоответствующая функция срабатывает только один раз
  • .captureИнициировать вторичные события привязки на этапе захвата
  • .passiveПриоритет событий по умолчанию (поведение прокрутки)

модификатор формы

  • .numberПреобразуется в числа, аналогично преобразованию синтаксического анализа.
  • .trimУдалить пробелы до и после строки

жизненный цикл

enter image description here

    let vm = new Vue({
        el:'#app',
        // template:'<h1>哈哈哈</h1>',
        data:{
            name:"liu"
        },
        // 生命周期钩子函数 就是VUE规定的一些在固定阶段执行的函数
        // 语法上 跟 data和el、methods等 同级
        beforeCreate(){
            // 创造之前
            // 不能获取data和methods里的数据
            console.log('beforeCreate');
            debugger;
        },
        created(){            
           // 能获取data和methods里的数据
           // 一般把ajax请求的发送写到这里
        },
        beforeMount() {},
        mounted(){
           // 在此时DOM已经渲染完成
        },
        beforeUpdate(){
           // 在视图更新时会触发其中函数
           // 函数在视图更新前执行
        },
        updated(){
           // 在视图更新时会触发其中函数
           // 函数在视图更新后执行
           // 不要写会触发视图更新的代码
        },
        beforeDestroy(){},
        destroyed(){}
    })
    vm.$destory();//手动销毁该实例,双向数据绑定没了

компоненты

  • Разделение более подробное, а уровень повторного использования относительно высок.
  • Функциональные компоненты Компоненты уровня страницы
  • глобальный компонент локальный компонент
  • В шаблоне шаблона может быть только один корневой элемент

Регистрация глобальных компонентов

  • Должен быть записан перед корневым компонентом (корневой экземпляр)
    //全局组件的定义
    Vue.component('qqq',{
        template:'<i>hello 小聪子</i>'
    })
<body>
    <div id="app">
        <h1>{{name}}</h1>
        <aaa></aaa>
        <aaa></aaa>
        <my-name></my-name>
        <!-- 不支持驼峰式命名 -->
        
    </div>
</body>
   <template id='qqq'>
        <div>
            <input type="text" v-model='name'>
            <h1><i>{{name}}</i></h1>
        </div>
    </template>

<script>
    //全局组件的定义
    //使用时只要把组件名当作标签使用即可
    Vue.component('aaa', {
        //没有el属性,有template属性,data是个函数,并且返回一个对象
        //template就是qqq标签要去展示的内容
        //template有且只能有一个根元素
        template: '#qqq',
        data() {
            return {
                name: 'liu'
            }
        },
        created() {
            console.log(this.name)
        }
    })
    Vue.component('myName', {
        template: `<h2>My name is </h2>`,
        data() {
            return {
            }
        },
    })
    let vm = new Vue({
        el: '#app',
        data: {
            name: "liu"
        }
    })
</script>

Регистрация локальных компонентов

  • Частичный компонент может использовать только частичный компонент, объявленный до этого как дочерний компонент.

<body>
    <div id="app">
        <h1>{{name}}</h1>
        <son></son>

        <parent></parent>
    </div>
</body>

<template id="opp">
    <h2>ninininini</h2>
</template>

<template id="o">
    <h2>小聪子<son></son></h2>
</template>

<script>
    let son = {
        template: '#opp',
        data() {
            return {

            }
        }
    }
    let parent = {
        template: '#o',
        data() {
            return {

            }
        },
        components: {
            son
        }
    }
    let vm = new Vue({
        el: '#app',
        data: {
            name: "liu"
        },
        components: {
            son,
            parent: parent
        }
    })
</script>

передача данных компонента

отец сыну

процесс

  • 1. Передать соответствующие данные дочернему компоненту через свойство привязки v-bind
  • 2. Подкомпоненты получают входящие данные через пропсы

Меры предосторожности

  • Родитель-потомок — это односторонний поток данных, и данные родительского компонента не могут быть изменены из дочернего компонента.
  • Но если это ссылочный тип данных, не изменяйте адрес, меняйте только содержимое, вы можете изменить
  • props могут быть массивами или объектами
  • Параметры пользовательских свойств в реквизите
  • - 1.default:默认值
    
  • - 2.type:规定此属性的数据类型
    
  • своим примеромthis.$parentВызов данных и методов родительского компонента (не рекомендуется)
<body>
    <div id="app">
        <h1>{{name}}</h1>
        <input type="text" v-model='name'>
        <son :name='name'></son>
    </div>
</body>

<template id="o">
    <div>
        <h3>{{name}}</h3>
        <button @click='fn'> 这个按钮点击了{{n}}次</button>
    </div>
</template>

<script>
    let son = {
        template: '#o',
        data() {
            return {
                n: 0
            }
        },
        methods: {
            fn() {
                this.n++
            }
        },
        props:['name']
    }
    let vm = new Vue({
        el: '#app',
        data: {
            name: "liu"
        },
        components: {
            son,
        }
    })
</script>
сын к отцу

По сути, родительский компонент использует данные дочернего компонента.

официальный процесс

  1. Метод триггера в родительском компоненте через пользовательское событие
  2. Затем выполнение метода подкомпонента передается черезthis.$emit('自定义事件名',this.qqq)Передать данные из дочерних компонентов

Вы также можете передать его в родительский компонентthis.$children[i]Данные и методы вызова подкомпонентов Вы также можете передать его в родительский компонентthis.$refs.sonВызвать метод дочернего компонента

слот

Напишите в шаблоне шаблона<slot></slot>, который может отображать содержимое внутри тега имени компонента при использовании компонента

именованный слот

Атрибут имени в теге слота — это функция, которая определяет, какую часть отображать. Когда не написано, по умолчанию по умолчанию, все отображается Название соответствуетslot='qqq'часть

При наличии в шаблоне элемента, соответствующего значению имени, содержимое, содержащееся в теге слота, отображаться не будет, в противном случае оно может отображаться

Монтирование дочернего и родительского компонентов

исполнительный лист

динамический компонент

keep-alive

- Когда нет поддержки активности, компонент компонента уничтожает старый и повторно рендерит новый. - После добавления keep-alive динамические компоненты имеют механизм кэширования и не уничтожат старые

  <keep-alive>
      <component :is='son'></component>
  </keep-alive>

vue-router

vue-router — плагин маршрутизации для vue.

Основное использование

  • шаг
  • 1. Объявить компоненты
  • 2. Напишите таблицу сопоставления маршрутизации
  • 3. Вставьте отредактированную таблицу сопоставления в экземпляр маршрутизатора.
  • 4. Вставьте экземпляр маршрутизатора в корневой экземпляр.
  • router-link управляет ссылкой перехода и отображаемым текстом
  • router-view управляет отображаемым содержимым компонентов
  • active-class управляет именем класса соответствующего выбранного пути
  • тег управляет тем, во что будет отображаться тег
<body>
    <div id="app">
       <router-link to='/home' active-class='current'>首页</router-link>
       <router-link to='/list' tag='div'>列表</router-link>
       <router-view></router-view>
    </div>
</body>

</html>
<template id="home">
    <div>home</div>
</template>
<template id="list">
    <div>list</div>
</template>
<script src="../node/node_modules/vue/dist/vue.js"></script>
<script src="../node_modules/vue-router/dist/vue-router.js"></script>
<script>

    let home = {
        template: '#home',

    }
    let list = {
        template: '#list',

    }

    //路由映射表
    let routes = [{
            path: '/home',
            component: home
        },
        {
            path: '/list',
            component: list
        }
    ]

    let router=new VueRouter({
        routes:routes,
    })
    let vm = new Vue({
        el: '#app',
        data: {
            name: "liu"
        },
        router,
    })
</script>

передать параметры

  • Предоставляет два способа передачи параметров
  • 1, параметр запроса (параметр вопросительного знака)
  • Карту маршрутизации менять не нужно:to={path:'',query:{}}или:to={name:'',query:{}}
  • 2, параметр params (параметр пути)
  • добавить в таблицу сопоставления/:变量форма;:to={name:'',params:{变量:''}}}

<router-link :to='{path:"/list",query:{id:123,e:name}}' tag='div'>列表</router-link>

перенаправить перенаправить

let routes = [
        {
            path:'/',
            redirect:'/son2/222'
        },
        {
            path:'/son1',
            // redirect:'/son2/5555',
            name:'son1',
            component:son1,
            redirect:'/son1/sz',
            children:[
                {
                    path:'/son1/sz',
                    component:sz
                }
            ]
        },
        {
            path:'/son2/:bl1234',
            name:'son2',
            component:son2
        },
        {
            path:'/*',
            redirect:'/son1'
        }
    ]

vuex

Это плагин, который может облегчить передачу данных экземпляров vue и их компонентов. Облегчить передачу данных в виде библиотеки для общедоступного хранения данных

Основное использование

  • шаг
  • 1. Создайте экземпляр vuex
  • 2. Зарегистрируйте его в корневом компоненте
  • 3. После регистрации корневой компонент и локальные или глобальные компоненты под ним могут использовать методы данных в экземпляре vuex.Когда несколько компонентов используют один и тот же набор правил, мы можем написать этот набор правил отдельно и написать их для общего использования. в экземпляре vuex.

Сводка метода

state

Подобно данным в экземпляре vue, храните данные использовать в экземпляре vuethis.$store.stateВызовите данные в состоянии использовать...Vuex.mapStore(['count'])поместить свои данные в вычисляемый

mutations

Единственный способ изменить данные, предоставленные официальным которая должна быть синхронной функцией пройти черезcommitдля вызова функции в мутациях где функция имеет хотя бы один параметрstate, до двух параметров плюсval(параметры при звонке) использовать...Vuex.mapMutations(['mu_add'])Поместите его функцию в методы

actions

Вы можете писать асинхронные функции, которые обычно используются для запуска ajax-запросов. Его нельзя напрямую использовать для изменения данных в состоянии.Вам необходимо передать первый параметр obj функции по умолчанию и использоватьobj.commit('mu_')вызвать функцию в мутациях для изменения данных использовать...Vuex.mapActions(['ac_add'])Поместите его функцию в методы

getters

Подобно вычисляемым свойствам в экземплярах vue, хранение данных использовать...Vuex.mapGetters(['remove'])поместить свою функцию в вычисляемый

    //1、创造一个vuex实例
    //2、把创造的实例放到根实例中
    //使用this.$store.state
    let son1 = {
        template: `<div>
                <button @click='add'>增加</button>
                <button @click='mu_add(100)'>增加</button>
                <button @click='add2(100)'>2增加</button>
                <h2>{{count}}</h2>
                <h2>{{qqq}}</h2>
            </div>`,
        data() {
            return {

            }
        },
        computed: {
            //两种监听vuex数据的写法
            // myCount(){
            //     return this.$store.state.count
            // }
            ...Vuex.mapState(['count', 'qqq'])
        },
        methods: {
            add() {
                // this.$store.state.count++
                // this.$store.commit('mu_add', 1)
                this.mu_add(10)
            },
            ...Vuex.mapMutations(['mu_add']),
            add2() {
                this.$store.dispatch('ac_add', 22)
                //dispatch 触发的是actions里的函数
                //commit   触发的是mutations里的函数
            }
        }
    }
    let son2 = {
        template: `<div>
                <button @click='remove'>减少</button>
                <h2>{{$store.state.count}}</h2>
            </div>`,
        methods: {
            remove() {
                this.$store.commit('mu_remove', 1)
            }
        },
    }
    let store = new Vuex.Store({
        state: {
            count: 0,
            qqq: 12
        },
        
        mutations: {
            mu_add(state, val = 1) {
                console.log(arguments)
                //第一个实参是默认传的state
                //第二个实参是自己传的参数
                //一共只有一个或两个实参
                state.count += val
            },
            mu_remove(state, val = 1) {
                console.log(arguments)
                //第一个实参是默认传的state
                //第二个实参是自己传的参数
                //一共只有一个或两个实参
                state.count -= val
            }
        },
        actions: {
            ac_add(obj,n) {
                //obj是vuex封装好的一个对象,里边提供了commit方法
                obj.commit('mu_add',n)
                console.log(arguments)
            }
        }
        //mutations中必须是同步函数,actions同步异步都行
        //想要修改state里的数据只能用commit来调用mutations里的函数
    })
    let vm = new Vue({
        el: '#app',
        store,
        data: {
            name: "liu"
        },
        components: {
            son1,
            son2
        },
        created() {
            console.log(this)
        },
    })

==========================================================

Front-end Xiaobai, публикую впервые, приветствуются комментарии и исправления!