Vue学习与研究
2018-03-15 本文已影响7人
MrSong
title: Vue学习与研究
notebook: 编程
tags: Vue
没办法,必须学点其他的了,好多移动端朋友都向前端靠拢了。还有不少直接转行的,在一棵树上吊死不可行。
Vue 基本语法
- el 绑定标签
- data 绑定数据
- methods 绑定事件,界面刷新一次执行一次
- computed 计算属性,有缓存,数据更改时执行
- catch 监听数据变化 ,newValue 新数据
- filters 过滤属性
<div id="app">
<ul >
<li v-for='item in formatMovie'>{{item}}</li>
</ul>
<button v-on:click='add'>添加电影</button>
</div>
<script>
var vm = new Vue({
// Vue实例绑定的标签
el: '#app',
// 数据绑定
data:{
movies:[
{
name:'捉妖记',
year:'2016'
},
{
name:'黑豹',
year:'2018'
},
{ name:'费事',
year:'2015'
}
]
},
// 监听数据变化 ,newValue 新数据
watch:{
movies:function (newValue) {
console.log(newValue[newValue.length-1].name);
}
},
// 计算属性,与缓存,数据更改是执行
computed:{
formatMovie:function () {
return this.movies.map(function (movie) {
return movie.name+"("+movie.year+")"
})
}
},
// 方法,界面刷新一次执行一次
methods:{
add:function () {
this.movies.push({name:'前任',year:'2055'})
}
}
});
</script>
filters
<div id="app">
<div>{{msg | upper(true)}}</div>
</div>
<script>
var vm = new Vue({
// Vue实例绑定的标签
el: '#app',
// 数据绑定
data:{
msg:'hello world'
},
// 过滤属性
filters:{
upper:function (val,isFirstWord) {
if(isFirstWord) {
return val.charAt(0).toUpperCase() + val.slice(1);
}else {
return val.toUpperCase()
}
}
}
});
</script>
修改样式style
- 修改单个属性
<div style="height:200px;width:200px;" v-bind:style='{backgroundColor:color}'></div>
<script>
var vm = new Vue({
// Vue实例绑定的标签
el: '#app',
// 数据绑定
data:{
color:'red'
},
)}
</script>
- 修改多个属性
<div style="height:200px;width:200px;" v-bind:style='styles'></div>
<script>
var vm = new Vue({
// Vue实例绑定的标签
el: '#app',
// 数据绑定
data:{
styles:{
backgroundColor:'red',
'border-radius':'20px'
}
},
)}
</script>
- 绑定多个style
<div style="height:200px;width:200px;" v-bind:style="[styles1,styles2]"></div>
<script>
var vm = new Vue({
// Vue实例绑定的标签
el: '#app',
// 数据绑定
data:{
color:'yellow'
},
computed:{
styles1:function () {
return {
backgroundColor:this.color
}
},
styles2:function () {
return {
'border-radius':'10px'
}
}
},
methods:{
changeColor:function () {
if (this.backgroundColor ==='yellow') {
this.backgroundColor = 'red'
}else {
this.backgroundColor = 'yellow'
}
}
}
});
</script>
绑定class
- 传递单个Class,使用
{circle:shape.isRound}
<style>
.circle{
background-color:red;
width:30px;
height:30px;
float:left;
margin:10px;
border-radius:15px;
}
.square{
background-color:blue;
width:30px;
height:30px;
float:left;
margin:10px;
/*border-radius:15px;*/
}
.up{
background-color:yellow;
width:30px;
height:30px;
float:left;
margin:10px;
/*border-radius:15px;*/
}
</style>
<div v-for='shape in shapes' class ='shape' v-bind:class='{circle:shape.isRound,square:!shape.isRound}' ></div>
<script>
var vm = new Vue({
// Vue实例绑定的标签
el: '#app',
// 数据绑定
data:{
shapes:[
{isRound:true},
{isRound:false}
],
}
});
</script>
- 传递多个Class,使用数组
[shape.type]
<div v-for='shape in shapes' class ='shape' v-bind:class='[shape.shape]' ></div>
<script>
var vm = new Vue({
// Vue实例绑定的标签
el: '#app',
// 数据绑定
data:{
shapes:[
{shape:'circle'},
{shape:'square'}
],
}
});
</script>
- 带有动画的class
<style>
// 三角形
.triangle{
/*background-color:yellow;*/
width:0;
height:0;
float:left;
}
.up{
border-left: 100px solid transparent;
border-right: 100px solid transparent;
border-bottom: 150px solid red;
/*border-radius:15px;*/
}
.down{
border-left: 100px solid transparent;
border-right: 100px solid transparent;
border-top: 150px solid blue;
/*border-radius:15px;*/
}
.animation{
animation: strentch 1.0s ease-out
}
@keyframes strentch{
0%{
transform: scale(0.4);
}
100%{
transform: scale(1);
}
}
</style>
<div v-for='shape in shapes' class ='shape' v-bind:class="[shape.shape,shape.direction?shape.direction:'',{animation:shape.animation}]" >
</div>
<script>
var vm = new Vue({
// Vue实例绑定的标签
el: '#app',
// 数据绑定
data:{
shapes:[
{shape:'circle',animation:true},
{shape:'square'},
{shape:'triangle',direction:'up'},
{shape:'triangle',direction:'down',animation:true},
],
}
});
</script>
组件
- 注册一个全局组件
<div id="app">
<my-component></my-component>
</div>
</div>
<script>
// 注册一个组件
Vue.component('my-component',{
template:'<div><button>{{count}}</button></div>',
// data 必须写成函数方式
data:function () {
return {count:0}
}
})
var vm = new Vue({
el: '#app'
});
</script>
- 局部组件,在哪里用就在哪里引入
<script>
// 注册一个组件
var component = {
template:'<div><button @click="clickMe">{{count}}</button></div>',
// data 必须写成函数方式
data:function () {
return {count:0}
},
methods:{
clickMe:function () {
this.count ++;
}
}
}
// Vue.component('my-component',component)
var vm = new Vue({
el: '#app',
// 局部组件
components:{
'my-component':component
}
});
</script>
Vue-cli 目录分析
image-
build: 项目构建(webpack)相关代码
-
config: 配置目录
-
node_modules: npm 加载的项目依赖模块
-
src: 这里是我们要开发的目录,基本上要做的事情都在这个目录里。里面包含了几个目录及文件:
- api: 封装工具类,如网络等
- assets: 放置一些图片,如logo等
- businesses: 各模块的js文件(ps:不同模块需要建不同文件夹进行管理)
- components: 目录里面放了一个自定义组件文件,如搜索框等
- less: 共用样式文件
- plugin: 封装的插件
- router: 路由,各个界面的分发
- views: 各界面代码就写在这里(ps:不同模块需要建不同文件夹进行管理)
- App.vue: 项目入口文件
- main.js: 项目的核心文件
-
static: 静态资源目录,如图片、字体等
-
test: 初始测试目录,可删除
-
.xxxx文件: 这些是一些配置文件,包括语法配置,git配置等
-
index.html: 首页入口文件,你可以添加一些 meta 信息或统计代码等
-
package.json: 项目配置文件
-
README.md: 项目的说明文档,markdown 格式
main.js 解惑
new Vue({
router,
render: h => h(App)
}).$mount('#app-box')
-
上面
render: h => h(App)
是个简写 -
来源如下
-
The answer (for anyone else who comes across this), is that render: h => h(App) is shorthand for:
render: function (createElement) {
return createElement(App);
}
- Which can be shortened to:
render (createElement) {
return createElement(App);
}
- Which can again be shortened to (with h being an alias to createElement as noted above):
render (h){
return h(App);
}
- Which is then shortened further to (using ES6 "fat arrow" syntax):
render: h => h(App);
App.vue 分析
// 界面模板,提供给外部使用的
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<script>
// 因为要提供给外部使用,所以要导出
// 可以在这里提供接口给外部使用
export default {
name: 'app'
}
</script>
// 全局样式
<style lang="less">
@import '~vux/src/styles/reset.less';
@import url('./less/common.less');
body {
background-color: #fbf9fe;
}
</style>
// </style scoped> 添加scoped定义样式为局部样式
index.html
- 这是项目入口文件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0">
<title>cid</title>
</head>
<body>
<div id="app-box"></div>
<!-- built files will be auto injected -->
</body>
</html>
package.json
- 这是项目配置文件,里面包含项目版本信息。依赖相关信息。
package-lock.json
- 这个也是配置文件,包含所有的依赖关系
组件传值
- 子组件接受传递过来的数据,接受多个
<template>
<div>
<h2>标题:{{msg}}</h2>
</div>
</template>
<script type="text/javascript">
export default{
props:['msg','name'] // 接受信息,关键字props
// props:{ // 接受信息,关键字props,可以指定类型
// msg:String
// }
// props : { // 接受信息,关键字props,可以指定类型
// msg : {
// type : [String,Number],// 接受多种类型数据
// required : true // 必填
// }
}
}
</script>
<style type="text/css" scoped> // 局部样式
*{
color: red;
}
</style>
- 父组件向子组件传值
<template>
<div id="app-box">
<MyComponent msg='号可怕' name='昵称'></MyComponent>
<div>内容来了</div>
</div>
</template>
- 子组件想父组件传值
<template>
<div>
<button @click = 'clickBtn'>点我点我</button>
</div>
</template>
<script>
export default {
methods : {
clickBtn(){
console.log('clickBtn')
this.$emit('foClick')// 关键是这个地方
// this.$emit('foClick','传递数据到上一级')// 后面的参数传递数据到上一级
}
}
}
</script>
<template>
<div id="app-box">
<div>分享次数:{{count}}</div>
<div>内容来了</div>
<myButton @clickBtn = 'foClick'></myButton>
</div>
</template>
<script>
import Vue from 'vue'
import ButtonComp from './components/ButtonComp'
Vue.component('myButton',ButtonComp)
export default {
data () {
return {
count : 0
}
},
methods : {
foClick () { // 接受子组件的点击事件
this.count ++;
}
}
}
</script>
slot 卡槽
- 在子组件中定义slot可以在使用时替换标签
- 第一种情况下,不管你在标签中间写什么数据都不会显示
- 第二种情况下,添加的数据会自动加载到标签里
// 子组件
<template>
<div>标题:{{msg}}</div> // 1
<!-- <div><slot>标题:{{msg}}</slot></div> // 2-->
</template>
// 父组件
<MyComponent><p>啦啦啦</p></MyComponent> //1
<MyComponent><p>啦啦啦</p></MyComponent> //2
// 结果
<h2 data-v-7920ea77="">标题:哈哈哈哈</h2> // 1
<div data-v-7920ea77=""><p data-v-7920ea77="">啦啦啦</p></div> // 2
- slot 也可以指定名字
// 定义
<template>
<!-- <h2>标题:{{msg}}</h2> -->
<div>
<slot name = 'one'>标题:{{msg}}</slot>
<slot name = 'two'>标题:{{msg}}</slot>
</div>
</template>
// 引用
<MyComponent>
<p slot = 'one'>啦啦啦111</p>
<p slot = 'two'>啦啦啦222</p>
</MyComponent>
Vue错误
- image
-
找不到属性,很有可能是this指向有问题,在函数内部再次调用其他函数时最好不要直接写this
可以考虑下面写法。
methods: {
clickToSearch: function () {
console.log('value' + this.value)
// 模拟查询数据,获取数据后刷新界面
var self = this;
setTimeout(function () {
// 刷新界面
self.datas.push('哈哈哈');
console.log( self.datas)
}, 2000)
}
}