Bootstrap

学习vue2遇到过的问题及个人总结

在这里插入图片描述

文章目录

碰到的问题

1.引入开发板vue.js和引入生产板vue.min.js区别?

在这里插入图片描述

区别:
开发版提供便于后端开发者读明白的词条,比如 创建vue实例缺少new关键字时,开发版报错如图1,生产版报错如图2。

在这里插入图片描述

图1

在这里插入图片描述

图2

2.vue实例中的data属性配置只针对el所指定的容器使用有效,超出范围无效

在这里插入图片描述

在这里插入图片描述

3.插值语法{{}}和v-bind指令语法都可以修改值,区别是啥?

插值语法{{}}作用于标签体,指的是标签中间的值

在这里插入图片描述
执行语法作用于标签中的属性

在这里插入图片描述

4.数据代理中defineProperty()方法定义get()和set(),那么属性value和writable:true必须注释掉,不然报错

详情请点击跳转上方导航知识点2.7

在这里插入图片描述

5.数据代理中defineProperty()方法就是为了实现动态给let中变量赋新值,其中必须设置属性value、enumerable:true、writable:true、configurable:true等,这样效果等价于直接在let变量中新增属性,既可增删改

详情请点击跳转上方导航知识点2.7

let person = {
        name:"张三",
        sex:"男"
}

Object.defineProperty(person, "age", {
        value:18,
        enumerable:true,    //控制属性是否可以枚举(也就是是否可以遍历访问到),默认值是false
        writable:true,      //控制属性是否可以被修改,默认值是false
        configurable:true,   //控制属性是否可以被删除,默认值是false
}

6.使用数据代理问题:为什么不在let变量中直接新增k,v,而是绕了一圈使用Object.defineProperty()方法?

详情请点击跳转上方导航知识点2.7

答案:因为数据代理方法用Object.defineProperty()可扩展性更好。

7.如果defineProperty中只定义value属性,那么控制台赋值无效,即必须设置writable:true才能对person属性实现更新

详情请点击跳转上方导航知识点2.7

let number = 18
let person = {
        name:"张三",
        sex:"男"
}

Object.defineProperty(person, "age", {
        value:18,
}

在这里插入图片描述

8.使用路由问题:html项目使用路由报错

在这里插入图片描述

原因:我项目是html的去练习vue使用,所以我引入项目内的vue-router.js就无效
解决方案:
第一种:引入cdh的,不引入项目内的vue-router.js,比如
第二种:按照官网文档用npm安装一下路由
在这里插入图片描述

9.使用列表渲染发现问题1:更新数据时发现的一个问题

详情请点击跳转上方导航知识点2.10

场景说明:有一个“个人信息”的列表,现在有一个按钮,点击实现只更新马冬梅信息,并实现页面响应时更新

在这里插入图片描述

下面介绍4种操作方式,以及可能会遇到的问题

注意点1:方式1可以实现功能,但是太复杂

注意点2:
问题:为啥整个更新{}对象无效?
答案:因为我们知道所谓的页面响应式更新(也就是上面导航知识点2.10.8),其实就是内部实现了set方法调用,从而实现页面更新DOM操作,而方式2无效,则说明,内部没有实现set方法,也就无法实现更新DOM。

注意点3:为啥使用splice()方法和就可以响应式更新DOM?因为Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新(详情请看上面导航知识点2.10.8)。

注意点4:使用Vue.set()或者vm.$set()也可以实现响应式更新DOM(详情请看上面导航知识点2.10.7)。
方式1:定义方法,只修改部分属性值,也奏效。
<div id="root">
    <h2>人员列表</h2>
    <button @click="updateMei">更新马冬梅的信息</button>
    <ul>
        <li v-for="(p,index) of persons" :key="p.id">
            {{p.name}}-{{p.age}}-{{p.sex}}
        </li>
    </ul>
</div>

const vm = new Vue({
        el:'#root',
        data:{
            persons:[
                {id:'001',name:'马冬梅',age:30,sex:'女'},
                {id:'002',name:'周冬雨',age:31,sex:'女'},
                {id:'003',name:'周杰伦',age:18,sex:'男'},
                {id:'004',name:'温兆伦',age:19,sex:'男'}
            ]
        },
        methods: {
            updateMei(){
                 this.persons[0].name = '马老师' //奏效
                /this.persons[0].age = 50 //奏效
                /this.persons[0].sex = '男' //奏效
            }
        }
    })
-------------------------------------------------------------------------------------------------    
方式2:由于部分修改觉得太费事,所以准备整个{}进行更新,但是不奏效(不奏效指的是data数据确实更新了,但是vue没监听到数据改变)。
updateMei(){        
      this.persons[0] = {id:'001',name:'马老师',age:50,sex:'男'} //不奏效
            }
-------------------------------------------------------------------------------------------------
方式3:由于方式2,没效果,所以采用数组内部方法实现更新,调用splice()方法。
updateMei(){        
      this.persons.splice(0,1,{id:'001',name:'马老师',age:50,sex:'男'}) //奏效
            }
-------------------------------------------------------------------------------------------------
方式4:使用Vue.set()或者vm.$set()方法实现更新数据,也奏效
Vue.set(vm.student.hobby,0,"抽烟1")

splice使用方式如下:

在这里插入图片描述

10.使用列表渲染发现问题2:在数组前插入标签时显示结构发生问题

详情请点击跳转上方导航知识点2.10

举例说明:默认存在3个标签且有值,有一个按钮效果是在最上面新增一行标签,此时会容易发生问题
点击按钮前:
在这里插入图片描述

点击按钮后:
在这里插入图片描述

结果:顺序乱了?详细原因如下图,对比相同就复用,对比不同就重新生成DOM
在这里插入图片描述

发生错误原因:默认数组中张三索引为0,新增一行老刘后,老刘在第一行索引变为0,而原来的第一行张三索引变为1,而虚拟DOM对比算法比较的是小标签的内容,也就是在对比下面两个图片时,由于key=0,就会把相同复用,而不同的内容(也就是“张三-18”或者“老刘-30”)会重新渲染生成DOM,这样就会导致整个页面结构混乱了。

解决方案:使用数据库中唯一标识作为:key值,比如表中唯一ID、身份证号、手机号等等

注意:
注意点1:默认不写:key时,解析DOM会自动加上数组index
注意点2::key最好绑定数据唯一标识,身份证、手机号、库表id等,这样无论在数组什么位置插入,哪怕是数组开头或者数组结尾,都不会影响结构。
注意点3:虚拟DOM存在于内存中,而用户操作的页面标签属于真实DOM

11.使用表单提交发现的问题

详情请点击跳转上方导航知识点2.11

问题1:使用radio标签,想实现二选一?只需设置相同name属性值即可

问题2:使用checkbox标签,定义data属性值的默认值时,配置”input的value属性”和不配置”input的value属性”,效果完全不一样。

<input type="checkbox"/>
    1.没有配置input的value属性,那么收集的就是checked(勾选 or 未勾选,是布尔值)
    2.配置input的value属性:
            (1)v-model的初始值是非数组,那么收集的就是checked(勾选 or 未勾选,是布尔值)
            (2)v-model的初始值是数组,那么收集的的就是value组成的数组

问题3:针对radio或者checked等无法输入值的标签,建议一定要配置value属性值

12.使用条件渲染发现问题

详情请点击跳转上方导航知识点2.9

问题1:v-if可能无效

使用v-if和v-else-if和v-else时中间不可以中断,否则无效,比如:
在这里插入图片描述

问题2:使用标签给一块元素绑定条件渲染时可能报错

注意:标签中只可以使用v-if,不能使用v-show,否则报错

13.使用Vue.set()或者vm.$set()向响应式对象中添加一个property属性时发现的问题

详情请点击跳转上方导航知识点2.10.7

假设data属性长这样:想实现点击按钮,新增一个性别的属性,也就是在data属性中新增一个sex的属性值,如果直接使用Vue.set()或者vm.$set()就会报错,无法添加成功
原因:Vue.set()或者vm.$set()方法有局限性,不能给vue实例或者data的直接属性进行添加(也就是不能给data属性或者Vue原型上直接添加属性),有效只能作用于data下面的某个属性对象,举例就是再封装个user属性对象即可直接有效使用。
这是错误的格式:
new Vue({
	el:'#root',
	data:{
		name:'',
		address:''

Vue.set(this.data,'sex','男') 无效
------------------------------------------------------------------------------------------
正确的格式:
var student =  new Vue({
	el:'#root',
	data:{
                 user:{
		name:'',
		    address:''
}

Vue.set(this.user,'sex','男') 有效

14.使用父组件调用子组件方法,修改父组件属性时,发现问题

问题:子组件调用父组件方法时传参,父组件如何接收到参数值?

1)如果只传递一个参数,比如:this.$emit('update-count', "你是谁?"); 
那么子组件标签形参可不带参数或者形参使用$event
<child v-on:update-count="changeCount"></child> 
或者<child v-on:update-count="changeCount($event)"></child>
那么父组件(vue实例)方法中通过value即可接收参数比如:  changeCount:function(value)

2)如果传递多个参数,比如: this.$emit('update-count', "ldz",29);,
那么子组件标签形参请使用arguments
<child v-on:update-count="changeCount(arguments)"></child>
那么父组件(vue实例)方法中通过value[index]即可接收参数,比如:
changeCount:function(value){
console.log("@" + value[0]);
console.log("@" + value[1]);
子组件
<template>
  <div>
    <button @click="student1Send()">点击学生1组件发送消息</button>
  </div>
</template>

<script>
export default {
  name: "B",
  data() {
    return {
      ipt:"我是学生1组件发过来数据",
      ipt2:"我是你爸爸"
    }
  },
  methods: {
    student1Send() {
      this.$emit('student1Send', this.ipt, this.ipt2)
    },
  }
}
</script>
<style scoped>
</style>
------------------------------------------------------------------------------------------
父组件
<template>
  <div id="app">
    <B ref="childrenB" @student1Send="getB(arguments)"></B>
    <p>接收的b数据:{{strb}}</p>
    <p>接收的b数据:{{strb2}}</p>
  </div>

</template>

<script>
import B from "./B.vue"

export default {
  name: "A",
  data() {
    return {
      strb:"",
      strb2:"",
    }
  },
  components: {
    B
  },
  methods: {
    getB(args) {
      console.log(args);
      this.strb = args[0];
      this.strb2 = args[1];
      console.log(this.$refs.childrenB)
    }
  },


在这里插入图片描述

在这里插入图片描述

15.有2种方式都可以实现父组件接收子组件传递的多个参数

方式1:调用子标签不写括号和形参,但方法形参使用…

子组件
this.$emit('student1Send', this.ipt, this.ipt2)
------------------------------------------------------------------------------------------
父组件
<B ref="childrenB" @student1Send="getB"></B>

methods: {
    getB(...args) {
      this.strb = args[0];
      this.strb2 = args[1];
    }

方式2:调用子标签写括号和形参arguments,那么方法形参不使用…

子组件
this.$emit('student1Send', this.ipt, this.ipt2)
------------------------------------------------------------------------------------------
父组件
<B ref="childrenB" @student1Send="getB(arguments)"></B>
methods: {
    getB(args) {
      this.strb = args[0];
      this.strb2 = args[1];
    }

16.父组件引用子组件,如何获取子组件的vue实例?

答案:可以通过ref属性获取,通过给子组件标签定义ref名字,在父组件方法中使用this.$refs.ref名字即可获取,比如父组件引入B子组件

<B ref=“childrenB” @student1Send=“getB(arguments)”>
this.$refs.childrenB.student1Send == B子组件vue实例

17.v-on和$on区别?

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

18.组件内样式标签使用lang=”less”导致启动报错

详情请看上方知识点导航3.19

原因:报错如图1告诉你缺少less-loader,而当你直接使用安装命令:npm i less-load,安装less-loader时也会报错如图2,该错误原因是版本不匹配,我们去node_modules下查找webpack版本如图3,项目中脚手架依托的webpack版本是4.46,而直接使用命令安装less-loader安装的是最新版10版本,而10版本完全是为了迎合webpack5版本,所以就导致版本不兼容。
解决方案:命令安装less-loader7版本即可(命令为:npm i less-load@7),因为less-loader8和9和10版本配套webpack5,而less-loader7版本配套咱们脚手架引入的webpack4.46版本

注意点1:使用命令可以查看webpack版本:npm view webpack version,如图4
注意点2:使用命令可以查看less-loader版本:npm view less-loaderversion,如图5
在这里插入图片描述

图1

在这里插入图片描述

图2

在这里插入图片描述

图3

在这里插入图片描述

图4

在这里插入图片描述

图5

19.同一组件中避免props中名字不要和data或者methods中重名

注意点1:同一组件中避免props中名字不要和data或者methods中重名,因为props优先级高于data和methods,代码如下,同时会报错报属性名已存在如图1

props:["add"]

methods: {
    //添加一个todo
    add(todoObj){
      this.todos.unshift(todoObj)
    }
  }

在这里插入图片描述

图1

20.父子组件通信使用props想实现点击checkbox修改勾选状态时发现问题

问题:子组件中如下代码都可以实现更改checkbox勾选状态,为啥不推荐使用方式2写法?

父组件中
data() {
      return {
        //由于todos是MyHeader组件和MyFooter组件都在使用,所以放在App中(状态提升)
        todos:[
          {id:'001',title:'抽烟',done:true},
          {id:'002',title:'喝酒',done:false},
          {id:'003',title:'开车',done:true}
        ]
      }
}
子组件中
props:['todo'],

方式1:
<input type="checkbox" :checked="todo.done" @change="handleCheck(todo.id)"/>

方式2:
<!-- 如下代码也能实现功能,但是不太推荐,因为有点违反原则,因为修改了props -->
<input type="checkbox" v-model="todo.done"/>

答案:咱们之前说过props中的属性不能修改,因为修改了会报错,那么方式2写法页面为啥没报错呢?因为传递过来的todo是个对象,vue默认只监听props中属性浅层次是否修改,即vue监听props,如果属性是字符串,修改值了直接报错如图2,如果属性是对象,那么只要地址不变哪怕内部属性值变了,vue也认为它没变。所以不要偷懒使用方式2写法,因为如果todo.done中属性done移出对象todo范围外的化直接报错,导致项目启动不了,所以最好不要偷懒。
在这里插入图片描述

图2

21.v-bind指令居然也可以传方法给子组件,但不推荐使用

因为v-bind指令传方法不正规,虽说不报错,但不严谨,不优雅,最好还是使用v-on+$emit方式实现父子组件方法调用。

22.“单文件组件”与“非单文件组件”区别?

在这里插入图片描述

23.vc和vm区别? vc≠vm

答案:
相同点:属性和方法99%相同
不同点:
1)vm可以绑定el决定为哪个容器服务,而vc不可以,vc只能被vm管理
2)vm的data可定义对象形式,可定义函数形式,而vc中data只能定义函数形式
在这里插入图片描述

24.问题:“组件实例对象”是啥呢?

“组件实例对象” =》 简称vc
答案:就是小型的vm

25.问题:为什么在table标签中直接使用自定义组件,无法正常显示?

原因:DOM解析时会解析到<table>标签的外部,table/ol/ul/select 这种html标签有特殊的结构要求,不能直接使用自定义标签。他们有自己的默认嵌套规则,比如:
table> tr> [th, td];
ol/ul > li;
select > option

26.问题:什么叫在使用字符串模板、x-template模板和.Vue组件时,不需要is进行转义?

答案:不需要转义如图1,需要转义如图2(详情请看知识点导航3.4.4)

<script type="text/x-template" id="template5">
    <table>
        <my-component1></my-component1>
    </table>
</script>
Vue.component('my-component2',{
    template:'#template2'
});
图1
<table>
       <tr is="my-component3">      
 </table>
<template id="template3">
    <ol>
        <li>a</li>
        <li>b</li>
    </ol>
</template>
Vue.component('my-component3',{
    template:'#template3'
});
图2

27.问题:在父组件App中使用$on的箭头函数中把子组件传递过来的值赋值给父组件属性,会导致父组件属性接收不到信息

失败图片

在这里插入图片描述

成功图片

在这里插入图片描述
答案:在父组件App中使用$on的普通函数this指代子组件的vc,而$on的箭头函数this指代父组件的vc,所以$on的普通函数的this.studentName = name就会赋值失败,正确写法就是上面说的,要么method定义赋值,$on中直接调用,要么$on中使用箭头函数去赋值

mounted() {
this.$refs.student.$on('atguigu',function (name,...params) {
      console.log('App收到了学生名:',name,params)
      console.log("this:", this);  //使用自定义组件的配置项的普通函数中this指代子组件Student.vue的vc
      this.studentName = name
}) //绑定自定义事件
}
mounted() {
this.$refs.student.$on('atguigu',(name,...params) => {
      console.log('App收到了学生名:',name,params)
      console.log("this:", this); //使用自定义组件的配置项的箭头函数中this指代父组件App.vue的vc
      this.studentName = name
    }) //绑定自定义事件
}

28.问题:我在子组件Student 标签中使用了自定义事件,我想再绑定个原生事件,为啥原生事件失效了?

<Student ref="student" @click="show"/>  //错误写法

methods: {
show(){
		alert(123)
	}
}

答案:因为原生事件也使用@注解,子组件标签默认会把@标识的原生事件理解为是自定义事件,所以就失效了,解决办法是在@click后面加.native标识符,这样子组件就知道这个click方法是原生方法。

<Student ref="student" @click.native="show"/> //正确写法

再引出个思考点:为啥说子组件中根元素标签只能有一个,比如最外层只能有1个div标签,为啥能不能有2个?

答案:给子组件标签绑定【自定义事件/原生事件】,实际是给里面的整个标签绑定函数,如果你有2个div,它哪知道给谁,如果2个都给岂不乱套了,当然这只是其中一个理由,实际子组件根元素标签只让有一个元素还有好多原因,只不过我还没学到。

29.生命周期问题:钩子函数beforeCreate和created代表创建前和创建后,这个创建指的是谁?

答案:指的是“数据监测和数据代理”也就是data属性和属性的get()和set(),一定不是指代vue实例,千万别弄混。

30.生命周期问题:图中的判断元素“Has template option?”中的template 指的是?

在这里插入图片描述
图中的判断元素“Has template option?”中的template 指的是图1元素(也就是data中的template属性),而不是图2元素(图2中的template 是标签)
在这里插入图片描述

图1

在这里插入图片描述

图2

31.生命周期问题:图3中的outerHtml指的是图4中绿色框内容,与其对立的interHtml指的才是红色框内容

在这里插入图片描述

图3

在这里插入图片描述

图4

32.生命周期问题:图5步骤会把之前生成内存中的虚拟DOM转成真实DOM,转成之后会往“vm.$el”上存了一份,问:为什么要保存一份?

答案:可以用在很多地方,比如vue提供了虚拟DOM和真实DOM比较算法,既然有比较那么去哪里拿虚拟DOM呢?诶,“vm.$el”上面就保存了可以直接使用。
在这里插入图片描述

图5

33.生命周期问题:图6中红框如何理解?,为啥最终都不奏效,注意这个“最终”字眼

原因:钩子函数beforeMount中无论做了什么操作都没用,因为执行到图7红框操作部分,只会把内存中虚拟DOM转为真实DOM插入页面中,会进行模板渲染覆盖,这样就会导致钩子函数beforeMount中无论做了什么操作都没用了。
在这里插入图片描述

图6

在这里插入图片描述

图7

34.生命周期问题:在div中定义模板和在data中定义模板,页面长得不一样。

举例说明:div中定义模板如图8,页面效果如图9,页面会发现root容器还在,而如果data中定义模板如图10,页面效果如图11,页面会发现root容器消失了。总结大白话就是说,如图12使用data中定义模板方式,会造成绿色框会替换掉红色框内容,就会造成原来红色框定义的x属性等等都消失了,都白写了。

在这里插入图片描述

图8

在这里插入图片描述

图9

在这里插入图片描述

图10

在这里插入图片描述

图11

在这里插入图片描述

图12

35.生命周期问题:面试官可能会问,在哪个钩子中页面和数据尚未保持同步啊?所谓数据未同步指的是data数据值已经改了,而页面却没进行动态更新。如图13

答案:就是beforeUpdate钩子函数中
在这里插入图片描述

图13

36.生命周期问题:官网红框容易造成歧义

在这里插入图片描述

图14

37.生命周期问题:一般不会在钩子函数beforeDestroy操作数据,因为即便操作数据,也不会再触发更新流程了。大白话说就是哪怕钩子函数beforeDestroy中执行修改属性操作了,值也改变了,但是页面也不会触发更新操作了,即值改了 但页面不更新了。

38.标签属性scoped问题:我有两个子组件,拥有重复名称但样式不同的class,那么父组件在加载两个子组件时以谁的样式为准呢?

答案:如图1以import的加载顺序为准,后加载会覆盖同名先加载的样式,而不以使用组件标签顺序为准,那么如何解决该问题呢?答案是在组件样式标签中配置scoped,比如如图2,它是怎么办到的呢,其实啊配置scoped后相当于动态给<template>标签内的<div>标签中加了个特殊属性,而且后面的值是每次运行随机生成的,通过”该特殊属性值“配合”控制标签属性选择器“一同控制样式,具体如图3
在这里插入图片描述

图1

在这里插入图片描述

图2

在这里插入图片描述

图3

39.全局事件总线问题:“全局事件总线”需要哪些特点?

答案:
1)被所有组件(vc、vm)能够看得见
2)能够调用$on、$emit、$off

40.全局事件总线问题:Vue原型对象上面的所有属性和方法是给谁用的?

答案:是给所有的vm和vc使用的

41.全局事件总线问题:为什么定义“全局事件总线”要放在main.js文件中?

答案:因为哪里引入Vue,哪里才会去定义“全局事件总线”

42.全局事件总线问题:为什么定义“全局事件总线”要放在beforeCreate的钩子函数中?

答案:原因1,beforeCreate钩子函数里this指代new出来的vm,原因2,在beforeCreate钩子函数里模板还没解析,数据监测和数据代理也还没完成呢。也就是说借助这个beforeCreate钩子函数你把想做的事儿做好了,原型上该放的放好了,随后模板开始解析,等组件执行的时候你该放的都放好了,后续才做都不会产生影响。

43.全局事件总线问题:如何避免在使用“全局事件总线”时自定义函数名重名使用问题?比如组件1使用自定义函数名叫demo,那组件2不全文搜索也使用了自定义函数名也叫demo,这就混了

答案:真实项目中src目录下创建一个config文件夹,里面创建个constants常量文件,里面用来定义要使用的自定义函数名,方便别人查看并避免重名问题。

44.全局事件总线问题:为什么要在组件销毁之前,把“全局事件总线”中定义的自定义事件函数解绑?那“知识点3.13自定义事件”中咋没说解绑的事儿呢?

答案:“知识点3.13自定义事件”中组件销毁了== vc销毁了,vc销毁了自定义事件也就销毁了,而“全局事件总线”中定义的自定义函数是一直存在的,哪怕使用组件销毁了,但是Vue实力定义的“全局事件总线”中还是会存在自定义事件,所以需要在组件销毁之前进行解绑。

45.全局事件总线销毁“全局事件总线”中定义的自定义事件请放在beforeDestroy()钩子中

46.全局事件总线子组件中使用“全局事件总线”时this. b u s . bus. bus.on()中回调配置要使用箭头函数,不要使用普通函数,箭头函数中this才指代vc,而普通函数中this指代vue实例,因为最终要在school组件上接收平行组件发过来的消息,所以要使用vc,而不是要使用vue实例,因为vue实例不是我们最终要的。

47.消息订阅与发布问题:“全局事件总线”和“消息订阅与发布”都可以实现任意组件间通信,那用哪个好?

答案:推荐使用“全局事件总线”,因为它是vue提供的,完全使用的vue技术,而“消息订阅与发布”则是第三方。

48.vue封装的过度与动画问题:想实现多个元素产生相同过度效果时,错误代码如下,运行发生了报错如图

<transition>
    <h1 v-show="!isShow" key="1">你好啊!</h1>
<h1 v-show="isShow" key="2">尚硅谷!</h1>
</transition-group>

在这里插入图片描述
答案:报错说明<transition>标签只能用于一个元素,如果想实现多个元素相同效果,请使用<transition-group>标签。

49.vue封装的过度与动画问题:如果改成使用<transition-group>标签后,运行还是报错了,感觉更严重了,下面两个过度一个都没显示,且还报错了。

答案:正确写法就是必须指定key值,这块在讲解v-for的时候着重强调要定义key的属性。
在这里插入图片描述

50.vue.js与vue.runtime.js区别?

在这里插入图片描述

51.问题:图1默认引入vue文件究竟引入了哪个?

答案:如图2中第6行指定了默认引入的vue是哪个版本的,默认引入的是运行版vue.js(也就是残缺版vue.js,它没有模板解析器)
在这里插入图片描述

图1

在这里插入图片描述

图2

52.问题:为啥vue提供了那么多版本?直接只提供一个最完整版的vue.js不好吗?

答案:vue.js最全版包括“核心功能+模板解析器”,而运行版不包括“模板解析器”,区别点在项目开发好用webpack打包成浏览器认识的东西后“模板解析器”就没用了,但是它还占内存大小,为了简洁提供了不同精简版的vue.js文件

53.问题:import导入默认vue.js,如图3实例化vue时如果使用template属性会报错,报错如图4。

解决方案有2种,方案1:引入完整版vue.js,方案2:在继续使用运行版vue.js的基础上,使用render函数也可以解决问题。
在这里插入图片描述

图3

在这里插入图片描述

图4

54.问题:既然vue实例化无法直接使用template属性,但vue模板中却可以直接使用<template>标签?

答案:vue专门为<template>标签找到了一个库去解析,如图5,其中21行专门用来解析vue组件中的标签,而js中的template属性它不管。
在这里插入图片描述

55.问题:简写版 render: h => h(App),指的是啥?

完整版如图6,其中createElement其实是一个函数,因为参数都在组件中,所以只需绑定app即可,即:简写版就变成了 render: h => h(App)
在这里插入图片描述

图6

56.修改默认配置问题:main.js是入口,为啥它是入口,我改名叫peiqi.js为入口是否可以?

答案:Vue 脚手架隐藏了所有 webpack 相关的配置,若想查看具体的 webpakc 配置, 请执行:vue inspect > output.js,如图红框指定的就是主入口文件,但是你想直接在output.js文件修改主入口名字为peiqi.js无效
在这里插入图片描述

57.修改默认配置问题:默认哪些文件可以改名字会生效,哪些不能改名字?

答案:如图,5个红框名字不能修改,其他的都可以修改
在这里插入图片描述

58.修改默认配置问题:如何想实现修改入口名称或者关闭ESLint格式校验?

使用图2中vue.config.js可以对脚手架进行个性化定制,详情见图1:https://cli.vuejs.org/zh

在这里插入图片描述

图1

在这里插入图片描述

59.问题:起名不合法,叫Header.vue在引入时第一下就报错了?

在这里插入图片描述
原因:html5的关键词就有header、footer等等之类的
解决方案:避免起关键字名字,组件名可以是 多单词组成,可以由模块或者结构名命名。

60.问题:如何让checkbox框勾选不勾选?

解决方案:标签添加<input type=“checkbox” checked=’true’> 或者<input type=“checkbox” checked=’false’>

61.问题:输入框如可获取输入值?

解决方案:两种方式,
方式1:内部方法形参为event,通过event.target.value获取值

methods: {
    add(event){
      console.log(event.target.value)
}

方式2:使用v-model标签

62.问题:单机版id如何创建?

解决方案:可以使用迷你版uuid的技术,它叫nanoid
安装使用步骤:

  • 第1步:npm i nanoid
  • 第2步:import引入nanoid,由于nanoid使用分别暴露,所以写法必须这样import {nanoid} from ‘nanoid’,且nanoid是一个函数,直接使用即可,比如const todoObj = {id:nanoid(),title:this.title,done:false}

63.问题:title是字符串,为啥空字符串取反可以为true?

答案:因为在js上,!null // true !’’ // true

64.问题:父组件通过v-bind标签向子组件传递方法时不要带参数,只传方法名即可

错误方式: :checkTodo=“checkTodo(value)”,
正确方式: :checkTodo=“checkTodo”,不然会报错如图3,因为你只想实现父组件中把方法传递给子组件使用,子组件使用时再把参数传进去

父组件中

<MyList :todos="todos" :checkTodo="checkTodo"></MyList>

methods: {
//勾选or取消勾选一个todo
    checkTodo(id){
      this.todos.forEach((todo)=>{
        if(todo.id === id) todo.done = !todo.done
      })
    },
}

子组件中

<input type="checkbox" :checked="todoObj.done" @change="handleCheck(todoObj.id)"/>

props:["todoObj", "checkTodo"]

methods:{
    //勾选or取消勾选
    handleCheck(id){
      //通知App组件将对应的todo对象的done值取反
      this.checkTodo(id)
    }
}

在这里插入图片描述

图7
;