2020-08-08

1. v-show 与 v-if 区别

  • v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。它是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
  • v-show只是简单的css属性切换,无论条件真与否,都会被编译。
  • v-if更适合条件不经常改变的场景,因为它切换开销相对较大,而v-show适用于频繁切换条件。

2. 动态绑定class的⽅法

1.对象语法

  • ​ 给v-bind:class 设置一个对象,可以动态地切换class,如下
        <div class="body">
            <div class="left">
                <Left v-bind:value="left"></Left>
            </div>
            <div class="right">
                    <Right :value="right">          
                    </Right>
            </div>
        </div>
    
  • 对象中可以传入多个属性,动态切换class; :class可以与普通class共存
<div class="row">
            
            <div class="col-lg-3">          
            <button class="btn btn-default btn-block" :class="{'btn-success': typeIndex == 0,
            'btn-default':typeIndex != 0}" @click="typeClick(0)">全部</button>
            <button v-for="(item,index) in typelst" class="btn btn-default btn-block"
             :class="{'btn-success': typeIndex == index+1,'btn-default':typeIndex != index+1}"
              @click="typeClick(index+1)">{{item}}</button>
            <!-- <button class="btn btn-info btn-block">水果零食</button>
            <button class="btn btn-info btn-block">生活用品</button> -->
            </div>
  • 当class的表达式过长或者逻辑复杂时候,可以绑定一个计算属性
  • 也可以直接绑定一个Object类型的数据,或者使用类似计算属性的methods

2.数组语法

  • 当需要应用多个class,可以使用数组语法,给:class 绑定一个数组,应用一个class列表

3. 计算属性和 watch 的区别

computed计算属性是用来声明式的描述一个值依赖了其它的值,当所依赖的值或者变量改变时,计算属性也会跟着改变;

<div> 选中商品的数量: {{selectedCount}}</div>
<div> 选中商品的总价: {{selectedTotalPrice}} </div>

computed:{
                selectedCount: function() {
                    let result = 0;
                    for (let i = 0; i < this.lst.length; i++) {
                        if (this.lst[i].checked) {
                            result+=this.lst[i].number;
                        }
                    }
                    return result;
                },
                selectedTotalPrice:function() {
                    let result = 0;
                    for (let i = 0; i < this.lst.length; i++) {
                        if (this.lst[i].checked) {
                            result+=this.lst[i].number*this.lst[i].price;
                        }
                    }
                    return result;
                }
        }

watch 监听的是已经在 data 中定义的变量,当该变量变化时,会触发 watch 中的方法。

4. ⽣命周期的钩子函数有哪些,分别可以在什么场景下使用

1. beforeCreate(创建前)

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

2. created(创建后)

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

3. beforeMount(载入前)

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

4. mounted(载入后)

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

5. beforeUpdate(更新前)

在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前。

6. updated(更新后)

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

7. beforeDestroy(销毁前)

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

8. destroyed(销毁后)

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

5. 父组件和子组件之间传值, 写一个案列

export default {
  name: 'App',
  data:function(){
      return {
          left:["left1","left2"],
          right:["right1","right2","right3"],
          name:"",
          vv:"", 
      }
  },
  /* 声明一个组件的名称,不重复就行*/
  methods:{
      getValue(value){
          //获取子组件传递值的回调函数
          this.name=value;
      }
  },
  components: { 
      /* 当键和值一样可以只写一个*/
    HelloWorld:HelloWorld,
    Header,
    Left,
    Right,
    BBB
    /* 注册组件  注册完组件就可以开始使用 */
  }
}
</script>
<template>
    <div>
        <Item :aa="value[0]"></Item>
        <Item :aa="value[1]"></Item>
        <Item :aa="value[2]"></Item>
        
        
    </div>
</template>

<script>
    import Item from './Item.vue'
    export default {
      name: 'Right', /* 声明一个组件的名称,不重复就行*/
      props:{
          value:Array
      },
      components:{
               Item
          },
      created() {
            console.log(this.value)
          }
    }
</script>

6. 写一个插槽使用的案列

<template>
    <div>
        
        <slot name="top" ></slot>
        用户名:<input type="text" name="username" />
        <slot name="middle"></slot>
        密码:<input type="text" name="password" />
        密码:<input type="text" name="password" />
         <slot name="bottom"></slot>
    </div>
</template>

<script>
    export default{
        name:"BBB"
    }
</script>
<div class="bb">
            <BBB>
                <!-- 把三个空的内容传递进去 -->
                <!-- 当子组件中欧协标签需要父组件自定义的时候可以使用插槽 -->
            <template v-slot:top>
                <h1>忘记密码</h1>
            </template>
            <template v-slot:middle>
                    <!-- <h1>忘记密码</h1> -->
                问题<input type="text"/>
                回答<input type="text"/>      
            </template>
            <template v-slot:bottom>
                <input type="submit" value="找回密码" />
            </template>
            </BBB>
        </div>

7. 声明式路由和编程式路由,写个案列

编程式路由:

<script>
export default {
    name:"login",
    methods:{
        telLogin() {
            this.$router.replace( // 编程式路由
                { name: 'tellogin'}
            ).catch(err=>{})
        },
        emailLogin() { 
            this.$router.replace( //编程式路由
                { name: 'emaillogin', params:{username:'zhangsan'},query:{age:12,gender:"男"}}
             ).catch(err=>{})
        }
    },
    created() { // 生命周期
        // 获取到动态路由传递的值
        let route = this.$route;
        console.log(route.params.id) // 获取到路由链接上传递的值
    }
}
</script>

8. 利用axios和Promise封装一个网络请求

import axios from 'axios';
import qs from "qs";

axios.interceptors.request.use(function (config) {
    config.headers.auth = "aaa";
  return config;
  }, function (error) {
    return Promise.reject(error);
  });

export default function request(url,method="get",data={},header={}) {
  // if (url.indexOf("res") == -1) {
  //   header['auth'] = "auth..."
  // }
  return new Promise((resolve, reject)=> {
    if (url == null) reject("url不能为空");
    axios({
      method: method,
      url: url,
      data: qs.stringify(data),
      headers: header,
    }).then(data=>{
      resolve(data.data);
    }).catch(err=>{
      reject(err)
    });
  })
}

9. 路由之间传值

<template>
  <div id="app">
    <div id="nav">
      <router-link :to="loginpath">登录</router-link> |
      <router-link to="/register" class="register" active-class="registeract" tag="button">注册</router-link>
    </div>
    <router-view/>
  </div>
</template>
<script>
  export default{
    name:'App',
    data:function(){
      return{
        id:4
      }
    },
    computed:{
      loginpath:function(){
        return "/login/" + this.id
      }
    }
  }

10. 嵌套路由的配置

const routes = [
    {
        path: '/',   // 默认的页面
        name: 'index',
        redirect: { name: 'login',params:{"id":10}}
    },
  {
    path: '/login/:id',   // 动态的路由
    name: 'login',
    component: Login,
    alias: '/dl/:id', // 起别名
    children: [
        {
          path: '/tellogin',  
          name: 'tellogin',
          component: TelLogin
        },
        {
          path: '/emaillogin/:username',  
          name: 'emaillogin',
          component: EmailLogin
        },
    ]
  },

11. 写个vuex的使用案列

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
  state: {
    count: 10,
    carts:[]
  },
  mutations: {
    increment (state,number) {
      state.count+=number;
    },
    addCart(state,goods){
        let tag = false;
        for (let i = 0; i < state.carts.length; i++) {
            let item = state.carts[i];
            if(item.id == goods){
                this.carts[i].number += 1;
                tag = true;
                return;
            }
        }
        if(!tag){
            goods.number = 1;
            goods.checked = true;
        }
        state.carts.push(goods);
    }
  },
  actions: {
      increment (context,number) {
        context.commit('increment',number)
      },
      addCart(context,goods){
          context.commit()
      }
    }
})
export default store;

12. 使用element_ui 写一个表单(包含 输入框,单选框,复选框, select, 时间选择器),获取到里面的值并输入到页面上

<template> 
    <div style="width: 500px;height: 250px; margin: 100px auto;"> 
        <el-form ref="form" :model="form" label-width="80px"> 
          <el-form-item label="输⼊框"> 
            <el-input v-model="form.name"></el-input> 
          </el-form-item> 
          <el-form-item label="地点"> 
            <el-select v-model="form.region" placeholder="请选择"> 
              <el-option label="上海" value="shanghai"></el-option> 
              <el-option label="北京" value="beijing"></el-option> 
            </el-select> 
          </el-form-item> 
          <el-form-item label="时间"> 
            <el-col :span="11"> 
              <el-date-picker type="date" placeholder="选择⽇期" v-
model="form.date1" style="width: 100%;"></el-date-picker> 
            </el-col> 
            <el-col class="line" :span="2">-</el-col> 
            <el-col :span="11"> 
              <el-time-picker placeholder="选择时间" v-model="form.date2" 
style="width: 100%;"></el-time-picker> 
            </el-col> 
          </el-form-item> 
          <el-form-item label="复选框"> 
            <el-checkbox-group v-model="form.type"> 
              <el-checkbox label="复选⼀" name="type"></el-checkbox> 
              <el-checkbox label="复选⼆" name="type"></el-checkbox> 
              <el-checkbox label="复选三" name="type"></el-checkbox> 
              <el-checkbox label="复选四" name="type"></el-checkbox> 
            </el-checkbox-group> 
          </el-form-item> 
          <el-form-item label="单选框"> 
            <el-radio-group v-model="form.resource"> 
              <el-radio label="单选框⼀"></el-radio> 
              <el-radio label="单选框⼆"></el-radio> 
            </el-radio-group> 
          </el-form-item> 
          <el-form-item> 
            <el-button type="primary" @click="onSubmit">提交</el-button> 
          </el-form-item> 
        </el-form> 
        <h1>信息显示</h1> 
        <h4>输⼊框:{{form.name}}</h4> 
        <h4>地点:{{form.region}}</h4> 
        <h4>⽇期:{{form.date1}}</h4> 
        <h4>时间:{{form.date2}}</h4> 
        <h4>复选框:{{form.type}}</h4> 
        <h4>单选框:{{form.resource}}</h4> 
    </div> 
     
</template> 
 
<script> 
   export default { 
        data() { 
             return { 
               form: { 
                 name: '', 
                 region: '', 
                 date1: '', 
                 date2: '', 
                 type: [], 
                 resource: '' 
               } 
             } 
           }, 
       methods: { 
          onSubmit() { 
              this.$router.push({ 
                 name: "Menu" 
              }) 
          } 
       } 
   } 
</script> 

13. 使用element_ui 写一个table, 包含姓名,年龄,操作(删除,更新)

<template> 
   <el-table :data="tableData" border style="width: 18%;margin: 100px auto;"> 
       <el-table-column prop="name" label="姓名" width="120"></el-table-
column> 
       <el-table-column prop="age" label="年龄" width="120"></el-table-column> 
       <el-table-column fixed="right" label="操作" width="100"> 
          <template slot-scope="scope"> 
              <el-button @click="handleClick(scope.row)" type="text" 
size="small">更新</el-button> 
              <el-button type="text" size="small" @click="open">删除</el-
button> 
          </template> 
       </el-table-column> 
   </el-table> 
</template> 
 
<script> 
   export default { 
       methods: { 
          handleClick(row) { 
              console.log(row); 
          }, 
          open() { 
              this.$confirm('此操作将永久删除该数据,        是否继续?', '提示', { 
                 confirmButtonText: '确定', 
                 cancelButtonText: '取消', 
                 type: 'warning' 
              }).then(() => { 
                 this.$message({ 
                     type: 'success', 
                     message: '删除成功!' 
                 }); 
              }).catch(() => { 
                 this.$message({ 
                     type: 'info', 
                     message: '已取消删除' 
                 }); 
              }); 
          } 
       }, 
       data() { 
          return { 
              tableData: [{ 
                 name: '学生 1', 
                 age: 11 
              }, { 
                 name: '学生 2', 
                 age: 12 
              }, { 
                 name: '学生 3', 
                 age: 13 
              }, { 
                 name: '学生 4', 
                 age: 14, 
              }] 
          } 
       } 
   } 
</script> 
 
<style> 
   .el-header { 
       background-color: #B3C0D1; 
       color: #333; 
       line-height: 60px; 
   } 
 
   .el-aside { 
       color: #333; 
   } 
</style> 
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,723评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,003评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,512评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,825评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,874评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,841评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,812评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,582评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,033评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,309评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,450评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,158评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,789评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,409评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,609评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,440评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,357评论 2 352