VUE学习笔记——v-for/组件
零、VUE代码风格指南:https://cn.vuejs.org/v2/style-guide/1.当直接在 DOM 中使用一个组件 (而不是在字符串模板或单文件组件) 的时候,我们强烈推荐遵循W3C 规范中的自定义组件名 (字母全小写且必须包含一个连字符,即kebab-case命名)。这会帮助你避免和当前以及未来的 HTML 元素相冲突(HTML 元素是大小写不敏感的,在 DOM 模板中会...
零、VUE代码风格指南:https://cn.vuejs.org/v2/style-guide/
1.当直接在 DOM 中使用一个组件 (而不是在字符串模板或单文件组件) 的时候,我们强烈推荐遵循 W3C 规范中的自定义组件名 (字母全小写且必须包含一个连字符,即kebab-case命名)。这会帮助你避免和当前以及未来的 HTML 元素相冲突(HTML 元素是大小写不敏感的,在 DOM 模板中会被自动转换为全小写 ,但是事件名是大小写敏感的,为了防止冲突推荐始终使用 kebab-case 命名)。
一、v-for列表渲染:https://cn.vuejs.org/v2/guide/list.html
1.v-for数组:v-for="(item, index) in items"
2.v-for对象:v-for="(value, key, index) in object"
【v-for与:key(看不懂就继续查):https://www.cnblogs.com/zhumingzhenhao/p/7688336.html
https://www.jb51.net/article/145477.htm
https://www.jianshu.com/p/5807d9378776】
3.v-for数组更新检测:
变异方法:push()、pop()、shift()、unshift()、splice()、sort()、reverse()
例子:example1.items.push({ message: 'Baz' })
替换数组的方法:filter()
, concat()
和 slice()
【注意事项:https://cn.vuejs.org/v2/guide/list.html#%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9】
【注意:类似v-for这样的指令必须放在vue实例里面才能生效:
<!--失效-->
<div>
<span v-for="n in 10">{{ n }}</span>
</div>
<!--生效:输出1 2 3 4 5 6 7 8 9 10-->
<div id="app">
<span v-for="n in 10">{{ n }}</span>
</div>
<script>
var vm = new Vue({
el: '#app'
});
</script>
】
4.v-for with v-if (v-for优先级更高) :https://cn.vuejs.org/v2/guide/list.html#v-for-with-v-if
【VUE代码风格指南:https://cn.vuejs.org/v2/style-guide/】
5.v-for 与组件
二、组件:https://cn.vuejs.org/v2/guide/components.html
1.熟悉基本示例的使用
【组件是可复用的 Vue 实例,所以它们与 new Vue
接收相同的选项,所以也会有 data
、computed
、watch
、methods
以及生命周期钩子等。仅有的例外是像 el
这样根实例特有的选项。】
2.组件可以复用,并且各自独立维护自己的数据,因为每个组件都对应一个新的实例
组件的data属性必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝
data: function () { return { count: 0 } } 而不是 data: { count: 0 }
3.组件的组织(树结构)、组件的注册(全局与局部)
4.实用例子:
【通过props向子组件传递数据、单个根元素、监听子组件事件$emit(参数1是事件名,参数2是携带的数据)、】
<div id="blog-post-demo">
<div v-bind:style="{ fontSize: postFontSize + 'em' }">
<blog-post v-for="post in posts" v-bind:key="post.id" v-bind:post="post" v-on:enlarge-text="onEnlargeText"></blog-post>
</div>
</div>
<button onclick="console.log(123)">text</button>
<script>
Vue.component('blog-post', {
props: ['post'], //对应父元素传过来的v-bind:post
//组件模板必须有且只有一个根元素
//$emit('enlarge-text' , 0.1) 第一个是要触发的事件名,第二个是携带的参数(传对象可以携带更多数据,父元素可以用$event接收该数据,该例子没写需查看文档深入了解)
//v-on:click="$emit('enlarge-text' , 0.1)" 会让父元素触发 v-on:enlarge-text="onEnlargeText" 监听器从而改变字体大小
template: `
<div class="blog-post">\
<h3>{{ post.title }}</h3>\
<button v-on:click="$emit('enlarge-text' , 0.1)">\
Enlarge text\
</button>\
<div v-html="post.content"></div>\
<hr>\
</div>\
`
})
new Vue({
el: '#blog-post-demo',
data: {
//数据也可以从API中获取
posts: [
{ id: 1, title: 'My journey with Vue', content: 'content1'},
{ id: 2, title: 'Blogging with Vue' , content: 'content2'},
{ id: 3, title: 'Why Vue is so fun' , content: 'content3'}
],
postFontSize: 1 //通过postFontSize统一字体大小
},
methods: {
//根据传递的参数改变字体的大小
onEnlargeText: function (enlargeAmount) {
this.postFontSize += enlargeAmount
}
}
})
</script>
【小知识:
a.简写函数:methods: { addCount: function () { this.count ++} } 与 v-on:click="addCount"
可以简写为v-on:click="count++",即可以不传函数名,直接写操作
b.开发者工具看JS文件乱码时:https://www.cnblogs.com/kennyliu/p/4086601.html
所以这样就好了:<script src="xxx.js" charset="utf-8" type="text/javascript"></script>
c.动态赋予一个复杂表达式的值
<blog-post v-bind:title="post.title + ' by ' + post.author.name" ></blog-post>】
5.通过插槽<slot>接收分发内容(让组件能够像HTML标签一样能显示标签所夹的内容)
<alert-box> Something bad happened. </alert-box>
Vue.component('alert-box', { template: ` <div class="demo-alert-box"> <strong>Error! </strong> <slot></slot> </div> ` })
最终会输出:Error! Something bad happened.
6.未研究的部分:
a.在组件上使用v-model()创建自定义输入组件:https://cn.vuejs.org/v2/guide/components.html#%E5%9C%A8%E7%BB%84%E4%BB%B6%E4%B8%8A%E4%BD%BF%E7%94%A8-v-model
b.解析DOM模板时的注意事项:https://cn.vuejs.org/v2/guide/components.html#%E8%A7%A3%E6%9E%90-DOM-%E6%A8%A1%E6%9D%BF%E6%97%B6%E7%9A%84%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9
三、深入了解组件:https://cn.vuejs.org/v2/guide/components-registration.html
1.组件注册(第一个参数是组件名,推荐使用 kebab-case (短横线分隔命名),引用时写<my-component-name>)
Vue.component('my-component-name', { /* ... */ })
a.全局注册:它们在注册之后可以用在任何新创建的 Vue 根实例 (new Vue
) 的模板中,在所有子组件中也是如此
【组件的嵌套:
简单例子(答案中有个简单的例子):https://segmentfault.com/q/1010000009912831/a-1020000009916983
复杂例子(没看,需研究):https://www.cnblogs.com/chengduxiaoc/p/7099552.html】
b.全局注册往往是不够理想的。比如,如果你使用一个像 webpack 这样的构建系统,全局注册所有的组件意味着即便你已经不再使用一个组件了,它仍然会被包含在你最终的构建结果中。这造成了用户下载的 JavaScript 的无谓的增加。
<div id="app">
<component-all></component-all>
<component-a></component-a>
<component-b>组件所夹的内容通过slot插槽显示(组件夹组件的时候需特别注意)</component-b>
<hr>
<component-b>全局注册的组件可以直接被其他组件使用:<component-all></component-all></component-b>
</div>
<script>
//全局注册
Vue.component('component-all', { template: '<h3>Template:</h3>' })
//局部注册
var ComponentA ={
template: '<span>this is A template</span>',
}
var ComponentB ={
template: '<p>this is B template: <slot></slot></p>',
}
//局部注册的组件嵌套
var ComponentAa ={
template: ' <p>this is Aa template: <son-component-a></son-component-a> </p> ',
components: {
'son-component-a': ComponentA
},
}
var app = new Vue({
el: '#app',
//定义想要使用的局部组件
components: {
'component-a': ComponentAa,
'component-b': ComponentB
}
});
</script>
2.props类型:
未指明类型时: props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
指明类型时:props: { title: String, likes: Number, isPublished: Boolean, commentIds: Array, author: Object, callback: Function, contactsPromise: Promise }
3.传递props(常会用)
4.单项数据流
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。
使用父元素传过来的props的方法一般有data(通常是初始化的数据)和computed(涉及计算的数据):
props: ['initialCounter'], data: function () { return { counter: this.initialCounter } }
props: ['size'], computed: { normalizedSize: function () { return this.size.trim().toLowerCase() } }
【注意:JS对象和数组是通过引用传入的,所以在子组件中改变这个对象或数组本身将会影响到父组件的状态。】
5.利用.sync修饰符双向绑定prop:https://cn.vuejs.org/v2/guide/components-custom-events.html#sync-%E4%BF%AE%E9%A5%B0%E7%AC%A6
【这样子组件也可以修改父组件的数据】
6.插槽:<slot>
元素作为承载分发内容的出口
<component-b v-for="post in posts" v-bind:key="post.id" v-bind:post="post" id='slef'>插槽内可以使用{{post.title}}</component-b>
<!-- 插槽可以使用组件内的数据,但是不可以使用类似id这种不传输到组件的数据 -->
插槽后备内容:
模板:<button type="submit"> <slot>Submit</slot> </button>
当父组件 <submit-button></submit-button>时渲染:Submit按钮
当父组件<submit-button> Save </submit-button>时渲染:Save按钮,默认的后备内容会被覆盖
n.未研究的内容:
a.使用了诸如 Babel 和 webpack 的模块系统来管理VUE:https://cn.vuejs.org/v2/guide/components-registration.html#%E6%A8%A1%E5%9D%97%E7%B3%BB%E7%BB%9F
b.JavaScript (字符串模板)与DOM (非字符串的模板):去搜索一下吧
【所以模板有多行的时候需要使用折行转义字符\】
c.prop验证:https://cn.vuejs.org/v2/guide/components-props.html#Prop-%E9%AA%8C%E8%AF%81
原生类型type可以是:String、Number、Boolean、Array、Object、Date、Function、Symbol
d.非prop特性:https://cn.vuejs.org/v2/guide/components-props.html#%E9%9D%9E-Prop-%E7%9A%84%E7%89%B9%E6%80%A7
【vue组件和Bootstrap模板组件混合使用】
e.自定义组件的v-model:https://cn.vuejs.org/v2/guide/components-custom-events.html#%E8%87%AA%E5%AE%9A%E4%B9%89%E7%BB%84%E4%BB%B6%E7%9A%84-v-model
【组件涉及表单的时候再研究】
f.插槽的高级使用-具名插槽和作用域插槽:
https://cn.vuejs.org/v2/guide/components-slots.html#%E5%85%B7%E5%90%8D%E6%8F%92%E6%A7%BD
g.动态组件和异步组件:https://cn.vuejs.org/v2/guide/components-dynamic-async.html
h.组件-处理边界情况:https://cn.vuejs.org/v2/guide/components-edge-cases.html
更多推荐
所有评论(0)