Vue学习一《基础:属性,事件,插槽》

VUE的简介

特点

  1. 轻量 开启gzip压缩后20kb

  2. 渐进式的框架

    1. 不需要学习所有就可以应用到项目
  3. 响应式的更新机制

  4. 学习成本低

开发环境的搭建

  1. 直接引入CDN

    <!DOCTYPE html>
    <html lang="zh-hans">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    
    <body>
        <div id="app">{{message}}
            <blog-post v-for="(item, index) in groceryList" :key="item.id" :todo="item"></blog-post>
        </div>
    
        <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
        <script>
            Vue.component('blog-post', {
                // 在 JavaScript 中是 camelCase 的
                props: ['todo'],
                template: '<li>{{ todo.text }}</li>'
            })
            var app = new Vue({
                el: '#app',
                data() {
                    return {
                        message: 'hello Vue',
                        groceryList: [
                            { id: 0, text: '苹果' },
                            { id: 1, text: '香蕉' },
                            { id: 2, text: '桔子' }
                        ],
                    }
                },
            })
        </script>
    </body>
    
    </html>
    

    这样直接使用非常简便的可以实现功能,但是存在缺点

    1. component全局定义

    2. 字符串类型的模板,没有语法高亮,而且数据量大的时候看起来杂乱

    3. 不支持css样式

    4. 只能使用HTML和ES5语法,无法使用预处理器和Babel

  2. 工程形式安装

    1. npm install -g @vue/cli脚手架

    2. vue create htllo-word 创建项目

    3. cd hello-word

    4. npm run server 启动脚手架项目

      # 一般因为网络问题需要切换npm源进行安装
      npm install nrm -g --save 
      nrm ls # 查看源列表
      nrm current # 查看当前源
      nrm use xxx # 使用某个源
      nrm add name http:/xxx/xxx/xxx # 添加自定义源到列表
      nrm del name # 删除某个源
      

组件化的开发

vue组件 = vue实例 = new Vue(options)

组件的三大核心概念

  • 属性

  • 事件

  • 插槽

属性

  • 自定义属性 props 在props中声明的属性

  • 原生属性 attrs 没有声明的属性,默认自动挂载在组件根元素上,设置inheritAttrs为false可关闭自动挂载

  • 特殊属性 class , style 挂载到根组件上,支持字符串,对象,数组等多种数据类型

自定义属性

简写:

props=['name','xxx','aaa']不推荐,后期维护困难

常用的书写方式:

<script>
export default {
  name: "PropsDemo",
  props: {
    name: String,
    taype: {
      validator: function(params) {
        return ["success", "warning", "danger"].includes(params);
      }
    },
    list: {
      type: Array,
      default: () => []
    },
    isVisble: {
      type: Boolean,
      default: false
    },
    onChange: {
      type: Function,
      default: () => {}
    }
  },
  methods: {}
};
</script>

使用方式

<PropsDemo name="hello" :type="type" :is-visible="false" :on-change="handlePropChange" title="属性Demo" class="test1" :class="['test2']" :stype="{marginTop:'20px'}" style="margin-top:10px"></PropsDemo>

事件

  • 普通事件

    • @click
      @input
      @change
      @xxx
      通过this.$emit('xxx',...)触发
      
  • 修饰符事件

    • @input.trim
      @click.stop
      @submit.prevent等
      一般用于原生HTML元素,自定义组件需要自行开发支持
      

例如:使用"$emit"来触发事件,改变字体大小

// main.js
// 创建vue主节点
import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')
//主节点App.vue
<template>
  <div id="app">
    <div :style="{fontSize:articleFontSize+'em'}">
      <article-demo
        v-on:changeFont="changeSize"
        v-for="(item, index) in article"
        :key="index"
        :article="item.body"
      />
    </div>
  </div>
</template>

<script>
import ArticleDemo from "./components/ArticleDemo.vue";
export default {
  name: "app",
  components: {
    ArticleDemo
  },
  data() {
    return {
      article: [
        { id: 1, body: { title: "t1", con: "c1" } },
        { id: 2, body: { title: "t2", con: "c2" } },
        { id: 3, body: { title: "t3", con: "c3" } }
      ],
      articleFontSize: 1
    };
  },
  methods: {
    changeSize(size) {
      this.articleFontSize += size;
    }
  }
};
</script>

<style>
</style>
//主节点同级别的components目录下的ArticleDemo.vue
<template>
  <div>
    <h3>{{article.title}}</h3>
    <button @click="$emit('changeFont',+0.1)">放大字体</button>
    <button @click="$emit('changeFont',-0.1)">减小字体</button>
    <div v-html="article.con"></div>
  </div>
</template>
<script>
export default {
  name: "ArticleDemo",
  props: {
    article: Object
  },
  methods: {}
};
</script>

当单击按钮的时候触发名字为changeFont的事件,而且传递参数

changeFont事件绑定在根节点下的<article-demo/>上,形式为:v-on:changeFont="changeSize",其实它指向的为根节点定义的changeSize方法

//changeSize方法
methods: {
 changeSize(size) {
 this.articleFontSize += size;
 }
 }

这个方法接收一个参数,也就是$emit触发的时候传递的参数,结果为对根组件的articleFontSize数据进行改变,然而,这个数据绑定着:style="{fontSize:articleFontSize+'em'}",所以字体大小也随着改变了

这样子组件中的按钮就可以触发父组件的方法,而且通过父组件的方法改变父组件的数据,实现数据的传递

例子二:通过emit实现子组件和父组件的数据传递

#component
<template>
  <div>
    <input :value="value" v-on:input="$emit('input',$event.target.value)" type="text">
    <p>子组件:{{value}}</p>
  </div>
</template>
<script>
export default {
  name: "EventBindData",
  props: {
    value: String
  }
};
</script>

子组件接收父组件传递来的value

子组件的input触发父组件的input方法,并且将事件的回调值作为参数抛出

# 父节点
<template>
  <div id="app">
    <div>
      <event-bind-data :value="searchText" v-on:input="searchText=$event"/>
      <label for>父组件:{{searchText}}</label>
    </div>
  </div>
</template>

<script>
import EventBindData from "./components/EventBindData.vue";
export default {
  name: "app",
  components: {
 
    EventBindData
  },
  data() {
    return {
      searchText: "xxxxxxx"
    };
  },
 
</script>

<style>
</style>

父节点定义searchText: "xxxxxxx"并将其传递给子节点

<event-bind-data :value="searchText" v-on:input="searchText=$event"/>
<label for>父组件:{{searchText}}</label>

插槽

  • 普通插槽

    • <template solt="xxx"></template>

    • <template v-slot:xxx></template>

  • 作用域插槽

    • <template slot='xxx' slot-scope='props'></template>

    • <template v-solt:xxx='props'></template>

插槽使得定义的组件中可以插入需要的内容

例如:定义组件的时候开启插槽

# component
<template>
  <div>
    <strong>Error!</strong>
    <slot></slot>
  </div>
</template>
<script>
export default {
  name: "ChaCaoDemo"
};
</script>

#App.vue
<template>
  <div id="app">
    <cha-cao-demo>我在这里插入数据</cha-cao-demo>
  </div>
</template>

<script>
import ChaCaoDemo from "./components/ChaCaoDemo.vue";
export default {
  name: "app",
  components: {
    ChaCaoDemo
  },
</script>

<style>
</style>

插槽允许组件可以在定义插槽的位置插入其他元素,甚至是其他组件

例如定义了个名字为simple的组件且开启插槽

那么在使用这个组件的时候

  • <simple>哈哈哈</simple>插入文字

  • <simple><p>哈哈哈</p></simple>插入其他html元素

  • <simple><component/></simple>插入其他组件

一个组件中可以定义多个插槽,给每个插槽可以命名

例如定义为main-body的组件

<template>
<div>
    <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot name="main"></slot>

  </main>
  <footer>
    <slot name="footer"></slot>
</div>
</template>

使用的时候

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

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

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

万物皆属性

element

  • 属性

    • 自定义属性props

    • 原生属性attrs

    • 特殊性属性class style

  • 事件

    • 普通事件

    • 修饰符事件

  • 插槽

    • 普通插槽

    • 作用域插槽

其实上述的均为属性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值