Vue基础学习

一、Vue入门基础知识

1、Vue使用的基本操作

i. 先下载,引入vue.js
ii. Vue,实例化一个vue实例化对象(new Vue({}))
    1. 新建一个vue实例化对象(Vue是一个构造函数)
    2. 执行vue构造函数中每一句代码
    3. 将新创建的vue实例化对象赋值给vue构造函数中的this

iii. 往vue实例化对象中传入一个对象(Vue实例化传入的对象里面的值也都为对象,以键值形式对存在,如data对象)

2、Vue的基础知识(应用:普通版的todolist(待办事项))

1) el: 节点挂载

限定Vue语法的作用范围

2) Data(需要渲染的数据,Vue 实例的数据对象)

    a) data的类型可以为:Object | Function。

    注:组件的定义只接受 function(因为函数有自己的作用域,每一个实例的data属性都是独立的)

    b) data可以为:

        1.    自定义数据

        2.    通过ajax获取的后台数据

        3.    Data是一个函数

 3)Vue语法,实现对(DOM)节点的渲染、删除、添加

    a) 模板渲染{{ obj }}(data中的数据可以直接在html中显示,让js变量直接在html中使用)

    b) v-for (列表渲染,使用for循环遍历数据生成节点,遍历对象和数组),数据驱动视图

    使用:1. 用 v-for 把一个数组对应为一组元素

                v-for=”(item,index) in list”

               list为源数据数组并且item是数组元素迭代的别名

                index为当前项的索引

                2、一个对象的 v-for

                v-for="(value,key) in object"

                object为data中定义的一个对象,value为对象的值,key为对象的键名

    c) 条件渲染v-if、v-show(使用数据隐藏和显示节点)
        1.v-if删除了节点
        2.v-show隐藏了节点(使用display:none隐藏了节点)

  d )删除节点,使用@click时间并在methods中定义delitem删除函数,并用v-bind绑定自定义属性,如::data-id="item.id"

        事件处理@click与回调函数methods (与v-bind结合使用,因为在进行操作的时候需要传入值)

        1. 在节点上直接绑定click事件
        2. 在methods属性中定义函数
        3. methods中使用data中的数据必须使用this访问

        4. this代表vue实例化对象

   e) 添加节点,通过input的value值与data绑定

   v-model与表单元素的value值的双向数据绑定(在表单控件或者组件上创建双向绑定,在节点上直接修改value属性)
            双向数据绑定

           1. 将表单中input的值value和data中值绑定起来

           (data设置该数据的属性值title:"默认值",input中绑定v-model="title",添加按钮绑定@click="additem")

            2. data改变input[value]改变

           data中的title的值改变,input中的value也会发生改变

            3. Input[value]改变data改变

            在input中输入值,点击添加按钮,data中的数据发生改变

    f)  绑定属性(自定义属性)(绑定属性值)V-bind:href,data-id
            1. 简写(:href)
            2. v-bind:的缩写 : (冒号)

    g)  v-if删除了节点,页面审查不到 

            v-show隐藏了节点(使用display:none隐藏了节点),页面能够审查到

  h)  template:定义组件模板,模板中的内容即为组件的内容
        1. 在template标签中写html模板,并标注id
        2. 在组件中使用template属性通过id引用template标签 

        3. 模板将会替换挂载的元素。挂载元素的内容都将被忽略

        4.    template中的html不会被浏览器首次加载时所渲染,在调用了组件之后才渲染的。

也就是说:template: '<App/>' 表示用<app></app>替换index.html里面的<div id="app"></div>

   i) 应用:普通版的todolist

 
  1. <!DOCTYPE html>

  2. <html lang="en">

  3.  
  4. <head>

  5. <meta charset="UTF-8">

  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">

  7. <meta http-equiv="X-UA-Compatible" content="ie=edge">

  8. <link rel="stylesheet" href="http://apps.bdimg.com/libs/bootstrap/3.3.4/css/bootstrap.css">

  9. <title>vue入门案例</title>

  10. </head>

  11.  
  12. <body>

  13. <div style="width: 500px;margin:0 auto;" id="app">

  14. <!-- V-if删除了节点,页面审查不到 -->

  15. <h1 v-if="status">{{message}}待办事项</h1>

  16. <!-- V-show隐藏了节点(使用display:none隐藏了节点),页面能够审查到-->

  17. <h1 v-show="status">{{message}}待办事项</h1>

  18. <p>即将添加的待办事项: {{title}}</p>

  19. <table class="table table-hover">

  20. <tr>

  21. <th>id</th>

  22. <th>标题</th>

  23. <th>操作</th>

  24. </tr>

  25. <!-- v-for,使用for循环遍历数据生成节点,遍历对象和数组-->

  26. <!-- v-bind的缩写 : (冒号),绑定属性(自定义属性) -->

  27. <tr :data-id="item.id" v-for="(item,index) in list">

  28. <td>{{item.id}}</td>

  29. <td>{{item.title}}</td>

  30. <td>

  31. <button class="btn btn-info" @click="delItem(item.id)">删除</button>

  32. </td>

  33. </tr>

  34. <!-- v-for遍历对象 -->

  35. <tr v-for="(value,key) in object">

  36. <td>{{key}}</td>

  37. <td>{{value}}</td>

  38. <td>

  39. <button class="btn btn-info">删除</button>

  40. </td>

  41. </tr>

  42. </table>

  43. <div class="form-group">

  44. <label for="exampleInputEmail1">添加待办事项</label>

  45. <!--V-model与表单元素的value值的双向数据绑定 -->

  46. <!-- 1 将表单中input的值value和data中值绑定起来

  47. 2 data改变input[value]改变

  48. 3 Input[value]改变data改变 -->

  49. <input v-model="title" type="text" class="form-control" id="exampleInputEmail1" placeholder="请输入待办事项">

  50. </div>

  51. <button @click="addItem()" type="submit" class="btn btn-default">添加</button>

  52. <div>

  53. <p>作者信息:{{author}}</p>

  54. <p>来源: <a :href="url">点击打开</a></p>

  55. </div>

  56. </div>

  57. <!-- <template id="clearApp">

  58. <h1>清空app</h1>

  59. </template> -->

  60. <script src="../js/vue.js"></script>

  61. <script>

  62. //VUE是一个构造函数

  63. //1 实现数据的渲染 删除 添加

  64.  
  65. var vm=new Vue({

  66. //节点挂载,用来限定vue的语法范围

  67. el: "#app",

  68. // template:"#clearApp",

  69. //data为需要渲染的数据

  70. //模板渲染{{ obj }}

  71. //(data中的数据可以直接在html中显示,让js变量直接在html中使用)

  72. data: function () {

  73. console.log(this);

  74. return {

  75. author:'xiean',

  76. status:false,

  77. url:'http://www.baidu.com',

  78. message: '小明的: ',

  79. title:'默认值',

  80. list: [

  81. { id: 0, title: "羽毛球" },

  82. { id: 1, title: "乒乓球" },

  83. { id: 2, title: "篮球" },

  84. { id: 3, title: "足球" }

  85. ],

  86. object:{

  87. name:"谢",

  88. sex:"女",

  89. address:"怀化"

  90. }

  91. }

  92. },

  93. methods: {

  94. delItem: function (id) {

  95. for (var key in this.list) {

  96. if (this.list[key].id == id) {

  97. this.list.splice(key, 1);

  98. }

  99. }

  100. },

  101. addItem:function(){

  102. this.list.push({id:this.list.length,title:this.title});

  103. console.log(this.list);

  104. }

  105. }

  106. });

  107.  
  108. </script>

  109. </body>

  110.  
  111. </html>

3、Vue组件

1)组件的创建与注册

  • 创建组件:Vue.extend({})
  • 创建组件,要在实例化对象之前创建
  • 组件是新的vue实例或者说是精简版的vue实例
  • 每一个组件里必须有一个根元素
  • 在父组件中使用components注册组件

  2) 组件通信

    1. 父子组件通信(通过局部注册)

    1)父组件传数据给子组件:(可以实现列表的渲染等操作)

        a) 为什么数据要放在父组件,数据需要分发,数据可能会在多个子组件中使用,所以vue官方推荐所有的数据都放在父组件中
        b) 父组件调用子组件的时候,给子组件绑定自定义属性,将值传递给子组件
       c) 子组件通过props接收父组件传递过来的数据
        d) props中的数据可以直接在子组件的模板中使用
        e) props在子组件中才有,父组件中没有
    2) 子组件传数据给父组件:$emit (用于实现节点的删除和添加等操作)
        a) 因为数据在父组件中,所以我们需要通过子组件将需要操作的数据传递给父组件,让父组件去操作数据
        b) 子组件通过$emit自定义一个事件,并且将需要操作的数据通过$emit传递给父组件
        c) 父组件我们需要@符来触发自定义事件,并且定义函数当做事件的回调函数,回调函数中形式参数接收子组件传过来的数据

a) 列表渲染(步骤)

  • 渲染节点时,父组件需要调用子组件,而数据在父组件中,子组件不能直接使用,所以父组件需要传数据给子组件,子组件获取数据后进行渲染。
  • 在父组件中绑定自定义属性如( :list="list"),子组件通过props接收父组件传递过来的数据,props接收的数据可以直接在子组件的模板中使用,然后用v-for进行数据的列表渲染。
  • ps: props在子组件中才有,父组件中没有

b) 删除节点

  • 删除节点,在子组件中点击删除按钮获取需要删除的记录的id,并将id传递给父组件,父组件中定义delitem进行删除。
  • 子组件通过$emit自定义一个事件,并将需要操作的数据通过$emit传递给父组件 (如:this.$emit("delitem",id))
  • 父组件中需要@符去触发自定义事件,并且自定义函数当作事件的回调函数,回调函数中形式参数接收子组件中传过来的数据。

c) 添加节点

添加节点首先需要进行input value值和data数据的双向绑定,然后通过 子组件的additem方法获取输入的对象,并通过$emit将数据对象传入至父组件中,父元素通过@符触发自定义事件,接收子组件传递过来的数据,并实现定义的函数。将数据push到list中。

 
  1. <!DOCTYPE html>

  2. <html lang="en">

  3.  
  4. <head>

  5. <meta charset="UTF-8">

  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">

  7. <meta http-equiv="X-UA-Compatible" content="ie=edge">

  8. <link rel="stylesheet" href="http://apps.bdimg.com/libs/bootstrap/3.3.4/css/bootstrap.css">

  9. <title>父子组件通信版todolist</title>

  10. </head>

  11.  
  12. <body>

  13. <div style="width: 500px;margin:0 auto;" id="app">

  14. <h1>待办事项</h1>

  15. <myh1></myh1>

  16. <mytable :list="list" @delitem="delitem"></mytable>

  17. <myadd :length="this.list.length" @additem="additem"></myadd>

  18. </div>

  19. <!-- 每一个组件必须有一个根元素,要不然会报错 -->

  20. <template id="myadd">

  21. <div>

  22. <div class="form-group">

  23. <label for="exampleInputEmail1">添加待办事项</label>

  24. <input v-model="title" type="text" class="form-control" id="exampleInputEmail1" placeholder="请输入待办事项">

  25. </div>

  26. <button @click="additem()" type="submit" class="btn btn-default">添加</button>

  27. </div>

  28. </template>

  29. <template id="mytable">

  30. <table class="table table-hover">

  31. <tr>

  32. <th>id</th>

  33. <th>标题</th>

  34. <th>操作</th>

  35. </tr>

  36. <tr :data-id="item.id" v-for="(item,index) in list">

  37. <td>{{item.id}}</td>

  38. <td>{{item.title}}</td>

  39. <td>

  40. <button @click="delitem(item.id)" class="btn btn-info">删除</button>

  41. </td>

  42. </tr>

  43. </table>

  44. </template>

  45. <script src="../js/vue.js"></script>

  46. </body>

  47.  
  48. <script>

  49. //vm (ViewModel 的缩写)

  50. //创建组件,每一个组件必须有一个根元素

  51. var myh1 = Vue.extend({

  52. //组件的模板

  53. template: "<h1>我是h1</h1>",

  54. data: function () {

  55. return {

  56.  
  57. }

  58. }

  59. })

  60. var mytable = Vue.extend({

  61. props: ['list'],

  62. template: "#mytable",

  63. data: function () {

  64. return {

  65.  
  66. }

  67. },

  68. methods: {

  69. delitem: function (id) {

  70. this.$emit("delitem", id);

  71. }

  72. }

  73. })

  74. var myadd = Vue.extend({

  75. props:['length'],

  76. template: "#myadd",

  77. data: function () {

  78. return {

  79. title: "默认值"

  80. }

  81. },

  82. methods:{

  83. additem:function(){

  84. this.$emit("additem",{id:this.length,title:this.title});

  85. }

  86. }

  87. })

  88. var vm = new Vue({

  89. el: "#app",

  90. data: function () {

  91. return {

  92. list: [

  93. { id: 0, title: "吃饭" },

  94. { id: 1, title: "睡觉" },

  95. { id: 2, title: "写代码" },

  96. { id: 3, title: "打游戏" },

  97. ]

  98. }

  99. },

  100. methods: {

  101. delitem: function (id) {

  102. for (var key in this.list) {

  103. if (this.list[key].id == id) {

  104. this.list.splice(key, 1);

  105. }

  106. }

  107. },

  108. additem:function(obj){

  109. console.log(obj);

  110. this.list.push(obj);

  111. }

  112. },

  113. //注册组件

  114. components: {

  115. myh1,

  116. mytable,

  117. myadd

  118. }

  119. })

  120.  
  121. </script>

  122.  
  123. </html>

 

2、兄弟组件通信(全局注册,在创建的时候就已经注册了)

    a) 使用Vue.component定义(包括创建和注册)全局组件
    b) 定义另外一个vue实例vm
    c) 在添加数据数据兄弟组件中使用vm.$emit传送数据
    d) 在获取的数据兄弟组件中created生命周期函数中使用vm.$on来接收数据,使用v-for渲染数据,绑定点击事件,删除元素

 
  1. <!DOCTYPE html>

  2. <html lang="en">

  3.  
  4. <head>

  5. <meta charset="UTF-8">

  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">

  7. <meta http-equiv="X-UA-Compatible" content="ie=edge">

  8. <link rel="stylesheet" href="http://apps.bdimg.com/libs/bootstrap/3.3.4/css/bootstrap.css">

  9. <title>兄弟组件通信</title>

  10. </head>

  11.  
  12. <body>

  13. <div style="width: 500px;margin:0 auto;" id="app">

  14. <h1>待办事项</h1>

  15. <mytable></mytable>

  16. <myadd></myadd>

  17. </div>

  18. <template id="mytable">

  19. <table class="table table-hover">

  20. <tr>

  21. <th>id</th>

  22. <th>标题</th>

  23. <th>操作</th>

  24. </tr>

  25. <tr v-for="item in list">

  26. <td>{{item.id}}</td>

  27. <td>{{item.title}}</td>

  28. <td>

  29. <button @click="delitem(item.id)" class="btn btn-info">删除</button>

  30. </td>

  31. </tr>

  32. </table>

  33. </template>

  34. <!-- //定义组件模板 -->

  35. <template id="myadd">

  36. <div>

  37. <div class="form-group">

  38. <label for="exampleInputEmail1">添加待办事项</label>

  39. <input v-model="title" type="text" class="form-control" id="exampleInputEmail1" placeholder="请输入待办事项">

  40. </div>

  41. <button @click="additem" type="submit" class="btn btn-default">添加</button>

  42. </div>

  43. </template>

  44. <script src="../js/vue.js"></script>

  45. </body>

  46.  
  47. <script>

  48. //通过两个子组件交互,实现通信

  49. //定义另外一个vue实例

  50. var vm = new Vue();

  51. //组件的创建和注册

  52. Vue.component('mytable', {

  53. //使用组件模板

  54. template: "#mytable",

  55. data: function () {

  56. return {

  57. list: []

  58. }

  59. },

  60. methods:{

  61. delitem:function(id){

  62. for(var key in this.list){

  63. if(this.list[key].id==id){

  64. this.list.splice(key,1);

  65. }

  66. }

  67. }

  68. },

  69. //生命周期函数,一个在创建的过程中会自己执行的函数

  70. created:function(){

  71. //保存指向mytable的地址

  72. var _this=this;

  73. vm.$on("additem",function(obj){

  74. _this.list.push(obj);

  75. });

  76. }

  77. })

  78. Vue.component('myadd', {

  79. template: "#myadd",

  80. data: function () {

  81. return {

  82. id:0,

  83. title:"默认值"

  84. }

  85. },

  86. methods:{

  87. additem:function(){

  88. vm.$emit("additem",{id:this.id++,title:this.title});

  89. }

  90. }

  91. })

  92. new Vue({

  93. el: "#app"

  94. })

  95. </script>

  96.  
  97. </html>

3、生命周期函数

d) Vue生命周期函数(执行vue构造函数的过程中,必须执行的代码,执行生命周期就是执行构造函数)
        i. 生命周期:Vue 实例化对象从开始创建、初始化数据、编译模板、挂载节点elDom→渲染、更新→渲染、卸载等一系列过程,我们称这是 Vue 的生命周期,各个阶段有相对应的事件钩子(在这个过程中会自己执行的函数)
        ii. beforeCreate:vue实例化对象创建完成之前
            1. this已经指向vue实例化对象,但不能访问data和methods中的属性和方法
        iii. created:vue实例化对象创建完成
            1. this已经指向vue实例化对象,可以访问data和methods中的属性和方法
            2. 未挂载到DOM,不能访问到$el属性
            3. 作用:
a) 常用于首屏数据渲染时,发送ajax请求获取数据。
        iv. beforeMount:通过数据生成了全部虚拟节点(使用createElement创建的节点,但是这些节点没有插入到html文档中),但还没有挂载到el节点上。
            1. 可以访问到$el
        v. mounted:vue实例挂载到el节点(DOM)上
            1. 把通过数据生成的虚拟节点,挂载 到el节点中
            2. 作用:
a) 常用于操作真实的dom节点
        vi. beforeUpdate:
            1. 手动添加的虚拟节点,但是还未插入到el(真实节点)中更新之前
            2. 不能操作该节点
        vii. updated:
            1. 手动添加的虚拟节点已经更新完成。
            2. 可以操作到手动添加的节点
        viii. beforeDestroy:(调用vm.$destroy()销毁实例)
            1. vue实例销毁之前调用。
        ix. destroyed:
            1. 实例销毁后调用,调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁

 
  1. <!DOCTYPE html>

  2. <html lang="en">

  3.  
  4. <head>

  5. <meta charset="UTF-8">

  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">

  7. <meta http-equiv="X-UA-Compatible" content="ie=edge">

  8. <title>生命周期函数</title>

  9. </head>

  10.  
  11. <body>

  12.  
  13. <div id="app">

  14. <ul>

  15. <li v-for="item in list">{{item}}</li>

  16. </ul>

  17. <button @click="additem">添加li</button>

  18. </div>

  19.  
  20. <script src="../js/vue.js"></script>

  21. <!-- <script src="js/vue-router.js"></script> -->

  22. <script>

  23. var vm=new Vue({

  24. el: "#app",

  25. // 1.this已经指向vue实例化对象,但不能访问data和methods中的属性和方法

  26. // beforeCreate:function(){

  27. // console.log(this);//输出vue的实例

  28. // console.log(this.title);//输出undefined

  29. // this.sayName();

  30. // },

  31. // created常用于首屏数据渲染时,发送ajax请求获取数据。

  32. // created:function(){

  33. // console.log(this);//输出vue的实例

  34. // console.log(this.title);//输出小明

  35. // this.sayName();//输出hello!小明

  36. // // $el即为#app

  37. // console.log(this.$el);//输出undefined

  38. // },

  39. // beforeMount:function(){

  40. // console.log(this);//输出vue的实例

  41. // console.log(this.title);//输出小明

  42. // this.sayName();//输出hello!小明

  43. // console.log(this.$el);//能获取到#app

  44. // console.log(document.querySelectorAll("li"));//只能获取到一个节点,不能获取到真实节点

  45. // },

  46. // mounted:function(){

  47. // console.log(this);//输出vue的实例

  48. // console.log(this.title);//输出小明

  49. // this.sayName();//输出hello!小明

  50. // console.log(this.$el);//能获取到#app

  51. // console.log(document.querySelectorAll("li"));//获取到真实节点

  52. // },

  53. // beforeUpdate:function(){

  54. // console.log(this);//输出vue的实例

  55. // console.log(this.title);//输出小明

  56. // this.sayName();//输出hello!小明

  57. // console.log(this.$el);//能获取到#app

  58. // console.log(document.querySelectorAll("li"));//手动添加的节点不能获取到

  59. // },

  60. // updated:function(){

  61. // console.log(this);//输出vue的实例

  62. // console.log(this.title);//输出小明

  63. // this.sayName();//输出hello!小明

  64. // console.log(this.$el);//能获取到#app

  65. // console.log(document.querySelectorAll("li"));//手动添加的节点能获取到

  66. // },

  67.  
  68. //添加事件已解除绑定,无法操作了

  69. beforeDestroy: function () {

  70. console.log("vue实例销毁之前调用");

  71. },

  72. destroyed: function () {

  73. console.log("实例销毁后调用,调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁");

  74. },

  75. data: function () {

  76. return {

  77. title: "小明",

  78. list: [121, 2313, 3213, 1231, 212]

  79. }

  80. },

  81. methods: {

  82. sayName: function () {

  83. console.log("hello!" + this.title);

  84. },

  85. additem: function () {

  86. this.list.push("123");

  87. }

  88. }

  89. });

  90. vm.$destroy();

  91. </script>

  92. </body>

  93.  
  94. </html>

4、computed计算属性与watch侦听器与methods方法的区别

    1)计算属性:适合大量计算,不适合大量逻辑判断,内存会缓存计算的结果,当要计算的数据相同时,它不会进行二次计算,而是取缓存里的数据。
    2)methods:适合大量逻辑处理(if,for等等),它不会缓存计算的过,当要计算的数据相同时,它会进行二次计算。

    3 watch:侦听需要变化的数据,执行回调函数。(可以用来监听pn的变化,实现分页)

 
  1. <!DOCTYPE html>

  2. <html lang="en">

  3. <head>

  4. <meta charset="UTF-8">

  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">

  6. <meta http-equiv="X-UA-Compatible" content="ie=edge">

  7. <title>计算属性</title>

  8. </head>

  9. <body>

  10.  
  11. <div id="app">

  12. <p>计算属性的结果为:{{count}}</p>

  13. <p>methods计算的结果为:{{count2()}}</p>

  14. watch:<input v-model="a" type="text">

  15. <p>c的值为:{{c}}</p>

  16. </div>

  17.  
  18. <script src="../js/vue.js"></script>

  19. <script>

  20. new Vue({

  21. el:"#app",

  22. data:function(){

  23. return {

  24. a:10,

  25. b:20,

  26. c:0

  27.  
  28. }

  29. },

  30. computed:{

  31. count:function(){

  32. return (this.a+this.b)*this.a

  33. }

  34. },

  35. methods:{

  36. count2:function(){

  37. return (this.a+this.b)*this.a

  38. }

  39. },

  40. watch:{

  41. //监听a的变化,执行这个函数

  42. a:function(){

  43. return this.c+=parseInt(this.a);

  44. }

  45. }

  46. });

  47. </script>

  48. </body>

  49. </html>

5、插槽slot
    1.) 从父组件中将带有数据的html模板传入到子组件
        a) 在父组件中使用slot属性定义插槽(插槽写在调用子组件的内部)
        b) 在子组件中使用<slot></slot>调用插槽
        c) 没有名字的模块,其内容会全部到没有名字的插槽中
        d) 作用:
                相当于不使用props也可以将父组件的data传递给子组件
    2.) 具名插槽
            a) 带有特点name属性的插槽
    3. )匿名插槽
        a) 没有name属性的插槽,除了具名插槽,剩下的都会被内容都会被渲染到匿名插槽中
    4. )作用域插槽
        a) 绑定了数据的插槽
        b) Slot-scope

        c) 必须使用template定义,并且要使用slot-scope属性定义一个引用

    删除节点步骤:1、先创建模板、创建组件、注册组件

                           2、父组件给子组件绑定自定义属性,将值传递给子组件;使用v-for渲染数据

                            3、将删除的按钮放到作用域插槽中,创建作用域插槽来传递数据

    5. )三者区别:
        a) 具名插槽和匿名插槽内容和样式与数据都由父组件提供

        b) 作用域插槽可以传递数据,数据由子组件提供

 
  1. <!-- 插槽 -->

  2. <!DOCTYPE html>

  3. <html lang="en">

  4. <head>

  5. <meta charset="UTF-8">

  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">

  7. <meta http-equiv="X-UA-Compatible" content="ie=edge">

  8. <title>插槽</title>

  9. </head>

  10. <body>

  11. <div id="app">

  12. <!-- 插槽要写在调用子组件内部 -->

  13. <child>

  14. <h1 class="header" slot="header">我是头部</h1>

  15. <div class="content" slot="content">我是内容</div>

  16. <div class="footer" slot="footer">我是尾部</div>

  17. <!-- 使用插槽很好的避免了父子组件间的频繁通信 -->

  18. <ul>

  19. <li v-for="item in list">{{item}}</li>

  20. </ul>

  21. </child>

  22. </div>

  23. <template id="child">

  24. <div class="wrap">

  25. <h1 class="header">

  26. <slot name="header"></slot>

  27. </h1>

  28. <div class="content">

  29. <slot></slot>

  30. </div>

  31. <div class="footer">

  32. <slot name="footer"></slot>

  33. </div>

  34. </div>

  35. </template>

  36. <script src="../js/vue.js"></script>

  37. <script>

  38. //定义一个子组件

  39. var child= Vue.extend({

  40. template:"#child",

  41. data :function(){

  42. return {

  43.  
  44. }

  45.  
  46. }

  47. })

  48. new Vue({

  49. el:"#app",

  50. data:function(){

  51. return {

  52. list:[121,3213,3213,231,3123,32]

  53. }

  54. },

  55. methods:{

  56.  
  57. },

  58. components:{

  59. child

  60. }

  61. })

  62. </script>

  63.  
  64. </body>

  65. </html>

 
  1. <!-- 作用域插槽 -->

  2. <!DOCTYPE html>

  3. <html lang="en">

  4.  
  5. <head>

  6. <meta charset="UTF-8">

  7. <meta name="viewport" content="width=device-width, initial-scale=1.0">

  8. <meta http-equiv="X-UA-Compatible" content="ie=edge">

  9. <link rel="stylesheet" href="http://apps.bdimg.com/libs/bootstrap/3.3.4/css/bootstrap.css">

  10. <title>作用域插槽版todolist</title>

  11. </head>

  12.  
  13. <body>

  14. <div style="width: 500px;margin:0 auto;" id="app">

  15. <h1>待办事项</h1>

  16. <mytable :list="list">

  17. <!-- scope即为传入的id对象 -->

  18. <!-- 作用域插槽 -->

  19. <template slot="delbtn" slot-scope="scope">

  20. <button @click="delitem(scope)" class="btn btn-info">删除</button>

  21. </template>

  22. </mytable>

  23. <myadd></myadd>

  24. </div>

  25. <template id="mytable">

  26. <table class="table table-hover">

  27. <tr>

  28. <th>id</th>

  29. <th>标题</th>

  30. <th>操作</th>

  31. </tr>

  32. <tr v-for="item in list">

  33. <td>{{item.id}}</td>

  34. <td>{{item.title}}</td>

  35. <td>

  36. <slot name="delbtn" :id="item.id"></slot>

  37. </td>

  38. </tr>

  39. </table>

  40. </template>

  41. <template id="myadd">

  42. <div>

  43. <div class="form-group">

  44. <label for="exampleInputEmail1">添加待办事项</label>

  45. <input type="text" class="form-control" id="exampleInputEmail1" placeholder="请输入待办事项">

  46. </div>

  47. <button type="submit" class="btn btn-default">添加</button>

  48. </div>

  49. </template>

  50. <script src="../js/vue.js"></script>

  51. <script>

  52. var mytable = Vue.extend({

  53. template: "#mytable",

  54. props: ['list'],

  55. data: function () {

  56. return {

  57.  
  58. }

  59. },

  60. methods: {

  61.  
  62. }

  63. })

  64. var myadd = Vue.extend({

  65. template: "#myadd",

  66. data: function () {

  67. return {

  68.  
  69. }

  70. }

  71. })

  72. new Vue({

  73. el: "#app",

  74. data: function () {

  75. return {

  76. list: [

  77. { id: 0, title: "吃饭" },

  78. { id: 1, title: "睡觉" },

  79. { id: 2, title: "写代码" },

  80. { id: 3, title: "打游戏" },

  81. ]

  82. }

  83. },

  84. methods: {

  85. delitem: function (scope) {

  86. //利用数组的foeach方法遍历

  87. console.log(this);

  88. var _this = this;

  89. this.list.forEach(function (item, index) {

  90. if (item.id == scope.id) {

  91. _this.list.splice(index, 1);

  92. }

  93. })

  94. }

  95. },

  96. components: {

  97. mytable,

  98. myadd

  99. }

  100. })

  101. </script>

  102. </body>

  103.  
  104. </html>

6、ref与$refs

    1. )使用ref对元素或子组件加一个标识
    2.)this.$refs.标识

    3. )作用:可以直接操作真实节点和子组件

 
  1. <!DOCTYPE html>

  2. <html lang="en">

  3.  
  4. <head>

  5. <meta charset="UTF-8">

  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">

  7. <meta http-equiv="X-UA-Compatible" content="ie=edge">

  8. <title>ref和$refs</title>

  9. </head>

  10.  
  11. <body>

  12. <div id="app">

  13. <input type="text" ref="input">

  14. <child ref="h1"></child>

  15. <!-- //验证字段为空时会用到 -->

  16. <!-- 点击即可获取到子组件的值 -->

  17. <button @click="getInput">点击</button>

  18. </div>

  19. <template id="child">

  20. <div>

  21. <h1>我是子组件</h1>

  22. <h2>我是子组件</h2>

  23. </div>

  24. </template>

  25. <script src="../js/vue.js"></script>

  26. <script>

  27. var child = Vue.extend({

  28. template: "#child",

  29. data: function () {

  30. return {

  31. name: "哈哈哈"

  32.  
  33. }

  34. }

  35. })

  36. new Vue({

  37. el: "#app",

  38. data: function () {

  39. return {

  40.  
  41. }

  42. },

  43. methods: {

  44. getInput: function () {

  45. // ref与refs用于直接操作真实的节点

  46. //获取子组件

  47. console.log(this.$refs.h1.name);

  48. //获取input节点

  49. console.log(this.$refs.input);

  50. }

  51. },

  52. components: {

  53. child

  54. }

  55. })

  56. </script>

  57. </body>

  58.  
  59. </html>

  • 33
    点赞
  • 121
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值