VUE学习笔记——v-for/组件

零、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

【显示过滤/排序结果:https://cn.vuejs.org/v2/guide/list.html#%E6%98%BE%E7%A4%BA%E8%BF%87%E6%BB%A4-%E6%8E%92%E5%BA%8F%E7%BB%93%E6%9E%9C

【注意:类似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 接收相同的选项,所以也会有 datacomputedwatchmethods 以及生命周期钩子等。仅有的例外是像 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(常会用)

https://cn.vuejs.org/v2/guide/components-props.html#%E4%BC%A0%E9%80%92%E9%9D%99%E6%80%81%E6%88%96%E5%8A%A8%E6%80%81-Prop

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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值