Vue.component
的缺点:
\
vue create my-app
命令创建一个默认的项目
在main.js
文件中有如下的代码:
new Vue({ render: h => h(App), }).$mount('#app')
如何理解render: h => h(App)
,可参考:
首先需要了解这是 es 6 的语法,表示 Vue 实例选项对象的 render 方法作为一个函数,接受传入的参数 h 函数,返回 h(App) 的函数调用结果。
v-slot can only be used on components or
<template>.
TotoItem.vue
<template> <li class="item"> <input type="checkbox" v-model="checked"/> <slot name="item" v-bind="{checked}"></slot> </li> </template> <script> export default { props: ["item"], data () { return { checked: false } } }; </script> <style scoped> .item { color: red; } </style>
App.vue
<template> <div id="app"> {{ msg }} <div> <input type="text" v-model="info"> <button v-on:click="handleClick">添加</button> </div> <ul> <todo-item v-for="item in list" :key="item" v-slot:item="itemProps"> <!-- <template v-slot:item="itemProps"> <span :style="{fontSize: '20px', color: itemProps.checked ? 'red': 'blue'}">{{ item }}</span> </template> --> <span :style="{fontSize: '20px', color: itemProps.checked ? 'red': 'blue'}">{{ item }}</span> </todo-item> </ul> </div> </template> <script> import TodoItem from './components/TodoItem.vue' export default { data() { return { msg: "hello wz", info: "", list: [] }; }, methods: { handleClick() { this.list.push(this.info); this.info = ""; } }, components: { TodoItem } }; </script> <style> </style>
自己的理解:
v-slot:item="itemProps"
表示的是name
为item
的slot
,itemProps
表示的是子组件中v-bind="{checked}
传递给父组件的itemProps
参考:
1.对slot与slot-scope的理解
由于slot是一块模板,因此对于任何一个组件,从模板种类的角度来分,共实都可分为非插槽模板和插槽模板。其中非插槽模板指的是HTML模板(也就是HTML的一些元素,比如div、span等构成的),其显与否及怎么显示完全由插件自身控制;但插槽模板(也就是slot)是一个空壳子,它显示与否以及怎么显示完全是由父组件来控制。不过,插槽显示的位置由子组件自身决定,slot写在组件template的哪块,父组件传过来的模板将来就显示在哪块。著作权归作者所有。
slot-scope
的值将被用作一个临时变量名,此变量接收从子组件传递过来的prop
对象
组件的三大核心概念:属性、事件和插槽
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。
额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。
如何解决:
1.这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用。在这种情况下,最好定义一个本地的 data 属性并将这个 prop 用作其初始值:
props: ['initialCounter'], data: function () { return { counter: this.initialCounter } }
2.这个 prop 以一种原始的值传入且需要进行转换。在这种情况下,最好使用这个 prop 的值来定义一个计算属性:
props: ['size'], computed: { normalizedSize: function () { return this.size.trim().toLowerCase() } }
如果在子组件中修改修改父组件的prop,会提示warn:
可参考官方文档:事件处理
各种控价的input 和 change事件可参考https://jsfiddle.net/posva/oqe9e8pb/
<script src="https://unpkg.com/vue/dist/vue.js"></script> <div id="app"> <input type="text" @input="addEvent" @change="addEvent" /> <input type="range" min="0" max="100" @input="addEvent" @change="addEvent" /> <input type="checkbox" @input="addEvent" @change="addEvent" /> <input type="radio" name="radio" value="1" @input="addEvent" @change="addEvent" /> <input type="radio" name="radio" value="2" @input="addEvent" @change="addEvent" /> <select @input="addEvent" @change="addEvent"> <option value="1">1</option> <option value="2">2</option> </select> <ul> <li v-for="event in events">{{ eventText(event) }}</li> </ul> </div> new Vue({ el: '#app', data: { events: [] }, methods: { addEvent ({ type, target }) { const event = { type, isCheckbox: target.type === 'checkbox', target: { value: target.value, checked: target.checked } } this.events.push(event) }, eventText (e) { return `${e.type}: ${e.isCheckbox ? e.target.checked : e.target.value}` } } })
可分为普通插槽和作用域插槽,但2.0之后就不再区分了
1.普通插槽:父->子,父组件传递数据/元素/组件给子组件,子组件定义
<slot>
占坑
2.作用域插槽:子->父,子组件<slot>
绑定属性,传递(数据)给父组件,父组件通过slot-scope接收子组件传递属性
3.使用v-slot
新语法,代替旧语法
4.多插槽时使用具名插槽方式(<slot name="header">
),用于将数据绑定在指定的插槽
Slot.vue
<template> <div> <slot /> <slot name="title" /> <slot name="item" v-bind="{ value: 'vue' }" /> </div> </template> <script> export default { name: "SlotDemo" }; </script>
使用
<h2>2.6 新语法</h2> <SlotDemo> <p>default slot</p> <template v-slot:title> <p>title slot1</p> <p>title slot2</p> </template> <template v-slot:item="props"> <p>item slot-scope {{ props }}</p> </template> </SlotDemo> <br /> <h2>老语法</h2> <SlotDemo> <p>default slot</p> <p slot="title">title slot1</p> <p slot="title">title slot2</p> <p slot="item" slot-scope="props">item slot-scope {{ props }}</p> </SlotDemo>
显示效果如下:
computed vs watch
补充:
生命周期分为三个阶段: