欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

vue组件化开发:调试工具、组件通信、插槽

程序员文章站 2022-06-03 23:21:53
...

Vue调试工具

调试工具安装

官方文档:https://github.com/vuejs/vue-devtools

  • 克隆仓库
  • 安装依赖包
  • 构建
  • 打开Chrome扩展页面,选中开发者模式
  • 加载已解压的扩展,选择:shells / chrome

vue组件化开发

组件化开发核心思想:把不同的功能封装到不同的组件中,然后组件通过组合的方式形成完整意义上的应用。

组件注册

注意事项

  • 组件参数的data值必须是函数,return一个对象。

    原因:使用函数会形成一个闭包的环境,这样就保证每一个组件都拥有一份独立的数据。

    注意:new Vue实例的时候,data是一个对象。
    var vm = new Vue({
          el: '#app',
          data: {}
    });
    
  • 组件模板必须是单个根元素,即只能有一个父元素多个子元素:div>div 这样写会报错:

    template: `<div></div> <div></div>`
    
  • 组件模板的内容可以是模板字符串,提高代码的可读性! template: 模板内容

  • 组件命名方式

    如果使用驼峰式命名组件,那么在使用组件的时候,只能在字符串模板template中用驼峰的方式使用组件,

    例如:代码示例中 <HelloWorld></HelloWorld>

    但是在普通的标签模板(父组件里面)中,必须使用字母小写且短横线的方式使用组件

    所有的html标签都是小写形式!例如:代码示例中 <hello-world></hello-world>

    • 短横线方式
    Vue.component('button-counter', {})
    
    • 驼峰方式
     Vue.component('HelloWorld', {})
    

代码示例如下:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>

<body>
  <div id="app">
    <button-counter></button-counter>
    <hello-world></hello-world>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <!-- 
     组件注册注意事项
        如果使用驼峰式命名组件,那么在使用组件的时候,
        只能在字符串模板template中用驼峰的方式使用组件,但是
        在普通的标签模板(父组件里面)中,必须使用字母小写且短横线的方式使用组件

        所有的html标签都是小写形式!
    -->
  <script type="text/javascript">
    // 注册全局子组件 HelloWorld
    Vue.component('HelloWorld', {
      data: function () {
        return {
          msg: 'HelloWorld1'
        }
      },
      template: '<div>{{msg}}</div>'
    });

    // 注册全局子组件 button-counter
    Vue.component('button-counter', {
      data: function () {
        return {
          count: 0
        }
      },
      template: `
        <div>
          <button @click="handle">点击了{{count}}次</button>
          <button>测试123</button>
          <HelloWorld></HelloWorld>
        </div>
      `,
      methods: {
        handle: function () {
          this.count += 2;
        }
      }
    });

    // 注册父组件
    var vm = new Vue({
      el: '#app',
      data: {

      }
    });
  </script>
</body>

</html>

全局组件注册语法

Vue.component('组件名称', {
    data: 组件数据,
    template: 组件模板内容
})

完整代码示例:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>

<body>
  <div id="app">
    <!-- 
          组件是可以重用的:赋值多个组件标签即可!
          因为子组件data是一个函数返回的是一个对象,每个组件都拥有独立的数据
         -->
    <span>点击了{{count}}次</span>
    <button-counter></button-counter>
    <button-counter></button-counter>
    <button-counter></button-counter>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <!-- 
      功能:计算点击了多少次
     -->
  <script type="text/javascript">
    // 注册子组件
    Vue.component('button-counter', {
      data: function () {
        return {
          count: 0
        }
      },
      template: '<button @click="handle">点击了{{count}}次</button>',
      methods: {
        handle: function () {
          // 每次点击增加2个数
          // count必须通过this调用
          this.count += 2;
        }
      }
    })
    var vm = new Vue({
      el: '#app',
      data: {

      }
    });
  </script>
</body>

</html>

局部组件注册

代码示例如下:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>局部组件用法</title>
</head>

<body>
  <div id="app">
    <hello-world></hello-world>
    <hello-tom></hello-tom>
    <hello-jerry></hello-jerry>
    <test-com></test-com>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <!-- 
      局部组件注册
        局部组件只能在注册他的父组件中使用
        下面代码,会报错:
         template: '<div>Test<hello-world></hello-world></div>'
      
        子组件:显示的内容由子组件data的return值决定
     -->
  <script type="text/javascript">
    // 注册全局子组件 test-com
    Vue.component('test-com', {
      template: '<div>Test<hello-world></hello-world></div>'
    });
    // 注册局部子组件 HelloWorld
    var HelloWorld = {
      data: function () {
        return {
          msg: 'HelloWorld'
        }
      },
      template: '<div>{{msg}}</div>'
    };
    // 注册局部子组件 HelloTom
    var HelloTom = {
      data: function () {
        return {
          msg: 'HelloTom'
        }
      },
      template: '<div>{{msg}}</div>'
    };
    // 注册局部子组件 HelloJerry
    var HelloJerry = {
      data: function () {
        return {
          msg: 'HelloJerry'
        }
      },
      template: '<div>{{msg}}</div>'
    };

    // 注册父组件 
    // 在父组件中使用components属性,注册局部组件
    var vm = new Vue({
      el: '#app',
      data: {

      },
      // 左边:组件的名称
      // 右边:组件的内容,可以抽取到一个对象当中,对象里面包含的信息:data、template、methods等
      components: {
        'hello-world': HelloWorld,
        'hello-tom': HelloTom,
        'hello-jerry': HelloJerry
      }
    });
  </script>
</body>

</html>

组件间数据交互

父组件向子组件传值

  • 父组件通过属性方式向子组件传值
  • 子组件通过props接收
  • 通过子组件template,渲染到页面上
父组件通过属性的方式传值给子组件,两种形式
  形式1:间接传值 
  在父组件data对象中首先把内容传递给 ptitle;然后再将ptitle传递给title,
  子组件通过props接收数据,最后 渲染页面
  在父组件data:{ ptitle: '动态绑定属性1' }
  <menu-item :title='ptitle'></menu-item>
  props: ['title', 'content'],
  template: '<div>{{title}}</div>'

形式2:直接传值  
  直接将内容传递给 content,子组件通过props接收数据,最后渲染页面
  <menu-item  content='hello'></menu-item>
  props接收数据  props: ['content'] 
  template: '<div>{{content}}</div>'

基本代码示例:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>

<body>
  <div id="app">
    <div>{{pmsg}}</div>
    <menu-item title='来自父组件的值'></menu-item>
    <menu-item :title='ptitle' content='hello'></menu-item>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>

  <script type="text/javascript">
    // 定义全局子组件
    Vue.component('menu-item', {
      props: ['title', 'content'],
      data: function () {
        return {
          msg: '子组件本身的数据'
        }
      },
      template: '<div>{{msg + "----" + title + "-----" + content}}</div>'
    });
    // 定义父组件
    var vm = new Vue({
      el: '#app',
      data: {
        pmsg: '父组件中内容',
        ptitle: '动态绑定属性1'
      }
    });
  </script>
</body>

</html>

父组件向子组件传值-props属性名规则:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>props属性名规则</title>
</head>

<body>
  <div id="app">
    <div>{{pmsg}}</div>
    <menu-item :menu-title='ptitle'></menu-item>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <!-- 
      父组件向子组件传值-props属性名规则:
      1.在props中使用驼峰形式,模板中需要使用短横线的形式
        因为DOM元素的组件,不区分大小写!
        父组件向子组件传值: <menu-item :menu-title='ptitle'></menu-item>  必须使用短横线的形式
        子组件负责接收: props: ['menuTitle'] 

      2.字符串形式的模板中没有这个限制
            template: '<div>{{menuTitle}}<third-com testTile="hello"></third-com></div>'
     -->
  <script type="text/javascript">
    Vue.component('third-com', {
      props: ['testTile'],
      template: '<div>{{testTile}}</div>'
    });
    Vue.component('menu-item', {
      props: ['menuTitle'],
      template: '<div>{{menuTitle}}<third-com testTile="hello"></third-com></div>'
    });
    var vm = new Vue({
      el: '#app',
      data: {
        pmsg: '父组件中内容',
        ptitle: '动态绑定属性'
      }
    });
  </script>
</body>

</html>

父组件向子组件传值-props属性值类型

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>

<body>
  <div id="app">
    <div>{{pmsg}}</div>
    <menu-item :pstr='pstr' :pnum='12' pboo='true' :parr='parr' :pobj='pobj'></menu-item>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <!-- 
     父组件向子组件传值-props属性值类型
     父组件通过属性方式向子组件传值
     子组件通过props接收
     通过子组件template,渲染到页面上

     加冒号,写什么类型就是什么类型
     不加冒号,统一是字符串
   -->
  <script type="text/javascript">
    Vue.component('menu-item', {
      props: ['pstr', 'pnum', 'pboo', 'parr', 'pobj'],
      template: `
        <div>
          <div>{{pstr}}</div>
          <div>{{12 + pnum}}</div>
          <div>{{typeof pboo}}</div>
          <ul>
            <li :key='index' v-for='(item,index) in parr'>{{item}}</li>
          </ul>
            <span>{{pobj.name}}</span>
            <span>{{pobj.age}}</span>
          </div>
        </div>
      `
    });
    var vm = new Vue({
      el: '#app',
      data: {
        pmsg: '父组件中内容',
        pstr: 'hello',
        parr: ['apple', 'orange', 'banana'],
        pobj: {
          name: 'lisi',
          age: 12
        }
      }
    });
  </script>
</body>

</html>

子组件向父组件传值

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>

<body>
  <div id="app">
    <div :style='{fontSize: fontSize + "px"}'>{{pmsg}}</div>
    <menu-item :parr='parr' @enlarge-text='handle'></menu-item>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <!-- 
    子组件向父组件传值-基本用法
      props传递数据原则:单向数据流

    功能:点击按钮增大字体!
   -->
  <script type="text/javascript">
    Vue.component('menu-item', {
      props: ['parr'],
      template: `
        <div>
          <ul>
            <li :key='index' v-for='(item,index) in parr'>{{item}}</li>
          </ul>
          <button @click='$emit("enlarge-text")'>扩大父组件中字体大小</button>
        </div>
      `
    });
    var vm = new Vue({
      el: '#app',
      data: {
        pmsg: '父组件中内容',
        parr: ['apple', 'orange', 'banana'],
        fontSize: 10
      },
      methods: {
        handle: function () {
          // 扩大字体大小
          this.fontSize += 5;
        }
      }
    });
  </script>
</body>

</html>

子组件向父组件传值-携带参数

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>

<body>
  <div id="app">
    <div :style='{fontSize: fontSize + "px"}'>{{pmsg}}</div>
    <menu-item :parr='parr' @enlarge-text='handle($event)'></menu-item>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <!-- 
        子组件向父组件传值-携带参数
        父组件用$event接收,然后通过事件将参数传递给函数handle使用
        handle:function(val){} ; val接收传递的参数
    -->
  <script type="text/javascript">
    Vue.component('menu-item', {
      props: ['parr'],
      template: `
        <div>
          <ul>
            <li :key='index' v-for='(item,index) in parr'>{{item}}</li>
          </ul>
          <button @click='$emit("enlarge-text", 5)'>扩大父组件中字体大小</button>
          <button @click='$emit("enlarge-text", 10)'>扩大父组件中字体大小</button>
        </div>
      `
    });
    var vm = new Vue({
      el: '#app',
      data: {
        pmsg: '父组件中内容',
        parr: ['apple', 'orange', 'banana'],
        fontSize: 10
      },
      methods: {
        handle: function (val) {
          // 扩大字体大小
          this.fontSize += val;
        }
      }
    });
  </script>
</body>

</html>

兄弟之间通信

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>

<body>
  <div id="app">
    <div>父组件</div>
    <div>
      <button @click='handle'>销毁事件</button>
    </div>
    <test-tom></test-tom>
    <test-jerry></test-jerry>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <!-- 
        兄弟组件之间数据传递:
        定义一个事件中心:
        1. 在兄弟1的methods方法中,向外触发事件且传递参数。
           然后在兄弟2的mounted方法中监听事件,接收参数。
    -->
  <script type="text/javascript">
    // 提供事件中心管理组件之间的通信:产生Vue实例
    var hub = new Vue();
    // 定义子组件:test-tom  加2
    Vue.component('test-tom', {
      data: function () {
        return {
          num: 0
        }
      },
      template: `
        <div>
          <div>TOM:{{num}}</div>
          <div>
            <button @click='handle'>点击</button>
          </div>
        </div>
      `,
      methods: {
        handle: function () {
          hub.$emit('jerry-event', 2);
        }
      },
      mounted: function () {
        // 在第二个test-jerry子组件的methods方法中:向外触发事件,携带参数1
        // 在第一个test-tom子组件的mounted方法中:监听事件
        // 接收参数val = 1
        hub.$on('tom-event', (val) => {
          this.num += val;
        });
      }
    });
    // 定义子组件:test-jerry
    Vue.component('test-jerry', {
      data: function () {
        return {
          num: 0
        }
      },
      template: `
        <div>
          <div>JERRY:{{num}}</div>
          <div>
            <button @click='handle'>点击</button>
          </div>
        </div>
      `,
      methods: {
        handle: function () {
          // 触发兄弟组件的事件
          hub.$emit('tom-event', 1);
        }
      },
      mounted: function () {
        // 在第一个test-tom子组件的methods方法中:向外触发事件,携带参数2
        // 在第二个test-jerry子组件的mounted方法中:监听事件
        // 接收参数val = 2

        hub.$on('jerry-event', (val) => {
          this.num += val;
        });
      }
    });
    // 父组件
    var vm = new Vue({
      el: '#app',
      data: {

      },
      methods: {
        handle: function () {
          hub.$off('tom-event');
          hub.$off('jerry-event');
        }
      }
    });
  </script>
</body>

</html>

插槽的用法

插槽基本用法

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>

<body>
  <div id="app">
    <alert-box>有bug发生</alert-box>
    <alert-box>有一个警告</alert-box>
    <alert-box></alert-box>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <!-- 
        组件插槽:父组件向子组件传递内容
        1.插槽的位置:在子组件template模板中
        2.插槽的内容在父组件标签的中间,父组件标签中的内容会传递给 <slot></slot>
        
          如果父组件标签中间没有内容 <alert-box></alert-box>
          slot 标签可以提供默认内容:<slot>默认内容</slot>
    -->
  <script type="text/javascript">
    Vue.component('alert-box', {
      template: `
                <div>
                    <strong>ERROR:</strong>
                    <slot>默认内容</slot>
                </div>`
    });
    var vm = new Vue({
      el: '#app',
      data: {

      }
    });
  </script>
</body>

</html>

具名插槽用法

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>

<body>
  <div id="app">
    <base-layout>
      <p slot='header'>标题信息</p>
      <p>主要内容1</p>
      <p>主要内容2</p>
      <p slot='footer'>底部信息信息</p>
    </base-layout>

    <base-layout>
      <template slot='header'>
        <p>标题信息1</p>
        <p>标题信息2</p>
      </template>

      <p>主要内容1</p>
      <p>主要内容2</p>

      <p slot='footer'>底部信息信息11111111111</p>
      <template slot='footer'>
        <p>底部信息信息1</p>
        <p>底部信息信息2</p>
      </template>


    </base-layout>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <!-- 
     具名插槽
     插槽中填充多个标签:可以用template包裹
     html标签只能使用一个具名插槽
    -->
  <script type="text/javascript">
    Vue.component('base-layout', {
      template: `
        <div>
          <header>
            <slot name='header'></slot>
          </header>
          <main>
            <slot></slot>
          </main>
          <footer>
            <slot name='footer'></slot>
          </footer>
        </div>
      `
    });
    var vm = new Vue({
      el: '#app',
      data: {

      }
    });
  </script>
</body>

</html>

作用域插槽用法

  • 应用场景:父组件对子组件的内容进行加工处理,从而呈现不同的样式
  • 语法规范:
1.父组件调用子组件的时候,给子组件传递插槽;这个插槽称为作用域插槽
使用作用域插槽:子组件可以向父组件的插槽中传递内容 :自定义属性=item

父组件中作用域插槽的内容以template开头和结尾。  <template></template>
父组件同时要声明从子组件接收的数据,放在那里  props ! slot-scope="props"
父组件同时还要告诉子组件模板的信息:接收到props怎么展示 
例如:以h1标签的形式展示  <h1>{{props.item}}</h1>

代码示例:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<style type="text/css">
  .current {
    color: orange;
  }
</style>

<body>
  <div id="app">
    <fruit-list :list='list'>
      <template slot-scope='slotProps'>
        <strong v-if='slotProps.info.id==3' class="current">{{slotProps.info.name}}</strong>
        <span v-else>{{slotProps.info.name}}</span>
      </template>
    </fruit-list>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <!-- 
      作用域插槽
        自定义属性 info
        在组件标签中,添加 template标签且添加slot-scope属性
    -->
  <script type="text/javascript">
    Vue.component('fruit-list', {
      props: ['list'],
      template: `
        <div>
          <li :key='item.id' v-for='item in list'>
            <slot :info='item'>{{item.name}}</slot>
          </li>
        </div>
      `
    });
    var vm = new Vue({
      el: '#app',
      data: {
        list: [{
          id: 1,
          name: 'apple'
        }, {
          id: 2,
          name: 'orange'
        }, {
          id: 3,
          name: 'banana'
        }]
      }
    });
  </script>
</body>

</html>

购物车案例

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style type="text/css">
    .container {}

    .container .cart {
      width: 300px;
      margin: auto;
    }

    .container .title {
      background-color: lightblue;
      height: 40px;
      line-height: 40px;
      text-align: center;
      /*color: #fff;*/
    }

    .container .total {
      background-color: #FFCE46;
      height: 50px;
      line-height: 50px;
      text-align: right;
    }

    .container .total button {
      margin: 0 10px;
      background-color: #DC4C40;
      height: 35px;
      width: 80px;
      border: 0;
    }

    .container .total span {
      color: red;
      font-weight: bold;
    }

    .container .item {
      height: 55px;
      line-height: 55px;
      position: relative;
      border-top: 1px solid #ADD8E6;
    }

    .container .item img {
      width: 45px;
      height: 45px;
      margin: 5px;
    }

    .container .item .name {
      position: absolute;
      width: 90px;
      top: 0;
      left: 55px;
      font-size: 16px;
    }

    .container .item .change {
      width: 100px;
      position: absolute;
      top: 0;
      right: 50px;
    }

    .container .item .change a {
      font-size: 20px;
      width: 30px;
      text-decoration: none;
      background-color: lightgray;
      vertical-align: middle;
    }

    .container .item .change .num {
      width: 40px;
      height: 25px;
    }

    .container .item .del {
      position: absolute;
      top: 0;
      right: 0px;
      width: 40px;
      text-align: center;
      font-size: 40px;
      cursor: pointer;
      color: red;
    }

    .container .item .del:hover {
      background-color: orange;
    }
  </style>
</head>

<body>
  <div id="app">
    <div class="container">
      <my-cart></my-cart>
    </div>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    var CartTitle = {
      props: ['uname'],
      template: `
        <div class="title">{{uname}}的商品</div>
      `
    }
    var CartList = {
      props: ['list'],
      template: `
        <div>
          <div :key='item.id' v-for='item in list' class="item">
            <img :src="item.img"/>
            <div class="name">{{item.name}}</div>
            <div class="change">
              <a href="" @click.prevent='sub(item.id)'>-</a>
              <input type="text" class="num" :value='item.num' @blur='changeNum(item.id, $event)'/>
              <a href="" @click.prevent='add(item.id)'>+</a>
            </div>
            <div class="del" @click='del(item.id)'>×</div>
          </div>
        </div>
      `,
      methods: {
        changeNum: function (id, event) {
          this.$emit('change-num', {
            id: id,
            type: 'change',
            num: event.target.value
          });
        },
        sub: function (id) {
          this.$emit('change-num', {
            id: id,
            type: 'sub'
          });
        },
        add: function (id) {
          this.$emit('change-num', {
            id: id,
            type: 'add'
          });
        },
        del: function (id) {
          // 把id传递给父组件
          this.$emit('cart-del', id);
        }
      }
    }
    var CartTotal = {
      props: ['list'],
      template: `
        <div class="total">
          <span>总价:{{total}}</span>
          <button>结算</button>
        </div>
      `,
      computed: {
        total: function () {
          // 计算商品的总价
          var t = 0;
          this.list.forEach(item => {
            t += item.price * item.num;
          });
          return t;
        }
      }
    }
    Vue.component('my-cart', {
      data: function () {
        return {
          uname: '张三',
          list: [{
            id: 1,
            name: 'TCL彩电',
            price: 1000,
            num: 1,
            img: 'img/a.jpg'
          }, {
            id: 2,
            name: '机顶盒',
            price: 1000,
            num: 1,
            img: 'img/b.jpg'
          }, {
            id: 3,
            name: '海尔冰箱',
            price: 1000,
            num: 1,
            img: 'img/c.jpg'
          }, {
            id: 4,
            name: '小米手机',
            price: 1000,
            num: 1,
            img: 'img/d.jpg'
          }, {
            id: 5,
            name: 'PPTV电视',
            price: 1000,
            num: 2,
            img: 'img/e.jpg'
          }]
        }
      },
      template: `
        <div class='cart'>
          <cart-title :uname='uname'></cart-title>
          <cart-list :list='list' @change-num='changeNum($event)' @cart-del='delCart($event)'></cart-list>
          <cart-total :list='list'></cart-total>
        </div>
      `,
      components: {
        'cart-title': CartTitle,
        'cart-list': CartList,
        'cart-total': CartTotal
      },
      methods: {
        changeNum: function (val) {
          // 因为统一用changeNum事件,所以分为三种情况:输入域变更、加号变更、减号变更
          if (val.type == 'change') {
            // 根据子组件传递过来的数据,跟新list中对应的数据
            this.list.some(item => {
              if (item.id == val.id) {
                item.num = val.num;
                // 终止遍历
                return true;
              }
            });
          } else if (val.type == 'sub') {
            // 减一操作
            this.list.some(item => {
              if (item.id == val.id) {
                item.num -= 1;
                // 终止遍历
                return true;
              }
            });
          } else if (val.type == 'add') {
            // 加一操作
            this.list.some(item => {
              if (item.id == val.id) {
                item.num += 1;
                // 终止遍历
                return true;
              }
            });
          }
        },
        delCart: function (id) {
          // 根据id删除list中对应的数据
          // 1、找到id所对应数据的索引
          var index = this.list.findIndex(item => {
            return item.id == id;
          });
          // 2、根据索引删除对应数据
          this.list.splice(index, 1);
        }
      }
    });
    var vm = new Vue({
      el: '#app',
      data: {

      }
    });
  </script>
</body>

</html>
相关标签: vue全家桶 vue.js