Vue.js的学习、安装、基础语法

1、基于MV*模式的框架

(1)Model绑定View

(2)没有控制器

(3)数据驱动,状态管理


2、核心思想

(1)数据驱动:非直接操作节点,是通过变量绑定数据

(2)组件化:抽离公用的代码,形成一个个组件

通过MVVM的数据绑定实现自动同步


(3)模拟双向绑定

<input type="text" name="" id="username" />
	<span id="uName"></span>

	<script type="text/javascript">
		var obj = {};
		// 三个参数:1、对象名 2、对象的要定义或修改属性 3、对定义或修改的属性描述
		Object.defineProperty(obj, "username", {
			get: function() {   // 获取该对象属性时执行
				console.log("get init");
			},
			set: function(val) {   // 设置该对象属性时执行
				document.getElementById("uName").innerHTML = val;
				document.getElementById("username").value = val;
			}
		});
		document.getElementById("username").addEventListener("keyup", function(event) {
				obj.username = event.target.value;
		});
	</script>

(4)单文件组件,一个文件由html、js、css组成

<template>                先是template
  <div id="app">
    <img src="./assets/logo.png">
    <router-view/>
  </div>
</template>

<script>                  这里是js
export default {
  name: 'App'
}
</script>

<style>                    最后是css, 若写成<style scoped>是确认当前作用域,不会污染别的文件
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

3、安装

这里使用npm安装(使用git-bash命令行)

(1)安装node.js

(2)npm官方镜像比较慢,这里使用淘宝NPM镜像

$ npm install -g cnpm --registry=https://registry.npm.taobao.org

(3)安装vue

$ cnpm install vue

(4)全局安装vue-cli

  · 成熟的vue项目架构设计

  · 本地测试服务器

  · 集成打包上线方案

lenovo@DESKTOP-NL309GS MINGW64 /e/workspace/xampp/htdocs/demo
$ cnpm install -g vue-cli          安装vue-cli
lenovo@DESKTOP-NL309GS MINGW64 /e/workspace/xampp/htdocs/demo
$ vue init webpack mall            初始化项目

? Project name (mall) mall
? Project name mall
? Project description (A Vue.js project) mall system
? Project description mall system
? Author snow-small
? Author snow-small
? Vue build standalone
? Install vue-router? (Y/n) Y
? Install vue-router? Yes
? Use ESLint to lint your code? (Y/n) n
? Use ESLint to lint your code? No
? Set up unit tests (Y/n) n
? Set up unit tests No
? Setup e2e tests with Nightwatch? (Y/n) n
? Setup e2e tests with Nightwatch? No
? Should we run `npm install` for you after the project has been created? (reco
? Should we run `npm install` for you after the project has been created? (reco
mmended) no

   vue-cli · Generated "mall".

# Project initialization finished!
# ========================

To get started:

  cd mall
  npm install (or if using yarn: yarn)
  npm run dev

Documentation can be found at https://vuejs-templates.github.io/webpack

(5)进入项目,安装依赖

lenovo@DESKTOP-NL309GS MINGW64 /e/workspace/xampp/htdocs/demo
$ cd ./mall

lenovo@DESKTOP-NL309GS MINGW64 /e/workspace/xampp/htdocs/demo/mall
$ cnpm install

(6)运行

lenovo@DESKTOP-NL309GS MINGW64 /e/workspace/xampp/htdocs/demo/mall
$ cnpm run dev      在localhost启动测试服务器
$ cnpm run build    生成上线目录(部署)

(7)成功显示

> [email protected] dev E:\workspace\xampp\htdocs\demo\mall
> webpack-dev-server --inline --progress --config build/webpack.dev.conf.js

 95% emitting DONE  Compiled successfully in 3970ms20:07:53

 I  Your application is running here: http://localhost:8080

4、基础语法

(1)模板语法:

  · Mustache语法: {{ msg }}

  · Html赋值:v-html = ""

  · 绑定属性:v-bind:id = ""

  · 使用表达式:{{ ok ? "YES", "NO"}}

  · 文本赋值:v-text = ""

  · 指令:v-if = ""

  · 过滤器:{{ message | caputalize}}和v-bind:id = "rawId|formatId"

(2)Class和Style绑定

v-bind:可以省略成:

  · 对象语法:v-bind:class = "{active:isActive, 'text-danger':hasError}"

isActive==true时,显示active

  · 数组语法:

<div v-bind:class="activeClass, errorClass">

    data: {

            activeClass: active,

            errorClass: text-danger

    }

  · style绑定对象语法:v-bind:style="{ color: activeColor, fontSie:fontSize + 'px'}"

<div :style="links"></div>

data: {
    links: {
        font-size: 12px,
        color: #fff
    }
}

(3)条件渲染: 

  · v-if

<a v-if="true"></a>     

  · v-else

<a v-if="true">aaa</a>     if显示的时候,else不显示,
<a v-else>bbb</a>

  · v-else-if

  · v-show

<a v-show="true"></a>      区别是show是display=block

  · v-clock 如果页面刷新太快,未加载出来的地方会同步隐藏相关的代码

(4)vue事件处理器

  · v-on:click="greet"或@click="greet"

  · v-on:click.stop  v-on:click.stop.prevent v-on:click.self v-on:click.once 

  · v-on:keyup:enter/esc/tab

(5)实例对象

new Vue({
			el: '#app',   挂载的对象
			template: '<div>{{ fruit }}</div>',   使用的模板
			data: {
				fruit: 'apple'             绑定的数据
			}
		});

(6)组件

    · 全局组件

<div id="app">
		<my-header></my-header>
		{{ test }}
	</div>

	<script type="text/javascript">
		Vue.component('my-header', {
			template: '<p>this is a my-header(全局组件)</p>'
		});
		new Vue({
			el: '#app',
			data: {
				test: 'this is a apple'
			}
		});
	</script>

· 局部组件

<div id="app">
		<my-header></my-header>
		{{ test }}
	</div>

	<script type="text/javascript">
		var myHeader = {
			template: '<p>this is a my-header(局部组件)</p>'
		};
		new Vue({
			el: '#app',
			data: {
				test: 'this is a apple'
			},
			components: {
				'my-header': myHeader
			}
		});
	</script>

当组件名为驼峰时myHeaderAbCd,在<template>里使用的时候:vue1时,要写成<my-header-ab-cd></my-header-ab-cd>,大写要分开;在vue2时,可以写成<myHeaderAbCd></myHeaderAbCd>

  · 组件之间的通信

父组件向子组件传递时

<comA number-to-do=11></comA>                         父组件,属性大小写不敏感,要用-,值都是string

import comA from './components/a'
components: {
    comA: comA
}

在./components/a中的实例选项中                   子组件要得到父组件的属性,需要使用props,使用时要转成驼峰形式{{ numberToDo }}
props: ['number-to-do']
或props: {

'number-to-do': [Number, String] 传对象,支持数字、字符型

}

子组件向父组件传递,通过事件传递

在./components/a中
<button @click="emitMyEvent"></button>

methods: {
    emitMyEvent () {
        this.$emit('my-event', 'this is components a')      在子组件中触发事件,通过$emit触发父组件中的自定义事件,并传参数
    }
}

在父组件中
<comA @my-event="getMyEvent"></comA>                        父组件中自定义事件,大小写不敏感

methods: {
    getMyEvent (params) {                                   参数值为子组件传来的值,== i get a event this is components a
        console.log('i get a event' + params)
    }
}

父组件向子组件传递模板

在父组件中
<comA>
    <p>11111</p><span>2222</span>
</comA>

在子组件中
<slot></slot>            使用<slot></slot>来接收,父组件的模板 == <p>111</p><span>2222</span>

有具名的slot

子组件
<slot name="header">no header</slot>          有具体名称,值默认为no header
<slot name="footer">no footer</slot>

父组件
<comA>
    <p slot="header">xxxx header</p>          使用slot="具体名称"来确认不同的slot
    <p slot="footer">xxxx footer</p>
</comA>

(7)v-for使用

数组:

<div id="app">
		<p v-for="item in list">{{ item.name }} - {{ item.price }}</p>
	</div>

	<script type="text/javascript">
		new Vue({
			el: '#app',
			data: {
				list: [
					{
						name: 'apple',
						price: 23
					},
					{
						name: 'banana',
						price: 24
					}
				]
			}
		});
	</script>

若是要有序号,在v-for="(item, index) in list",使用时{{ index }}从0开始的序号

对象:

<div id="app">
		<p v-for="(value, key) in objList">{{ value }} - {{ key }}</p>
	</div>

	<script type="text/javascript">
		new Vue({
			el: '#app',
			data: {
				objList: {
					name: 'apple',
					price: 22,
					weight: 20
				}
			}
		});
	</script>

列表更新:

methods: {
				change() {
					Vue.set(this.list, 1, {   第一项要改变的列表,第二项第几个数据,三为改变后的值
						name: 'orange',
						price: 20
					})
				}
			}

(8)表单绑定

<input type="text" v-model="myValue">
<input type="checkbox" v-model="box" value="apple">      复选框
<input type="checkbox" v-model="box" value="banana">
<input type="checkbox" v-model="box" value="orange">
{{ box }}

data: {
    box: []
}
<input type="radio" v-model="box" value="apple">        单选按钮
<input type="radio" v-model="box" value="banana">
<input type="radio" v-model="box" value="orange">
{{ box }}
<select v-model="section">
	<option value="1">1</option>
	<option value="2">2</option>
</select>
{{ section }}

data: {
    section: null }

v-model.lazy:延迟

v-model.number:整形

v-model.trim:去空格

(9)计算属性

<div id="app">
		<input type="text" v-model="myValue">
		{{ inputWithoutNumber }}
	</div>

	<script type="text/javascript">
		new Vue({
			el: '#app',
			data: {
				myValue: '',
			},
			computed: {
				inputWithoutNumber () {
					return this.myValue.replace(/\d/g, '');       去掉数字
				}
			}
		});
	</script>

(10)属性监听

<div id="app">
	<input type="text" v-model="myValue">	
</div>

<script type="text/javascript">
	new Vue({
		el: '#app',
		data: {
			myValue: '',
		},
		watch: {
			myValue (newValue, oldValue) {     监听myValue
				console.log(newValue, oldValue);
			}
		}
	});
</script>

(11)css3过渡动画


<div id="app">
		<button @click="show = !show">toggle</button>
		<transition name="fade">                            通过transition,name随便取
			<p v-show="show">i am show</p>
		</transition>
	</div>


	<script type="text/javascript">
		new Vue({
			el: '#app',
			data: {
				show: true
			}
		});
	</script>

	<style type="text/css">
		.fade-enter-active, .fade-leave-active {           v-enter...中的v是上面的name
			transition: opacity .5s;
		}
		.fade.enter, .fade-leave-active {
			opacity: 0;
		}
	</style>

对于多元素动画,<transition mode="out-in">模式是先出后进,默认先进后出,

若多元素标签相同,如<p key="1">i am one</p>  <p key="2">i am two</p>,实现一个进一个出,不加key区别的话,不会有动画

(12)js实现动画

<div id="app">
		<button @click="show = !show">toggle</button>
		<transition 
		@before-enter="beforeEnter"                             
		@enter="enter" 
		@leave="leave" 
		:css="false" >                                        清除css的影响
			<p class="animate-p" v-show="show">i am show</p>
		</transition>
	</div>


	<script type="text/javascript">
		new Vue({
			el: '#app',
			data: {
				show: true
			},
			methods: {
				beforeEnter (el) {
					$(el).css({
						left: '-500px',
						opacity: 0
					})
				},
				enter (el, done) {
					$(el).animate({
						left: 0,
						opacity: 1
					}, {
						duration: 1500,
						complete: done            一定要有done
					})
				},
				leave (el, done) {
					$(el).animate({
						left: '500px',
						opacity: 0
					}, {
						duration: 1500,
						complete: done
					})
				}
			}
		});
	</script>

	<style type="text/css">
		.animate-p {
			position: absolute;
			left: 0;
		}
	</style>

(13)自定义指令

<div id="app">
		<p v-color="'red'">this is v-color</p>      v-color是自定义指令
	</div>

	<script type="text/javascript">
		new Vue({
			el: '#app',
			directives: {                       定义
				color (el, binding) {       当前的元素,绑定的值
					el.style.color = binding.value
				}
			}
		});
	</script>



 
 
 

猜你喜欢

转载自blog.csdn.net/snow_small/article/details/79346820