vue脚手架页面是怎么生成的? (组件注册,路由插件的使用);
主要涉及的文件:
index.html
index.js
main.js
APP.vue
大致的过程就是:
main.js 通过
import Vue from 'vue'
import App from './App'
import router from './router'
引入主要的文件;并通过下面的代码,初始化 vue 视图,挂载到 index.html 的id = "app" 的节点中(根节点);
new Vue({
el: '#app',
router,
template: '<App/>',
components: { App }
})
router :引用 router 路由插件,它会运行 router文件夹下的 index.js
components: { App } 的意思就是 注册APP.vue 作为子组件;
template: '<App/>' 的意思就是挂在名为App的子组件到 根节点;它其实是重写了 根节点 的所有内容;
'<App/>' 其实是 <App></App> 的缩写;所以template 还可以写成:
template: '<div>文字<App></App></div>',
//这就跟 在普通vue文件中插入 子组件 一样了
这个页面的几个“App ”的依赖关系是:
import App from './App' 引入了 App.vue 组件 (相当于声明并赋值了App变量)
components: { App } 在实例中 注册上面的 App子组件;
template: '<App/>' 使用 这个组件替换实例的根节点内容
index.html部分已经搞定,那么看一下被使用作为的根节点App.vue 文件中发生了什么:
它除了常规的html 和css 代码;还有一句
<router-view/>
//它相当于
<router-view></router-view>
它的意思是说,当前位置 引入 router 路由插件引导的子组件;
最后,看一下router 引入了什么: 那就是router文件夹下 index.js 的内容:
import forms from '@/components/form.vue' // 把form.vue 子组件引入
export default new Router({ //新建路由,并输出
routes: [
{
path: '/', //路由重定向的路径写法
component: forms //组件为forms
}
]
})
可以看到,router 的 index.js 把你编写的子组件 form.vue 作为子组件 并重定向为默认子组件
这样 App.vue 的 <router-view/> 就会找到 form.vue 渲染出来;
组件的定义,注册 与 使用
1,全局组件:
2,局部组件
通过父组件的 components 属性注册;
通俗来说就是 :vue 的文档树 是通过组件的方式组织的; 每个组件可以成为其它组件的子组件(只需要引入);
每个组件都有
template: 组件的html 结构;
components :注册或者定义 该组件的要使用的子组件;
3 组件树实例代码:
效果:
组件的data 为什么 都是这样的方?:
data:function (){
reture {
a:1,
b:2
}
}
因为 当这个组件被引用的时候,我们希望每次引用都是独立的;而不是改变其中一个,全部改变;这样reture 相当于复制的一个新的对象存储数据;
内置组件
component 渲染一个“元组件”为动态组件。依 is 的值,来决定哪个组件被渲染。
<component :is="currentView"></component>
var vm = new Vue({
el: '#example',
data: {
currentView: 'home'
},
components: {
home: { /* ... */ },
posts: { /* ... */ },
archive: { /* ... */ }
}
})
当你同一位置有多个组件切换的时候,可能需要用到 内置组件控制;通过is 绑定 变量z 控制显示哪个变量;
常用场景 tab 切换;
<keep-alive>缓存组件
<keep-alive><my-component/></keep-alive>
通过keep-alive 内置组件 让浏览器 缓存 你的<my-component/>组件
<transition name="fade">
<p v-if="show">hello</p>
</transition>
transition 是过渡动画组件; 例子中 p元素通过 变量 show 控制显示隐藏; 配合自定义的css 动画 fade 显示过渡效果;
过渡动画执行过程 有几个状态,可以通过css 为这些状态自定义样式
.fade-enter-active, .fade-leave-active { //显示和隐藏两个动作的过渡期 透明度都是0.5
transition: opacity .5s
}
.fade-enter, .fade-leave-to /* .fade-leave-active 在低于版本 2.1.8 中 */ {
opacity: 0
} //显示动作开始时 和 隐藏动作结束时 的透明度都是 0;
动画组件还为几个 过渡 提供钩子
<transition @after-enter="transitionComplete"> //在离开动作完成后执行 transitionComplete方法
<div v-show="ok">toggled content</div>
</transition>
除了 after-enter 外还有多个 钩子函数
slot 内容分发组件;
顾名思义 就是通过slot组件去定制 子组件的 某些 需要自定义的显示内容; 这里的内容不只是变量;还包括html;它主要靠 属性 name 去对应 内容
(官方例子)
假定我们有一个 app-layout 组件,它的模板为:
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot>我是默认内容</slot> //当没有传入内容是 ;默认内容会被展示
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
父组件模板:
<app-layout>
<h1 slot="header">这里可能是一个页面标题</h1> //具名slot 会根据名字 找到子组件中对应位置插入
<p>主要内容的一个段落。</p> //不具名的 内容 会替换 子组件中<slot>我是默认内容</slot> 的默认内容
<p>另一个主要段落。</p>
<p slot="footer">这里是一些联系信息</p>
</app-layout>
渲染结果为:
<div class="container">
<header>
<h1>这里可能是一个页面标题</h1>
</header>
<main>
<p>主要内容的一个段落。</p>
<p>另一个主要段落。</p>
</main>
<footer>
<p>这里是一些联系信息</p>
</footer>
</div>
v-bind 与 class 的应用
v-bind简写 为 " : " 用它来绑定元素的 属性; 例如title ,name,class,自定属性等;它绑定 class非常灵活
1. v-bind:class 与 本身的class 不会冲突;
<div class="box" :class="a"></div>
data:function(){
reture {
a: "red"
}
}
//结果是:
<div class="box red"></div>
2. data 可以是对象;value 的bool 值代表是否渲染此class
<div class="box" :class="a"></div>
data:function(){
reture {
a:{
red:true,
bold: true,
padding:false
}
}
}
//结果是:
<div class="box red bold"></div>
3. data 可以是数组;
<div class="box" :class="a"></div>
data:function(){
reture {
a:["red","buld"]
}
}
//结果是:
<div class="box red bold"></div>
4.data 是数组对象的混合
<div class="box" :class="a"></div>
data:function(){
reture {
a:["red",{blue:false,padding:true}]
}
}
//结果是:
<div class="box red padding"></div>
vue 的条件判断
vue 主要通过 v-if 和 v-show ,v-else 控制模板的渲染流程
<div class="box" v-if="a"></div>
<div class="box" v-show="a"></div>
<div class="box2" v-else></div>
他们的区别是: 如果a==false; v-if 是不会渲染 box 的,就是dom中找不到 box;v-show则只会把box 设置为 display:none;
v-else 会对应最近的一个 v-show 或者 v-if 做渲染;它不需要变量;
事件修饰器 实现 按enter 的时候 执行搜索
<input class="box" :keydown.enter = "doSearch">
//或者
<input class="box" :keydown.13 = "doSearch">
自定义事件 ——父子组件的信息传递
子 传给 父
//父组件:
<componentA @myEvent="doSome"></componentA>
compononet
methods:{
doSome (str){
console.log(str)
}
}
//子组件
<template>
<button @click="saySome"></button>
</template>
methods:{
saySome(){
this.$emit("myEvent","123")
}
}
//结果 点击子组件的button 后;输出 123
父 传给 子
//父组件
<h1>我是父亲{{fatherName}}</h1>
<my-child num="10"></my-child>
//或者动态绑定这个值
<my-child :num="fatherName"></my-child>
data:(){
return {
fatherName:"百丽"
}
}
//子组件
"my-child":{
template:"<div class='son'><h3>我是{{num}}儿子</h3><my-child-child></my-child-child></div>",
props:["num"]
}
结果:
或者
props 属性可以写成 对象的形式
props:{
num:["string","Number"] //表示只接受 字符串或者数字类型的值;
}
表单元素的使用
表单的数绑定 用到 v-model
input
<input v-model="a">
<div>{{a}}</div>
data:function(){
reture {
a:""
}
}
// 在输入框中输入值,就会赋值到 变量a 同时 div 的内容也会是a ;
// 数据的回填 只需要给 a 赋值就可以
checBox
<input type="checBox" value="a" v-model="arr">
<input type="checBox" value="b" v-model="arr">
<input type="checBox" value="c" v-model="arr">
<div>{{arr}}</div>
data:function(){
reture {
arr:[]
}
}
// 被选中的 checBox 它的值会被打印 成为arr 的一个元素
// 回填操作;只要给 arr 填入 元素;元素对应的checbox 就会被选中;例如:
data:function(){
reture {
arr:["a"] // value=="a" 的 checBox 会被选中
}
}
select
<select v-model="selection" @change="dod">
<option v-for="item in arr2" :value="item.value">{{item.name}}</option>
</select>
//通过 arr2 渲染出 option;
//这里的 value 前面一定要加 “:” 否则会把item.value当做普通字符串渲染
data:function(){
reture {
arr2:[
{
value:"10",
name:"banana"
},
{
value:"2",
name:"apple"
}
],
selection:null
}
}
methods:{
dod(){
console.log(this.selection)
}
}
// 通过为select 绑定 dod方法和绑定selection值 change事件发生时输出当前选中值;
// 回填,只要给selection 赋值;对应的项就会默认选中
总结:双向绑定自动完成视图更新;改变data 就会有视图结果;回填表单,单选的 回填值是字符串;多选的对应值是数组;
计算属性 与 监听属性
计算属性
<input v-model="d">
{{computerD}}
data:function(){
reture {
d:""
}
}
computed:{
computerD(){
return this.d.replace(/\d/g,'')
}
}
//结果: 在表单输入的值 会被删除数字 剩下文字输出到页面;
监听属性 主要应用于 只要x改变 就做处理 的情况;
<input v-model="d">
{{mode}}
data:function(){
reture {
d:"",
mode:""
}
}
watch:{
d(val,old){
this.mode = "新值:"+val+" 旧值: "+old
}
}
//结果: 每当d 改变时 ;mode 也改变;
自定义指令
vue 通过 directives 自定义指令
<div v-color="red"></div>
directives:{
color:function(el,binging){ //color 对应 v-color 指令; 处理函数有两个参数,el代表绑定的元
el.style.color = binging.value; //素,binging 代表指令的值;
}
}
全局自定义指令 只要 在main.js 中定义指令,这个指令就会被全局使用;本质上就是,在new.Vue() 实例化 vue实例的时候,挂载在根节点 的时候 定义指令 为全局指令;
自定义指令 的分时段执行;
这时 color 的写法会有不同;color 变成了对象;每个时期对应为key,value是fn;
应用场景:表单渲染完成以后,focus 到某个input
<input type="text" v-focus>
directives:{
focus:{
inserted:function(el,binging){ //在插入完成后 执行
el.focus();
}
}
}
vue 插件的安装与使用
插件是什么? 可以理解为 一个功能丰富的vue 组件;
可以在package.json 中找到所有注册的插件
插件安装
在 命令行输入 npm install xxx --save 把插件安装到 项目,并且通过--save 写入到package.json中
这样别人通过 package.json 就可以安装我们的项目依赖插件;
引入到文件
引入到 实例中
引入组件中的 @ 是什么东西
它是一个自定义命令;在webpack 中做了定义,意思是@补充路径为绝对路径;