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

  • 事件

    • 普通事件

    • 修饰符事件

  • 插槽

    • 普通插槽

    • 作用域插槽

其实上述的均为属性

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,让我来回答你的问题。 Vue 组件 object_vue 源码系列一是关于 Object.defineProperty 的。Object.defineProperty 是 JavaScript 中的一个方法,可以用来定义对象的属性。这个方法可以让我们定义一个新的属性或者修改一个已经存在的属性。这个方法的语法如下: ```javascript Object.defineProperty(obj, prop, descriptor) ``` 其中,obj 是要定义属性的对象,prop 是要定义或修改的属性名,descriptor 是属性的描述符,它是一个对象,可以包含以下属性: - value:属性的值,默认为 undefined。 - writable:属性是否可写,默认为 false。 - enumerable:属性是否可枚举,默认为 false。 - configurable:属性是否可配置,默认为 false。 使用 Object.defineProperty 方法,可以实现一些高级的对象操作,例如: 1. 将一个属性设置为只读,即无法修改。 2. 将一个属性设置为不可枚举,即无法通过 for...in 循环遍历到该属性。 3. 将一个属性设置为不可配置,即无法删除该属性或者修改该属性的描述符。 在 Vue 中,Object.defineProperty 方法被广泛地应用于组件的实现中,例如: 1. 监听数据变化,通过设置 getter 和 setter 方法,实现数据的响应式更新。 2. 实现 computed 计算属性,通过设置 getter 方法,实现计算属性的缓存和响应式更新。 3. 实现 watch 监听器,通过设置 getter 方法,监听数据的变化并触发回调函数。 以上就是我对你提出的问题的回答。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值