VUEJS学习网址:https://cn.vuejs.org/javascript
此文章是用来记录本身的学习和实践心得。css
看图说话:html
Pass Propsvue
Emit Eventsjava
v-on
绑定监听,触发对应事件;以上为通用语,具体分析react
<v-input label="姓名"></v-input>
<input v-model="msg" /> <v-profile :message="msg"></v-profile>
子组件接收到数据以后想处理一下不当心改了怎么办?git
父组件的数据改变后,子组件的prop会自动更新,可是这个prop的副本不会啊?github
子组件的prop副本改变了想要通知父组件怎么办?web
(添加)父组件的prop改变,可是不想通知子组件怎么办?vue-router
。。。
其实以上???在2.3有了更好的方法,以前的就是看看。
.sync修饰符
***父组件***
<input v-model="msg" />
<v-profile :message.sync="msg"></v-profile>
***子组件***
$.emit('update:message',newValue)
(9-21)补充:注释仍是建议使用data或compute属性,而不是直接修改prop
子组件想要触发父组件能够emit(父组件须要监听才会触发),父组件触发子组件事件呢?
可是!$refs
只在组件渲染完成后才填充,而且它是非响应式的。它仅仅做为一个直接访问子组件的应急方案——应当避免在模版或计算属性中使用 $refs
。
使用空的vue实例做为中央事件总线
var bus = new Vue(); // 触发组件 A 中的事件 bus.$emit('id-selected', 1) // 在组件 B 建立的钩子中监听事件 bus.$on('id-selected', function (id) { // ... })
考虑vuex
(2018-07-28)注意到了$attrs和¥listeners,用于在多层嵌套中交互,见文档
首先,在父组件中给子组件标签中间放置内容是无效的。而后slot出场。
白话版本:
匿名slot:
slot标签存在与子组件template中;
子组件在父组件中使用的时候,子组件标签中的结构会在编译后替换子组件的slot标签;
若是子组件中没有slot,则父组件中子组件标签中的内容会消失;
具名slot:
顾名思义,是具备name属性的slot标签;并有匿名组件的特性(以上);
子组件在父组件中使用的时候,子组件中的结构中会有某些标签拥有slot属性并赋值,这些会在编译后替换子组件的相应slot标签;
一句话解释:主要的内容是写在父组件中的子组件标签中,编译后插入子组件的相应位置
讲真,说到这里我本身都不明白要slot干吗。
官方给了个布局的例子:
<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> <p>主要内容的一个段落。</p> <p>另外一个主要段落。</p> <p slot="footer">这里有一些联系信息</p> </app-layout>
可是好像也没什么好推荐的。(我的见解)
再想一想:
子组件的template中至少有一个slot标签,slot标签中的内容是default content。什么场景能用到呢?我想到了刚刚写的表格数据筛选,当时用的是v-if,v-else。若是改为slot呢。。。想到slot属性值须要动态传餐,原来写在子组件内部的过滤过程要搬出来放到父组件中执行,而后把执行好的数据塞给子组件的prop。。。
再理一次:
我在子组件的template中设置两个slot
<slot name="Data">各类展示数据的结构都放这里</slot>
<slot name="noData">没有相关数据</slot>
父组件中设置
<input v-model="filterData" /> <button v-on:click="filterMethod">筛选</button> <v-table :datas="datas"> <div slot="Data">
...
<div> <v-tabel>
关键就是slot属性动态赋值的问题。。。走不通,脑洞大了按下不说了
做用域插槽
语法:
<template scope="props"> ... </template>
——————这个官网例子我是好半天才明白
<my-awesome-list :items="items"> <!-- 做用域插槽也能够是具名的 --> <template slot="item" scope="props"> <li class="my-fancy-item">{{ props.text }}</li> </template> </my-awesome-list>
以上的template中的props其实和子组件的props属性是相同的,子组件传递了什么prop,它就接收什么,像是下边的传了个text
<ul> <slot name="item" v-for="item in items" :text="item.text"> <!-- 这里写入备用内容 --> </slot> </ul>
我看了很长很长时间,为何要这么拐个弯呢。。。
————一晚上事后—————
这样内容更灵活:数据是相同的(父组件提供数据),子组件负责了循环(添加逻辑),父组件引用子组件时插入的做用域插槽的模板决定了(展现的形式)!这分工!!!点个赞!!!
我修改了一下本身的table而后页面展现了个空白。以后发现问题出在子组件往外传数据的时候变量名不能用"name"。修改掉。2017-07-14:使用index也不行。。。
2017-07-15:在实际使用的时候发现复用性不强。感受父子组件之间声明式props传递数据的方式使加强复用性变得困难。
<component>
元素,动态地绑定到它的 is
特性,咱们让多个组件可使用同一个挂载点,并动态切换:很适用于制做Tab类的效果<component v-bind:is="currentView" :data1="data1" :data2="data2"> <!-- 组件在 vm.currentview 变化时改变! --> </component>
done()
//放到钩子最后,表示执行工做完毕,能够切换组件,配合keep-alive使用,activated钩子只执行一次暂时说到这里,忽然得回头看一下react,没时间了,回头会继续。
以上的满基础的(我是新手),有什么不对的求指出,感谢!!!
添加:
使用全局注册的时候没有问题(框架自行解决)
若是是模块引用(我都是这样的),须要在第一次循环的子组件上声明
beforeCreate: function () { this.$options.components.TreeFolderContents = require('./tree-folder-contents.vue') }
本身模仿的示例
treeFolder
<template>
<ul>
<li v-for="folder in folders">
<span @click="toggle(folder)">folder.name:{{folder.name}}</span>
<tree-folder-content v-if="folder.children"
:children="folder.children"
v-show="folder.show"
/>
</li>
</ul>
</template>
<script>
import treeFolderContent from './treeFolderContent.vue';
export default{
name: "tree-folder",
data(){
return {
expand: false
}
},
components: {
'tree-folder-content': treeFolderContent
},
props: ['folders'],
methods:{
toggle: function(item) {
item.show = !item.show;
}
}
}
</script>
treeFolderContent
<template>
<ul>
<li v-for="child in children">
<span @click="toggle(child)">child.name:{{child.name}}</span>
<TreeFolder v-if="child.children"
:folders="child.children"
v-show="child.show"
/>
</li>
</ul>
</template>
<script>
export default{
name: "tree-folder-content",
beforeCreate(){
this.$options.components.TreeFolder = require('./treeFolder.vue');
},
data(){
return {
expand: false
}
},
props: ['children'],
methods:{
toggle: function(item) {
item.show = !item.show;
}
}
}
</script>
引用方式
<template>
<div class="main">
<div class="content">
<tree-folder :folders="menu"></tree-folder>
</div>
</div>
</template>
<script>
import treeFolder from './../commen/treeFolder.vue'
export default{
name: "nav3",
data(){
return {
menu: [
{
name: 'a一级导航', show: true,
children: [
{name: 'a二级导航', show: false},
{name: 'a二级导航', show: false}
]
},
{
name: 'b一级导航', show: true,
children: [
{name: 'b二级导航', show: false},
{name: 'b二级导航', show: false},
{
name: 'b二级导航', show: false,
children: [
{
name: 'b三级导航', show: false,
children: [
{name: 'b四级导航', show: false,}
]
}
]
},
]
},
{
name: 'c一级导航', show: true,
children: [
{name: 'c二级导航', show: false},
{name: 'c二级导航', show: false},
{
name: 'c二级导航', show: false,
children: [
{name: 'c三级导航', show: false}
]
},
]
}
]
}
},
components: {
'tree-folder': treeFolder
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less" rel="stylesheet/less">
.content {
background: blue;
color: #fff;
}
</style>
小点tip:
v-once
将渲染结果缓存起来;vue1.x版本中有不少系统自带的过滤器,在vue2.x版本中都没有了。
2017-07-15
看图说话:
mounted
不会承诺全部的子组件也都一块儿被挂载。若是你但愿等到整个视图都渲染完毕,能够用 vm.$nextTick 替换掉 mounted。OK,问题解决。DOM展示给用户后,用户操做(v-on)引起data change。可是这时候并非直接操做DOM,而是操做虚拟dom(我的理解:由vue-loader将vue组件文件中的代码解析成了javascript,(render的过程)在用户操做的时候,最早操做这些伪DOM(js操做),而后在re-render成真正的DOM。再此,也总结出vue的一大特色:data和dom并非直接通信,而是经过虚拟dom)。这里又牵扯出了数据驱动。。。看图。。。先看看,等等换成新的关注点吧(>.<)
当这个钩子被调用时,组件 DOM 已经更新,因此你如今能够执行依赖于 DOM 的操做。然而在大多数状况下,你应该避免在此期间更改状态。若是要相应状态改变,一般最好使用计算属性或 watcher 取而代之。(官网原文,我以为记着就好)
该钩子在服务器端渲染期间不被调用。
//用Javascript代码表示DOM节点的伪代码 Let domNode = { tag: 'ul' attributes: { id: 'myId' } children: [ //这里是 li ] };
var loading = document.createElement("div"); loading.style.width = "1000px"; loading.style.height = "1000px"; loading.className = 'loading'; loading.style.backgroundColor = "#000";
数据驱动原理
连接:
2017-07-17
会有 6 个(CSS)类名在 enter/leave 的过渡中切换
v-enter
: 定义进入过渡的开始状态。在元素被插入时生效,在下一个帧移除。
v-enter-active
: 定义过渡的状态。在元素整个过渡过程当中做用,在元素被插入时生效,在 transition/animation
完成以后移除。 这个类能够被用来定义过渡的过程时间,延迟和曲线函数。
v-enter-to
: 2.1.8版及以上 定义进入过渡的结束状态。在元素被插入一帧后生效(于此同时 v-enter
被删除),在 transition/animation
完成以后移除。
v-leave
: 定义离开过渡的开始状态。在离开过渡被触发时生效,在下一个帧移除。
v-leave-active
: 定义过渡的状态。在元素整个过渡过程当中做用,在离开过渡被触发后当即生效,在 transition/animation
完成以后移除。 这个类能够被用来定义过渡的过程时间,延迟和曲线函数。
v-leave-to
: 2.1.8版及以上 定义离开过渡的结束状态。在离开过渡被触发一帧后生效(于此同时 v-leave
被删除),在 transition/animation
完成以后移除。
看概念并不难,直接说我跳过的坑:
css过渡
css动画 顾名思义,是动画 animation 。
搭配animate.css一块儿使用。能够经过如下特性来自定义过渡类名:他们的优先级高于普通的类名
enter-class
enter-active-class
enter-to-class
(>= 2.1.8 only)leave-class
leave-active-class
leave-to-class
(>= 2.1.8 only)event.preventDefault()
或 event.stopPropagation()
是很是常见的需求。尽管咱们能够在 methods 中轻松实现这点,但更好的方式是:methods 只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。(原文)<button v-on:click="warn(' ...', $event)"> Submit </button> ...... methods: { warn: function (message, event) { // 如今咱们能够访问原生事件对象 if (event) event.preventDefault() alert(message) } }
<!-- 阻止单击事件冒泡 --> <a v-on:click.stop="doThis"></a> <!-- 阻止默认事件 --> <form v-on:submit.prevent="onSubmit"></form> <!-- 点击事件将只会触发一次 --> <a v-on:click.once="doThis"></a> <!-- 只有在 keyCode 是 13 时调用 vm.submit() --> <input v-on:keyup.13="submit"> <!-- 同上 --> <input v-on:keyup.enter="submit"> <!-- 缩写语法 --> <input @keyup.enter="submit"> .enter .tab .delete (捕获 “删除” 和 “退格” 键) .esc .space .up .down .left .right 自定义键值修饰符 Vue.config.keyCodes.f1 = 112
鼠标或键盘事件监听
.ctrl
.alt
.shift
.meta
关注点:命名视图
https://jsfiddle.net/posva/6du90epg/
关注点:v-once 与 keep-alive
今天把本身写的心得又读了一遍,对v-once 和keep-alive有点迷惑
v-once只渲染元素和组件一次。随后的从新渲染,元素/组件及其全部的子节点将被视为静态内容并跳过。这能够用于优化更新性能。
keep-alive包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。
今天11月30日,由于一些缘由我有2个月没有注意“vuejs”,就这样它悄悄地改变了。。。
纸上得来终觉浅,但愿有机会去实践。
实践来了。
2018.1.15
工做告一个段落了,使用公司的接口将新的webApp项目改为了vuejs项目。不是每一个页面都从新写了,时间也是不容许的吧。
实现:vue-router,vuex,vue-resourse,selected,下拉加载,输入框和select等。
地址:*********************老大说放公司代码属于侵权。。。
不会再新增关于vue的新随笔,就这一篇,不断的补充,感受也挺好。(我又加了一个关于框架的。。。)
关注点:watch
watch用来监控某个变化的属性,而后执行方法。在我以往的使用中,只有该监控的属性发生变化时才会触发方法。
2018-08-01 在项目中使用vue有半年了,这半年来项目不断,也算是用vue‘摸爬滚打’了,可是总以为浅。想的用的都很表面,只是‘能跑通’罢了。挫败。