目录
面试题:react、vue中的key有什么作用?(key的内部原理)
1.虚拟DOM中key的作用:
key是虚拟DOM对象的表示,当数据发生变化时,Vue会根据新数据生成新的虚拟DOM,随后Vue进行新虚拟DOM与旧虚拟DOM的差异比较,比较规则如下
2.对比规则:
1)旧虚拟DOM中找到了与新虚拟DOM相同的key:
2)旧虚拟DOM中没找到与虚拟DOM相同的key
3.用index作为key可能会引发的问题
4.开发中如何选择key?
当watch属性和计算属性都能使用时,优先使用计算属性
- html>
- <html lang="en">
- <head>
- <meta charset="UTF-8" />
- <meta http-equiv="X-UA-Compatible" content="IE=edge" />
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <title>Documenttitle>
- <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js">script>
- head>
- <body>
- <div id="root">
-
- <h2>人员列表h2>
- <input type="text" placeholder="请输入名字" v-model="keyWord">
- <ul>
- <li v-for="(p,index) of fillPersons" :key="index">
- {{p.name}}---{{p.age}}-----{{p.sex}}
- li>
- ul>
- ul>
- div>
- body>
- <script>
- Vue.config.productionTip = false; //阻止vue在启动时生成生产提示
- // 用watch实现
- // #region
- /* new Vue({
- el: "#root",
- data: {
- keyWord:'',
- persons: [
- { id: "001", name: "马冬梅", age: 19,sex:'女' },
- { id: "002", name: "周冬雨", age: 20,sex:'女' },
- { id: "003", name: "周杰伦", age: 21,sex:'男' },
- { id: "004", name: "周兆伦", age: 22,sex:'男' },
- ],
- fillPersons:[]
- },
- watch:{
- // console.log('keyWord被改了',val);
- // this.fillPersons=this.persons.filter((p)=>{
- // return p.name.indexOf(val)!==-1
- // })
- immediate:true,
- handler(val){
- this.fillPersons=this.persons.filter((p)=>{
- return p.name.indexOf(val)!==-1
- })
- }
- }
- }) */
-
- new Vue({
- el:'#root',
- data: {
- keyWord:'',
- persons: [
- { id: "001", name: "马冬梅", age: 19,sex:'女' },
- { id: "002", name: "周冬雨", age: 20,sex:'女' },
- { id: "003", name: "周杰伦", age: 21,sex:'男' },
- { id: "004", name: "周兆伦", age: 22,sex:'男' },
- ]
- },
- computed:{
- fillPersons(){
- return this.persons.filter((p)=>{
- return p.name.indexOf(this.keyWord)!==-1
- })
- }
- }
-
- })
- script>
- html>
- html>
- <html lang="en">
- <head>
- <meta charset="UTF-8" />
- <meta http-equiv="X-UA-Compatible" content="IE=edge" />
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <title>Documenttitle>
- <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js">script>
- head>
- <body>
- <div id="root">
-
- <h2>人员列表h2>
- <input type="text" placeholder="请输入名字" v-model="keyWord">
- <button @click="sortType=2">年龄升序button>
- <button @click="sortType=1">年龄降序button>
- <button @click="sortType=0">原顺序button>
- <ul>
- <li v-for="(p,index) of fillPersons" :key="index">
- {{p.name}}---{{p.age}}-----{{p.sex}}
- li>
- ul>
- ul>
- div>
- body>
- <script>
- Vue.config.productionTip = false; //阻止vue在启动时生成生产提示
-
- new Vue({
- el:'#root',
- data: {
- keyWord:'',
- sortType:0,//0原顺序 1降序 2升序
- 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:'男' },
- ]
- },
- computed:{
- fillPersons(){
- const arr=this.persons.filter((p)=>{
- return p.name.indexOf(this.keyWord)!==-1
- })
- // 判断是否需要排序
- if(this.sortType){
- arr.sort((p1,p2)=>{
- return this.sortType===1?p2.age-p1.age:p1.age-p2.age
- })
- }
- return arr
- }
- }
-
- })
- /* let arr=[1,3,2,4,5,6]
- arr.sort((a,b)=>{
- return b-a
- })
- console.log(arr); */
- script>
- html>
- html>
- <html lang="en">
- <head>
- <meta charset="UTF-8" />
- <meta http-equiv="X-UA-Compatible" content="IE=edge" />
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <title>Documenttitle>
- <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js">script>
- head>
- <body>
- <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>
- ul>
- div>
- body>
- <script>
- Vue.config.productionTip = false; //阻止vue在启动时生成生产提示
-
- 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]={id:'001',name:'马老师',age:50,sex:'男'}
- }
- }
- })
- script>
- html>
参数
用法:
向响应式对象添加一个property,并确保这个property同样是响应式的,且触发视图更新。它必须用于响应式对象上添加新property,因为Vue无法探测普通的新增property。
注意:对象不能是Vue实例,或者Vue实例的根数据对象。
- html>
- <html lang="en">
- <head>
- <meta charset="UTF-8" />
- <meta http-equiv="X-UA-Compatible" content="IE=edge" />
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <title>Documenttitle>
- <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js">script>
- head>
- <body>
- <div id="root">
- <h1>学校信息h1>
- <h2>学校名称:{{school.name}}h2>
- <h2>学校地址:{{school.address}}h2>
- <h2>校长是:{{school.leader}}h2>
- <hr />
- <h1>学生信息h1>
- <button @click="addSex">添加一个性别属性,默认值是男button>
- <h2>姓名:{{student.name}}h2>
- <h2 v-if="student.sex">性别:{{student.sex}}h2>
- <h2>年龄:真实{{student.age.rAge}},对外{{student.age.sAge}}h2>
- <h2>朋友们h2>
- <ul>
- <li v-for="(f,index) in student.friends" :key="index">
- {{f.name}}----{{f.age}}
- li>
- ul>
- div>
- body>
-
- <script>
- Vue.config.productionTip = false; //阻止vue在启动时生成生产提示
-
- const vm = new Vue({
- el: "#root",
- data: {
- school: {
- name: "guigu",
- address: "北京",
- },
- student: {
- name: "学生",
- age: {
- rAge: 40,
- sAge: 29,
- },
- friends: [
- { name: "朋友a", age: 18 },
- { name: "朋友b", age: 19 },
- ],
-
- },
- },
- methods: {
- addSex() {
- // Vue.set(this.student, 'sex', '男');
- this.$set(this.student,'sex','男')
- },
- },
- });
- script>
- html>
- html>
- <html lang="en">
- <head>
- <meta charset="UTF-8" />
- <meta http-equiv="X-UA-Compatible" content="IE=edge" />
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <title>Documenttitle>
- <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js">script>
- head>
- <body>
- <div id="root">
- <h1>学校信息h1>
- <h2>学校名称:{{school.name}}h2>
- <h2>学校地址:{{school.address}}h2>
- <h2>校长是:{{school.leader}}h2>
- <hr />
- <h1>学生信息h1>
- <button @click="addSex">添加一个性别属性,默认值是男button>
- <h2>姓名:{{student.name}}h2>
- <h2 v-if="student.sex">性别:{{student.sex}}h2>
- <h2>年龄:真实{{student.age.rAge}},对外{{student.age.sAge}}h2>
- <h2>爱好h2>
- <ul>
- <li v-for="(h,index) in student.hobby" :key="index">
- {{h}}
- li>
- ul>
- <h2>朋友们h2>
- <ul>
- <li v-for="(f,index) in student.friends" :key="index">
- {{f.name}}----{{f.age}}
- li>
- ul>
- div>
- body>
-
- <script>
- Vue.config.productionTip = false; //阻止vue在启动时生成生产提示
-
- const vm = new Vue({
- el: "#root",
- data: {
- school: {
- name: "guigu",
- address: "北京",
- },
- student: {
- name: "学生",
- age: {
- rAge: 40,
- sAge: 29,
- },
- hobby:['抽烟','喝酒','烫头'],
- friends: [
- { name: "朋友a", age: 18 },
- { name: "朋友b", age: 19 },
- ],
-
- },
- },
- methods: {
- addSex() {
- // Vue.set(this.student, 'sex', '男');
- this.$set(this.student,'sex','男')
- },
- },
- });
- script>
- html>
1.Vue会监视data中所有层次的数据
2.如何监测对象中的数据?
通过setter实现监视,且要在new Vue时就传入要监测的数据
3.如何监测数组中的数据?
通过包裹数组更新元素的方法实现,本质就是做了两件事:
4.在Vue修改数组中的某个元素一定要用如下方法:
特别注意:Vue.set()和vm.$set()不能给vm或vm的根数据对象添加属性
- html>
- <html lang="en">
- <head>
- <meta charset="UTF-8" />
- <meta http-equiv="X-UA-Compatible" content="IE=edge" />
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <title>Documenttitle>
- <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js">script>
- head>
- <body>
- <div id="root">
- <h1>学生信息h1>
-
- <button @click="student.age++">年龄+1岁button><br>
- <button @click="addSex">添加一个性别属性,默认值是男button><br>
- <button @click="student.sex='未知'">修改性别button><br>
- <button @click="addFriend">在列表首位添加一个朋友button><br>
- <button @click="updateFirstFriendName">修改第一个朋友的名字为:张三button><br>
- <button @click="addHobby">添加一个爱好button><br>
- <button @click="updateHobby">修改第一个爱好button><br>
-
- <h2>学生姓名:{{student.name}}h3>
- <h2 v-if="student.sex">性别:{{student.sex}}h2>
- <h2>年龄:{{student.age}}h2>
- <h2>爱好h2>
- <ul>
- <li v-for="(h,index) in student.hobby" :key="index">{{h}}li>
- ul>
- <h2>朋友们h2>
- <ul>
- <li v-for="(f,index) in student.friends" :key="index">
- {{f.name}}----{{f.age}}
- li>
- ul>
- div>
- body>
- <script>
- Vue.config.productionTip = false; //阻止vue在启动时生成生产提示
- new Vue({
- el: "#root",
- data: {
- student: {
- name: "tom",
- age: 18,
- hobby: ["抽烟", "喝酒", "烫头"],
- friends: [
- { name: "a", age: 35 },
- { name: "b", age: 25 },
- ],
- },
- },
- methods: {
- addSex() {
- // Vue.set(this.student,'sex','男')
- this.$set(this.student, "sex", "男");
- },
- addFriend(){
- this.student.friends.unshift({name:'c',age:70})
- },
- updateFirstFriendName(){
- this.student.friends[0].name='张三'
- },
- addHobby(){
- this.student.hobby.push('学习')
- },
- updateHobby(){
- // this.student.hobby.splice(0,1,'看书')
- // Vue.set(this.student.hobby,0,'看书')
- this.$set(this.student.hobby,0,'看书')
-
- }
- },
- });
- script>
- html>