Vue2入门二:组件化开发-组件与实例

vue入门学习笔记,vue.js下载
  • 1、组件

组件指页面中的一部分

<!DOCTYPE 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>Vue Learning</title>
    <script src="./vue.js"></script
  </head>
  <body>
    <div id="app">
        <div>
            <input v-model="inputValue"/>
            <button @click="handleClick">提交</button>
        </div>
        <ul>
            <todo-item v-for="(item,index) of itemValues" 
                        :key="index" 
                        :content="item"> <!-- 定义属性content来传递值-->        
            </todo-item>
        </ul>
    </div>
    
    <script>
        <!-- 全局组件 -->
        Vue.component("todo-item",{
            props:["content"],//子组件中定义props来接收父组件传递来的参数,然后才能在模板中使用
            template:"<li>{{content}}</li>"
        })
        <!-- 局部组件 使用前需要在Vue实例中使用components声明 -->
        //var TodoItem={
        //    template:"<li>item</li>"
        //}
        
        new Vue({
            el:"#app",
            //components:{
            //    "todo-item":TodoItem
            //},
            data:{
                inputValue:"",
                itemValues:[]
            },
            methods:{
                handleClick:function(){
                    this.itemValues.push(this.inputValue)
                    this.inputValue=""
                }
            }
        })
    </script>
  </body>
</html>
  • 2、组件与实例的关系

每一个组件也是一个vue的实例,实例拥有的属性和方法组件也有。父组件不定义模板是因为它把子组件当做模板。

<!DOCTYPE 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>Vue Learning</title>
    <script src="./vue.js"></script
  </head>
  <body>
    <div id="app">
        <div>
            <input v-model="inputValue"/>
            <button @click="handleSubmit">提交</button>
        </div>
        <ul>
            <todo-item v-for="(item,index) of itemValues" 
                        :key="index" 
                        :content="item">     
            </todo-item>
        </ul>
    </div>
    
    <script>
        Vue.component("todo-item",{
            props:["content"],
            template:"<li @click='handleClick'>{{content}}</li>",//子组件也拥有属性
            methods:{//子组件也拥有方法
                handleClick:function(){
                    alert("123")
                }
            }
        })

        new Vue({
            el:"#app",
            data:{
                inputValue:"",
                itemValues:[]
            },
            methods:{
                handleSubmit:function(){
                    this.itemValues.push(this.inputValue)
                    this.inputValue=""
                }
            }
        })
    </script>
  </body>
</html>
  • 3、实组件通信:发布订阅模式

子组件与父组件通信才能实现子组件对父组件数据的操作,通过发布订阅来完成。

(1)父组件向子组件传值:props

//子组件:组件内部通过props接收传递过来的值
Vue.component('menu-item',{
        props:['postTitle'],
        template: '<div>{{title}}</div>'
})
//父组件
//①父组件通过属性将值传递给子组件 ;传入一个静态的值
<menu-item post-title="来自父组件的数据"></menu-item>
//②建议使用v-bind进行绑定;dataTitle:父组件中的数据 ;动态赋予一个变量的值
<menu-item :post-title="dataTitle"></menu-item>

 引用官方文档的话:所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。

注意:

①prop 命名规则 (camelCase vs kebab-case):使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 命名

②prop的类型:字符串,数值,布尔值,数组,对象

(2)子组件向父组件传值:

 引用官方文档的话:每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。

不推荐直接在子组件中直接更新父组件中的值。

//子组件中自定义事件:通过触发自定义事件(含参),使用$emit
<button @click="$emit('enlarge-text',0.1)">扩大字体</button>

//父组件中监听:使用$event接收参数
<menu-item @enlarge-ext="fontSize+=$event"></menu-item>

  (3)非父子组件(即兄弟组件)传值:

分成以下三步:

单独的事件中心管理组件间的通信;

var eventHub=new Vue()

②监听事件(在mounted钩子函数中)与销毁事件

//
add-todo
监听事件名称,addTodo方法
eventHub.$on('add-todo',addTodo) eventHub.$off('add-todo')

③触发事件

//add-todo触发事件名称,addTodo方法
eventHub.$emit('add-todo',id)
  • 4、插槽

 组件插槽的作用:父组件向子组件传递内容;

 插槽位置:

    Vue.component('menu-item',{
        template: `
            <div>
            <strong>Error</strong>
            <slot></slot>
            </div>
           `
    })

 插槽内容:

<menu-item>插槽内容</menu-item>

 (1)具名插槽-即具有名字的插槽

 插槽定义:
<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>

 插槽内容:

<base-layout>
  <template v-slot:header>
    <h1>Here might be a page title</h1>
  </template>

  <p>A paragraph for the main content.</p>
  <p>And another one.</p>

  <template v-slot:footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>

(2)作用域插槽-父组件对子组件的内容进行加工处理

  插槽定义:

Vue.component('fruit-list', {
    props: ['list'],
    template: `
      <ul>
      <li v-for="item in list" v-bind:key="item.id">
        <slot v-bind:itemid="item">
          {{ item.name }}
        </slot>
      </li>
      </ul>
    `
})

 插槽内容:

<fruit-list v-bind:inlist="list">
        <template slot-scope="slotProps">
            <strong v-if="slotProps.item.current">
                {{slotProps.item.text}}
            </strong>
        </template>
</fruit-list>

 

  • 5、实现todolist的删除功能

<!DOCTYPE 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>Vue Learning</title>
    <script src="./vue.js"></script
  </head>
  <body>
    <div id="app">
        <div>
            <input v-model="inputValue"/>
            <button @click="handleSubmit">提交</button>
        </div>
        <ul>
            <todo-item v-for="(item,index) of itemValues" 
                        :key="index" 
                        :content="item"
                        :index="index"
                        @delete="handleDelete"><!--2 父组件订阅了事件delete-->     
            </todo-item>
        </ul>
    </div>
    
    <script>
        Vue.component("todo-item",{
            props:["content","index"],
            template:"<li @click='handleClick'>{{content}}</li>",
            methods:{
                handleClick:function(){
                    this.$emit('delete',this.index)<!--1 子组件发布一个事件delete--> 
                }
            }
        })

        new Vue({
            el:"#app",
            data:{
                inputValue:"",
                itemValues:[]
            },
            methods:{
                handleSubmit:function(){
                    this.itemValues.push(this.inputValue)
                    this.inputValue=""
                },
                handleDelete:function(index){<!--3 父组件处理handleDelete-->
                    this.itemValues.splice(index,1)
                }
            }
        })
    </script>
  </body>
</html>

  

 【Vue】组件传值的六种方法

 

 
 
 
 
 
posted @ 2020-12-19 15:37  权杖攻城狮  阅读(360)  评论(0编辑  收藏  举报