(给达达前端加星标,提升前端技能)
面试官问: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 οnclick="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>
面试官问:你用过vue-cli吗?说一说
达达回答:好的
vue-cli安装,第一用npm安装
npm -v
vue-cli安装
npm install vue-cli -g
-
vue -V
-
-
-
-g代表全局安装,然后查看版本
初始化项目
-
用vue
init命令来初始化项目
-
-
-
vue
init <template-name> <project-name>
-
-
-
init:表示要用vue-cli来初始化项目
-
-
-
<template-name>:表示模板名称
-
-
-
vue-cli官方提供的
5种模板
-
-
-
webpack
-
-
-
webpack-simple
-
-
-
browserify
-
-
-
browserify-simple
-
-
-
simple
-
-
-
<project-name>:标识项目名称,用户根据自己的项目来起名字。
项目初始化
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吗?说一说
达达回答,嗯,了解。
安装
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:
'<App/>'
-
})
页面跳转
-
<router-link to="/">[显示字段]
</router-link>
-
-
-
<p>导航 :
-
<router-link to="/">首页
</router-link>
-
<router-link to="/hello">hello
</router-link>
-
</p>
编程式导航
-
this.$router.push(
'/xxx')
-
-
-
<button
@click=
"goHome">回到首页</button>
-
-
-
export
default {
-
name:
'app',
-
methods: {
-
goHome(){
-
this.$router.push(
'/home');
-
}
-
}
-
}
-
-
-
// 同于 history.back()
-
this.$router.go(
-1)
-
// 同于 history.forward()
-
this.$router.go(
1)
路由嵌套
-
<template>
-
<div class="hello">
-
<h1>{{ msg }}
</h1>
-
-
<p>导航 :
-
<router-link to="/home">首页
</router-link> |
-
<router-link to="/home/one">-子页面1
</router-link> |
-
<router-link to="/home/two">-子页面2
</router-link>
-
</p>
-
-
-
<router-view/>
-
</div>
-
</template>
-
-
-
<script>
-
export
default {
-
name:
'Home',
-
data () {
-
return {
-
msg:
'dada!'
-
}
-
}
-
}
-
</script>
-
-
-
<style scoped>
-
</style>
子页面
-
<template>
-
<div class="hello">
-
<h1>{{ msg }}
</h1>
-
</div>
-
</template>
-
<script>
-
export
default {
-
name:
'One',
-
data () {
-
return {
-
msg:
'Hi, I am One Page!'
-
}
-
}
-
}
-
</script>
-
-
-
<style scoped>
-
</style>
-
-
-
<template>
-
<div class="hello">
-
<h1>{{ msg }}
</h1>
-
</div>
-
</template>
-
<script>
-
export
default {
-
name:
'Two',
-
data () {
-
return {
-
msg:
'Hi, I am Two Page!'
-
}
-
}
-
}
-
</script>
-
-
-
<style scoped>
-
</style>
路由配置
-
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
-
},
-
]
-
}
-
]
-
})
路由传递参数
-
<router-link
:to="{name:xxx, params: {key:value}}">
-
dada
-
<
/router-link>
-
-
<router-link :to="{name: 'one', params:{username:'123'}}">
-
子页面
-
</router-link>
-
{
-
path:
'one', // 子页面
-
name:
'one', // 路由名称-命名路由
-
component:One
-
}
<h2>{{$route.params.username}}</h2>
url中传递参数
-
{
-
path:
'/home/two/:id/:name', // 子页面
-
component:Two
-
},
-
<p>ID:{{ $route.params.id}}
</p>
-
<p>名称:{{ $route.params.name}}
</p>
<router-link to="/home/two/1/达达">子页面</router-link>
编程式导航带参数
-
{
-
path:
'/home/three', // 子页面
-
name:
'three',
-
component:Three
-
}
-
<p>ID:{{ $route.params.id}}
</p>
-
<p>名称:{{ $route.params.name}}
</p>
-
<button @click=
"toThreePage">页面-
params传参</button>
-
-
-
// script
-
methods: {
-
toThreePage() {
-
this.$router.push(
-
{
-
name:
'three',
-
params: {
-
id:
1,
-
name:
'dada'
-
}
-
}
-
)
-
}
-
}
query传参数
-
{
-
path:
'/home/three', // 子页面
-
name:
'three',
-
component:Three
-
}
-
<p>ID:{{ $route.query.id}}
</p>
-
<p>名称:{{ $route.query.name}}
</p>
-
<button
@click=
"toThreePage">页面-params传参</button>
-
-
-
methods: {
-
toThreePage() {
-
this.$router.push(
-
{path:
'/home/three', query: {id:
1, name:
'da'}}
-
)
-
}
-
}
命名路由
-
{
-
path:
'one', // 子页面
-
name:
'one', // 路由名称-命名路由
-
component: One // 页面组件
-
}
-
// template跳转调用
-
<router-link :to=
"{name: 'one'}">子页面</router-link>
-
-
-
// router.push函数跳转调用
-
router.push({ name:
'user'}})
-
import Vue from 'vue'
-
import Router from 'vue-router'
-
// 创建页面组件
-
const Header = { template: '<div>Header</div>' }
-
const Left = { template: '<div>Left</div>' }
-
const Right = { template: '<div>Right</div>' }
-
-
-
Vue.use(Router)
-
-
-
export default new Router({
-
routes: [
-
{
-
path: '/', // 主页路由
-
components: {
-
default: Header,
-
a: Left,
-
b: Right
-
}
-
}
-
]
-
})
-
-
-
<template>
-
<div id="app">
-
<router-view />
-
<router-view name="a" class="left" />
-
<router-view name="b" class="right" />
-
</div>
-
</template>
-
-
-
<script>
-
export default {
-
name: 'App'
-
}
-
</script>
-
-
-
<style>
-
#app {
-
text-align: center;
-
color: #2c3e50;
-
width: 500px;
-
border: 1px solid red;
-
margin: 0 auto;
-
}
-
-
-
.left,.right{
-
float: left;
-
width:48%;
-
text-align: center;
-
border:1px solid red
-
}
-
</style>
重定向
-
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' // 重定向-传递参数
-
},
-
]
-
}
-
]
-
})
-
<router-link to="/">首页
</router-link> |
-
<router-link to="/home/two/1/lisi">子页面
</router-link> |
-
<router-link :to="{name: 'three', params: {id: 1, name: 'dada'}}">
-
子页面
-
</router-link>
redirect: '/home' // 重定向-不带参数
redirect: '/home/two/:id/:name' // 重定向-传递参数
别名
-
{
-
path:
'/one', // 子页面
-
component:One,
-
alias:
'/oneother'
-
}
<router-link to="/oneother">子页面1</router-link>
过渡动画
-
<transition name="fade" mode="out-in">
-
<router-view />
-
</transition>
-
.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: [...]
-
})
404
-
// 404
-
{
-
path:
'*',
-
component:
() =>
import(
'@/components/404')
-
}
路由钩子,第一全局钩子,第二,路由单独钩子,第三,组件内钩子
-
const router =
new VueRouter({ ... })
-
-
-
// 全局路由拦截-进入页面前执行
-
router.beforeEach(
(to, from, next) => {
-
next();
-
});
-
-
-
router.afterEach(
() => {
-
-
});
-
-
-
export
default router;
路由单独钩子
-
{
-
path:
'/home/one',
// 子页面
-
component: One,
-
-
beforeEnter:
(to, from, next) => {
-
console.log(
'进入前执行');
-
next();
-
}
-
}
组件内钩子
-
<script>
-
export
default {
-
name:
'Two',
-
data () {
-
return {
-
msg:
'dada'
-
}
-
},
-
-
-
beforeRouteEnter(to,
from, next) {
-
console.log(
'进入enter路由钩子')
-
next()
-
},
-
-
-
beforeRouteLeave(to,
from, next){
-
console.log(
'进入leave路由钩子')
-
next()
-
},
-
-
-
beforeRouteUpdate(to,
from, next) {
-
console.log(
'进入update路由钩子')
-
console.log(to.params.id)
-
next()
-
}
-
}
-
</script>
路由
-
import Home
from
'@/components/Home'
-
{
-
path:
'/home',
-
component: Home
-
}
面试官问:你了解vuex是什么吗?要不也说说
达达回答:好的。
vuex是一个为 Vue.js 应用程序开发的状态管理模式。采用集中式存储管理应用的所有组件的状态,以相应的规则保证状态以一种可预测的方式发生变化。
单向数据流
vuex的核心
安装
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;
<h2>{{ $store.state.count }}</h2>
-
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'
-
})
-
<button
@click=
"$store.commit('DA')">+</button>
-
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
代码封装
-
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全家桶】vue前端交互模式-es7的语法结构?async/await
【面试需要】掌握JavaScript中的this,call,apply的原理
2019年的每一天日更只为等待她的出现,好好过余生,庆余年 | 掘金年度征文
觉得本文对你有帮助?请分享给更多人
关注「达达前端」加星标,提升前端技能
在博客平台里,未来的路还很长,也希望自己以后的文章大家能多多支持,多多批评指正,我们一起进步,一起走花路。
非常感谢读者能看到这里,如果这个文章写得还不错,觉得「达达」我有点东西的话,觉得我能够坚持的学习,觉得此人可以交朋友的话, 求点赞,求关注,求分享,对暖男我来说真的
非常有用!!!
感谢阅读,原创不易,喜欢就点个[在看] or [转发朋友圈],这是我写作最大的动力。
意见反馈
若本号内容有做得不到位的地方(比如:涉及版权或其他问题),请及时联系我们进行整改即可,会在第一时间进行处理。
这是一个有质量,有态度的公众号
点关注,有好运
好文章,我在看❤️
转载:https://blog.csdn.net/qq_36232611/article/details/104075158