轻量 开启gzip压缩后20kb
渐进式的框架
不需要学习所有就可以应用到项目响应式的更新机制
学习成本低
直接引入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>这样直接使用非常简便的可以实现功能,但是存在缺点
component全局定义
字符串类型的模板,没有语法高亮,而且数据量大的时候看起来杂乱
不支持css样式
只能使用HTML和ES5语法,无法使用预处理器和Babel
工程形式安装
npm install -g @vue/cli脚手架
vue create htllo-word 创建项目
cd hello-word
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
事件
普通事件
修饰符事件
插槽
普通插槽
作用域插槽
其实上述的均为属性
