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

 
回答:Vue的安装可以从两个方面进行安装,第一种是CDN引入,第二种是NPM安装。
 
CDN引入
 
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
NPM安装
 
npm install vue
面试官问,如何创建Vue项目?
 
写下代码:
 
创建项目
 
<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <title>Vue入门之Helloworld</title>

    <!--引入Vue库-->

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

</head>

<body>

    <!--创建一个Div-->

    <div id="app">

        <!--Vue的模板的绑定数据的方法,用两对花括号进行绑定Vue中的数据对象的属性 -->

        {{message}}

    </div>

 

 

    <!--创建Vue的对象,并把数据绑定到上面创建好的div上去。-->

    <script type="text/javascript">

        var app=new Vue({ // 创建Vue对象。Vue的核心对象。

            el:'#app', // el属性:把当前Vue对象挂载到 div标签上,#app是id选择器

            data:{    // data: 是Vue对象中绑定的数据

                message:'hello Vue!' // message 自定义的数据

            }

        })

</script>

</body>

</html>
 
 
输出的结果:
 
hello Vue!
面试官问:v-if和v-show的区别是?
 
回答:
 
内部指令
 
v-if用于显示与隐藏的元素
 
<div v-if="isShow">前端</div>
v-else,v-if不是它,就是它v-else
 
<div v-else>前端</div>
v-show
 
<div v-show="isShow">你好</div>
v-else-if
 
<div v-if="type === 'A'">A</div>
<div v-else-if="type === 'B'">B</div>
<div v-else-if="type === 'C'">C</div>
<div v-else>Not A/B/C</div>
v-if和v-show的区别是:
 
v-if用于元素的被销毁和重建,使用这个指令开销较为高,在运行过程中,尽量用在很少改变时的情况下使用。v-if元素销毁和存在
 
v-show的用法,这个指令的使用开销较小,在常频繁地切换使用
 
面试官问:内部指令的用法有哪些,怎么用呢?
 
回答:好,慢慢讲述。
 
v-for的用法
 
<!-- 模板 -->

<div id="app">

    <ul>

        <li v-for="item in items">

            {{item}}

        </li>

    </ul>

</div>

 

 

<!--JS代码 -->

<script type="text/javascript">

    var app=new Vue({

        el:'#app',

        data:{

            items:[ 1, 2, 3, 4]

        }

    })

</script>

对象遍历

<!-- 模板 -->

<div id="app">

    <ul>

        <li v-for="(value, key, index) in object">

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

        </li>

    </ul>

</div>

 

 

<!--JS代码 -->

<script type="text/javascript">

    var app=new Vue({

        el:'#app',

        data:{

            object: {

                firstName: 'dada',

                lastName: 'qianduan'

            }

        }

    })

</script>

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

<div>{{ message }}</div>

<!-- 一样的 -->

<div v-text="message"></div>

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

<span v-html="msgHtml"></span>

v-on的用法

// html

<div>{{count}}</div>

<button v-on:click="add">加</button>

 

 

// JS

data:{

    count: 1

},

methods: {

    add() {

        this.count++;

    }

}

缩写

<button @click="add">加</button>

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

data: {

    count: 1,

}

input的用法

<input type="text" v-model="message">

textarea

<textarea  cols="30" rows="10" v-model="message"></textarea>

checkbox

<input type="checkbox" id="first" value="1" v-model="status">

<label for="first">有效</label>

 

 

<input type="checkbox" id="second" value="2" v-model="status">

<label for="second">无效</label>

 

 

<div>状态:{{status}}</div>

radio

<input type="radio" id="one" value="男" v-model="sex">

<label for="one">男</label>

 

 

<input type="radio" id="two" value="女" v-model="sex">

<label for="one">女</label>

 

 

<div>性别:{{sex}}</div>

select

<select v-model="selected">

    <option disabled value="">请选择</option>

    <option>A</option>

    <option>B</option>

    <option>C</option>

</select>

 

 

<div>Selected: {{ selected }}</div>

v-bind方法

// html

<img v-bind:src="imgSrc"  width="200px">

 

 

// js

data: {    

    imgSrc:''

}

缩写

<img :src="imgSrc"  width="200px">

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

<div v-pre>{{message}}</div>

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

// css

[v-cloak] {

    display: none;

}

 

 

// html

<div v-cloak>{{message}}</div>

v-once只能显示一次,第一次渲染的值就不会改变了
 
<div v-once>{{message}}</div>
面试官问:你知道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中常用的语句有哪些
 
回答:好的,请认真听讲
 
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');

}

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


回答:知道吧


<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <title>Vue入门之自定义指令</title>

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

</head>

<body>

<div id="app">

    <div v-test="color">

        {{num}}

    </div>

</div>

<button onclick="unbindApp()">解绑</button>

 

 

<script type="text/javascript">

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'

    }

})

</script>

</body>

</html>

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


回答,用过的


组件全局注册


Vue.component('button-counter', {

    data: function () {

        return {

            count: 0

        }

    },

    template: '<button v-on:click="count++">全局组件: {{ count }}</button>'

});

 

 

new Vue({

    el: '#app'

});

 

 

<button-counter></button-counter>

组件局部注册


new Vue({

    el: '#app',

    components:{

        "button-inner":{

            data: function() {

                return {

                    inner: 0

                }

            },

            template: '<button v-on:click="inner++">局部组件: {{ inner }}</button>'

        }

    }

});

 

 

<button-inner></button-inner>

props属性传值


new Vue({

        el: '#app',

        components:{

            "button-props":{

                template:`

                <div style="color:red;">

                参数1: {{ da }}:---参数2: 

                {{fromHere}}

                </div>

                `,

                props:['da', 'fromHere']

            }

        }

    });

 

 

// html使用

<button-props da="da" from-here="world"></button-props>

 

 

props中需要驼峰取值

父子组件


// 子组件

var city = {

    template:`<div>dada</div>`

}

// 父组件

var parent = {

    template:

        `<div>

            <p> dadada!</p>

            <city></city>

        </div>`,

    components:{

        "city": city

    }

}

 

 

// 实例化

new Vue({

    el: '#app',

    // 定义局部组件

    components:{

        // 组件注册

        "parent": parent

    }

});

 

 

// html使用

<parent></parent>

面试官:你了解模板吗?


回答:还好


<div id="app">

</div>

 

 

<script type="text/javascript">

    // 实例化

    new Vue({

        el: '#app',

        data: {

            message: 'hello'

        },

        template:`<h1 style="color:red">模板</h1>`

    });

</script>

<div id="app">

    <template id="demo2">

        <h2 style="color:red">template模板</h2>

    </template>

</div>

 

 

<script type="text/javascript">

    // 实例化

    new Vue({

        el: '#app',

        data: {

            message: 'hello'

        },

        template:'#demo2'

    });

</script>

<div id="app">

</div>

 

 

<script type="x-template" id="demo3">

    <h2 style="color:red">script标签模板</h2>

</script>

 

 

<script type="text/javascript">

    // 实例化

    new Vue({

        el: '#app',

        data: {

            message: 'hello'

        },

        template:'#demo3'

    });

</script>

面试问:你了解插槽不?


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


<div id="app">

    <children>

        <span>123</span>

    </children>

</div>

 

 

<script type="text/javascript">

    var app = new Vue({

        el: '#app',

        components: {

            children: {

                template: "<button><slot></slot>单个插槽</button>"

            }

        }

    });

</script>

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


<div id="app">

    <children>

        <span slot="first" @click="toknow">123</span>

        <span slot="second">456</span>

    </children>

</div>

 

 

<script type="text/javascript">

    var app = new Vue({

        el: '#app',

        methods: {

            toknow: function () {

                console.log("dada");

            }

        },

        components: {

            children: {

                template: "<button>

                <slot name='first'>

                </slot>

                具名插槽

                <slot name='second'>

                </slot>

                </button>"

            }

        }

    });

</script>

作用域插槽slot


<div id="app">

    <!-- 将数据传递给组件 -->

    <tb-list :data="data">

        <template slot-scope="scope">

            <p>索引:{{JSON.stringify(scope)}}</p>

            <p>索引:{{scope.$index}}</p>

            <p>姓名:{{scope.row.name}}</p>

            <p>年龄: {{scope.row.age}}</p>

            <p>性别: {{scope.row.sex}}</p>

        </template>

    </tb-list>

</div>

 

 

<script type="text/javascript">

    var app = new Vue({

        el: '#app',

        data: {

            data: [{

                name: 'dada',

                age: '12',

                sex: 'man'

            }]

        },

        components: {

            // 作用域slot

            'tb-list': {

                template:

                    `<ul>

                        <li v-for="(item, index) in data">

                            <slot :row="item" :$index="index">

                            </slot>

                        </li>

                    </ul>`,

                // 获取值

                props: ['data']

            }

        }

    });

</script>
 
————————————————