【一起来烧脑】一步学会Vue.js系统

vue

Vuejs是一个构建数据驱动的web界面的库,通过api实现响应的数据绑定和组合的视图组件,Vue.js的核心是一个响应的数据绑定系统,它让数据与DOM保持同步非常简单,一旦创建了绑定,DOM 将与数据保持同步。


Vue.js 安装

<script> 标签

CDN

NPM

# 最新稳定版本

$ npm install vue

# 最新稳定CSP兼容版本

$ npm install vue@csp

vue.js提供了一个官方命令工具,可以快速搭建大型单页应用。

# 全局安装 vue-cli

$ npm install -g vue-cli

# 创建一个基于 "webpack" 模板的新项目

$ vue init webpack my-project

# 安装依赖

$ cd my-project

$ npm install

$ npm run dev

开发版本

git clone https://github.com/vuejs/vue.git node_modules/vue

cd node_modules/vue

npm install

npm run build

Bower

# 最新稳定版本

$ bower install vue

语法格式如下:

var vm = new Vue({

// 选项

})

<div id="vue_det">

<h1>site : {{site}}</h1>

<h1>url : {{url}}</h1>

<h1>{{details()}}</h1>

</div>

<script type="text/javascript">

var vm = new Vue({

el: \'#vue_det\',

data: {

site: "",

url: "",

alexa: ""

},

methods: {

details: function() {

return this.site + " 程序员";

}

}

})

</script>

Vue构造器中有一个el参数

它是DOM元素中的id

<div id = "vue_det"></div>

<div id="vue_det">

<h1>site : {{site}}</h1>

<h1>url : {{url}}</h1>

<h1>Alexa : {{alexa}}</h1>

</div>

<script type="text/javascript">

// 数据对象

var data = { site: "", url: "", alexa: 10000}

var vm = new Vue({

el: \'#vue_det\',

data: data

})

// 它们引用相同的对象

document.write(vm.a === data.a) // true

document.write("<br>")

// 设置属性也会影响到原始数据

vm.site = "imooc"

document.write(data.site + "<br>") // imooc

// ……反之亦然

data.alexa = 1234

document.write(vm.alexa) // 1234

</script>

Vue 实例

提供了一些有用的实例属性与方法

前缀 $

<div id="vue_det">

<h1>site : {{site}}</h1>

<h1>url : {{url}}</h1>

<h1>Alexa : {{alexa}}</h1>

</div>

<script type="text/javascript">

// 数据对象

var data = { site: "", url: "", alexa: 10000}

var vm = new Vue({

el: \'#vue_det\',

data: data

})

document.write(vm.$data === data) // true

document.write("<br>") // true

document.write(vm.$el === document.getElementById(\'vue_det\')) // true

</script>


目录

[外链图片转存失败(img-jDOJm1Ph-1563338047361)(https://upload-images.jianshu.io/upload_images/11158618-6a1fbaa8fb8a4d59.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)]

模板语法

文本插值

<div id="app">

<p>{{ message }}</p>

</div>

HTML

<div id="app">

<div v-html="message"></div>

</div>

<script>

new Vue({

el: \'#app\',

data: {

message: \'<h1></h1>\'

}

})

</script>

属性

<div id="app">

<label for="r1">修改颜色</label><input type="checkbox" v-model="class1" id="r1">

<br><br>

<div v-bind:class="{\'class1\': class1}">

directiva v-bind:class

</div>

</div>

<script>

new Vue({

el: \'#app\',

data:{

class1: false

}

});

</script>

表达式

<div id="app">

{{5+5}}<br>

{{ ok ? \'YES\' : \'NO\' }}<br>

{{ message.split(\'\').reverse().join(\'\') }}

<div v-bind:id="\'list-\' + id"></div>

</div>

<script>

new Vue({

el: \'#app\',

data: {

ok: true,

message: \'\',

id : 1

}

})

</script>

指令

<div id="app">

<p v-if="seen">现在你看到我了</p>

</div>

<script>

new Vue({

el: \'#app\',

data: {

seen: true

}

})

</script>

参数

<div id="app">

<pre><a v-bind:href="url"></a></pre>

</div>

<script>

new Vue({

el: \'#app\',

data: {

url: \'\'

}

})

</script>

<a v-on:click="doSomething">

修饰符

<form v-on:submit.prevent="onSubmit"></form>

用户输入

<div id="app">

<p>{{ message }}</p>

<input v-model="message">

</div>

<script>

new Vue({

el: \'#app\',

data: {

message: \'imooc\'

}

})

</script>

<div id="app">

<p>{{ message }}</p>

<button v-on:click="reverseMessage">反转字符串</button>

</div>

<script>

new Vue({

el: \'#app\',

data: {

message: \'coding\'

},

methods: {

reverseMessage: function () {

this.message = this.message.split(\'\').reverse().join(\'\')

}

}

})

</script>

过滤器

<!-- 在两个大括号中 -->

{{ message | capitalize }}

<!-- 在 v-bind 指令中 -->

<div v-bind:id="rawId | formatId"></div>

<div id="app">

{{ message | capitalize }}

</div>

<script>

new Vue({

el: \'#app\',

data: {

message: \'coding\'

},

filters: {

capitalize: function (value) {

if (!value) return \'\'

value = value.toString()

return value.charAt(0).toUpperCase() + value.slice(1)

}

}

})

</script>

过滤器可以串联:

{{ message | filterA | filterB }}

过滤器是JavaScript函数,可以接受参数:

{{ message | filterA(\'arg1\', arg2) }}

v-bind 缩写

<!-- 完整语法 -->

<a v-bind:href="url"></a>

<!-- 缩写 -->

<a :href="url"></a>

v-on 缩写

<!-- 完整语法 -->

<a v-on:click="doSomething">

</a><!-- 缩写 -->

<a @click="doSomething"></a>

条件语句

<div id="app">

<p v-if="seen">现在看到了这句话</p>

<template v-if="ok">

<h1></h1>

<p></p>

<p></p>

</template>

</div>

<script>

new Vue({

el: \'#app\',

data: {

seen: true,

ok: true

}

})

</script>

v-else

<div id="app">

<div v-if="Math.random() > 0.7">

Sorry

</div>

<div v-else>

Not sorry

</div>

</div>

<script>

new Vue({

el: \'#app\'

})

</script>

v-else-if

<div id="app">

<div v-if="type === \'A\'">

A </div>

<div v-else-if="type === \'B\'">

B </div>

<div v-else-if="type === \'C\'">

C </div>

<div v-else>

Not A/B/C

</div>

</div>

<script>

new Vue({

el: \'#app\',

data: {

type: \'C\'

}

})

</script>

v-show

<h1 v-show="ok">Hello!</h1>

循环语句

v-for可以绑定数据到数组来渲染一个列表

<div id="app">

<ol>

<li v-for="site in sites">

{{ site.name }}

</li>

</ol>

</div>

<script>

new Vue({

el: \'#app\',

data: {

sites: [

{ name: \'course\' },

{ name: \'class\' },

{ name: \'coding\' }

]

}

})

</script>

v-for可以通过一个对象的属性来迭代数据

<div id="app">

<ul>

<li v-for="value in object">

{{ value }}

</li>

</ul>

</div>

<script>

new Vue({

el: \'#app\',

data: {

object: {

name: \'慕课网\',

url: \'http://www.imooc.com\',

slogan: \'程序员的梦工厂!\'

}

}

})

</script>

v-for也可以循环整数

<div id="app">

<ul>

<li v-for="n in 10">

{{ n }}

</li>

</ul>

</div>

计算属性

<div id="app">

<p>原始字符串: {{ message }}</p>

<p>计算后反转字符串: {{ reversedMessage }}</p>

</div>

<script>

var vm = new Vue({

el: \'#app\',

data: {

message: \'imooc\'

},

computed: {

// 计算属性的 getter

reversedMessage: function () {

// `this` 指向 vm 实例

return this.message.split(\'\').reverse().join(\'\')

}

}

})

</script>

computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值

methods ,在重新渲染的时候,函数总会重新调用执行

var vm = new Vue({

el: \'#app\',

data: {

name: \'\',

url: \'\'

},

computed: {

site: {

// getter

get: function () {

return this.name + \' \' + this.url

},

// setter

set: function (newValue) {

var names = newValue.split(\' \')

this.name = names[0]

this.url = names[names.length - 1]

}

}

}})

// 调用 setter, vm.name 和 vm.url 也会被对应更新

vm.site = \'实战 https:\';

document.write(\'name: \' + vm.name);

document.write(\'<br>\');

document.write(\'url: \' + vm.url);

监听属性

可以通过watch来响应数据的变化

<div id = "computed_props">

千米 : <input type = "text" v-model = "kilometers">

米 : <input type = "text" v-model = "meters">

</div>

<p id="info"></p>

<script type = "text/javascript">

var vm = new Vue({

el: \'#computed_props\',

data: {

kilometers : 0,

meters:0

},

methods: {

},

computed :{

},

watch : {

kilometers:function(val) {

this.kilometers = val;

this.meters = val * 1000;

},

meters : function (val) {

this.kilometers = val/ 1000;

this.meters = val;

}

}

});

// $watch 是一个实例方法

vm.$watch(\'kilometers\', function (newValue, oldValue) {

// 这个回调将在 vm.kilometers 改变后调用

document.getElementById ("info").innerHTML = "修改前的值" + oldValue + ",修改后的值" + newValue;

})

</script>

样式绑定

Class 与 Style 绑定

<div class="static" v-bind:class="{ \'class-a\': isA, \'class-b\': isB }"></div>

data: {

isA: true,

isB: false

}

<div v-bind:class="classObject"></div>

data: {

classObject: {

\'class-a\': true,

\'class-b\': false

}

}

<div v-bind:class="[classA, classB]">

data: {

classA: \'class-a\',

classB: \'class-b\'

}

<div v-bind:class="[classA, isB ? classB : \'\']">

绑定内联样式

<div v-bind:style="{ color: activeColor, fontSize: fontSize + \'px\' }"></div>

data: {

activeColor: \'red\',

fontSize: 30

}

<div v-bind:style="styleObject"></div>

data: {

styleObject: {

color: \'red\',

fontSize: \'13px\'

}

}

<div v-bind:style="[styleObjectA, styleObjectB]">

事件处理器

v-on指令

<div id="app">

<button v-on:click="counter += 1">增加1</button>

<p>这个按钮被点击了 {{ counter }} 次。</p>

</div>

<script>

new Vue({

el: \'#app\',

data: {

counter: 0

}

})

</script>

<div id="app">

<!-- `greet` 是在下面定义的方法名 -->

<button v-on:click="greet">Greet</button>

</div>

<script>

var app = new Vue({

el: \'#app\',

data: {

name: \'Vue.js\'

},

// 在 `methods` 对象中定义方法

methods: {

greet: function (event) {

// `this` 在方法里指当前 Vue 实例

alert(\'Hello \' + this.name + \'!\')

// `event` 是原生 DOM 事件

if (event) {

alert(event.target.tagName)

}

}

}

})

// 也可以用 JavaScript 直接调用方法

app.greet() // -> \'Hello Vue.js!\'

</script>

<div id="app">

<button v-on:click="say(\'hi\')">Say hi</button>

<button v-on:click="say(\'what\')">Say what</button></div>

<script>

new Vue({

el: \'#app\',

methods: {

say: function (message) {

alert(message)

}

}

})

</script>

事件修饰符

<!-- 阻止单击事件冒泡 -->

<a v-on:click.stop="doThis"></a>

<!-- 提交事件不再重载页面 -->

<form v-on:submit.prevent="onSubmit"></form>

<!-- 修饰符可以串联 -->

<a v-on:click.stop.prevent="doThat"></a>

<!-- 只有修饰符 -->

<form v-on:submit.prevent></form>

<!-- 添加事件侦听器时使用事件捕获模式 -->

<div v-on:click.capture="doThis">...</div>

<!-- 只当事件在该元素本身(而不是子元素)触发时触发回调 -->

<div v-on:click.self="doThat">...</div>

<!-- click 事件只能点击一次,2.1.4版本新增 -->

<a v-on:click.once="doThis"></a>

按键修饰符

<!-- 只有在 keyCode 是 13 时调用 vm.submit() -->

<input v-on:keyup.enter="submit">

<!-- 缩写语法 -->

<input @keyup.enter="submit">

按键别名:

.enter、.tab、.delate、.esc、.space、.up、.down、.left、.right、.ctrl、.alt、.shift、.meta

表单

<div id="app">

<p>input 元素:</p>

<input v-model="message" placeholder="编辑这里">

<p>消息是: {{ message }}</p>

<p>textarea 元素:</p>

<p style="white-space: pre">{{ message2 }}</p>

<textarea v-model="message2" placeholder="多行文本输入"></textarea>

</div>

<script>

new Vue({

el: \'#app\',

data: {

message: \'\',

message2: \'\'

}

})

</script>

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title></title>

<script src="https://cdn.bootcss.com/vue/2.2.2/vue.min.js"></script>

</head>

<body>

<div id="app">

<select v-model="selected" name="fruit">

<option value="">选择一个网站</option>

<option value=""></option>

<option value=""></option>

</select>

<div id="output">

选择的网站是: {{selected}}

</div>

</div>

<script>

new Vue({

el: \'#app\',

data: {

selected: \'\'

}

})

</script>

</body>

</html>

<div id="app">

<input type="radio" id="" value="" v-model="picked">

<label for=""></label>

<br>

<input type="radio" id="" value="" v-model="picked">

<label for=""></label>

<br>

<span>选中值为: {{ picked }}</span></div>

<script>

new Vue({

el: \'#app\',

data: {

picked : \'coding\'

}

})

</script>

<div id="app">

<p>单个复选框:</p>

<input type="checkbox" id="checkbox" v-model="checked">

<label for="checkbox">{{ checked }}</label>

<p>多个复选框:</p>

<input type="checkbox" id="course" value="course" v-model="checkedNames">

<label for="course">course</label>

<input type="checkbox" id="class" value="class" v-model="checkedNames">

<label for="class">class</label>

<input type="checkbox" id="coding" value="coding" v-model="checkedNames">

<label for="coding">coding</label>

<br>

<span>选择的值为: {{ checkedNames }}</span></div>

<script>new Vue({

el: \'#app\',

data: {

checked : false,

checkedNames: []

}

})

</script>

过渡

<div v-if="show" transition="my-transition"></div>

组件

封装可重用的代码

注册一个全局组件语法格式如下:

Vue.component(tagName, options)

tagName 为组件名,options 为配置选项

<tagName></tagName>

全局组件

所有的实例都能用全局组件

<div id="app">

<w></w>

</div>

<script>

// 注册

Vue.component(\'w\', {

template: \'<h1>自定义组件!</h1>\'

})

// 创建根实例

new Vue({

el: \'#app\'

})

</script>

局部组件

<div id="app">

<w></w>

</div>

<script>

var Child = {

template: \'<h1>自定义组件!</h1>\'

}

// 创建根实例

new Vue({

el: \'#app\',

components: {

// <> 将只在父模板可用

\'w\': Child

}

})

</script>

Prop

Prop是父组件用来传递数据的一个自定义属性

父组件的数据需要通过props把数据传给子组件

子组件需要显式的用props选项声明prop

<div id="app">

<child message="hello!"></child>

</div>

<script>

// 注册

Vue.component(\'child\', {

// 声明 props

props: [\'message\'],

// 同样也可以在 vm 实例中像 "this.message" 这样使用

template: \'<span>{{ message }}</span>\'

})

// 创建根实例

new Vue({

el: \'#app\'

})

</script>

动态prop

<div id="app">

<div>

<input v-model="parentMsg">

<br>

<child v-bind:message="parentMsg"></child>

</div>

</div>

<script>

// 注册

Vue.component(\'child\', {

// 声明 props

props: [\'message\'],

// 同样也可以在 vm 实例中像 "this.message" 这样使用

template: \'<span>{{ message }}</span>\'

})

// 创建根实例

new Vue({

el: \'#app\',

data: {

parentMsg: \'父组件内容\'

}

})

</script>

<div id="app">

<ol>

<todo-item v-for="item in sites" v-bind:todo="item"></todo-item>

</ol>

</div>

<script>

Vue.component(\'todo-item\', {

props: [\'todo\'],

template: \'<li>{{ todo.text }}</li>\'

})

new Vue({

el: \'#app\',

data: {

sites: [

{ text: \'course\' },

{ text: \'class\' },

{ text: \'coding\' }

]

}

})

</script>

<div id="app">

<ol>

<todo-item v-for="item in sites" v-bind:todo="item"></todo-item>

</ol>

</div>

<script>

Vue.component(\'todo-item\', {

props: [\'todo\'],

template: \'<li>{{ todo.text }}</li>\'

})

new Vue({

el: \'#app\',

data: {

sites: [

{ text: \'course\' },

{ text: \'class\' },

{ text: \'coding\' }

]

}

})

</script>

prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来

type可以是下面几种原生构造器:

String、Number、Boolean、Function、Object、Array

自定义指令

bind:只调用一次

unbind:只调用一次,在指令从元素上解绑时调用

Vue.directive(id, definition) 方法注册一个全局自定义指令

Vue.directive(\'my-directive\', {

bind: function () {

// 准备工作

// 例如,添加事件处理器或只需要运行一次的高耗任务

},

update: function (newValue, oldValue) {

// 值更新时的工作

// 也会以初始值为参数调用一次

},

unbind: function () {

// 清理工作

// 例如,删除 bind() 添加的事件监听器

}

})

<div v-my-directive="someValue"></div>

Vue.directive(\'my-directive\', function (value) {

// 这个函数用作 update()

})

自定义过滤器

Vue.filter()注册一个自定义过滤器

Vue.filter(\'reverse\', function (value) { 

return value.split(\'\').reverse().join(\'\')

})

Vue.js允许通过简单的方法来自定义过滤器,即,利用管道“|”来完成过滤

混合

分布复用功能

// 定义一个混合对象

var myMixin = {

created: function () {

this.hello()

},

methods: {

hello: function () {

console.log(\'hello from mixin!\')

}

}

}

// 定义一个组件,使用这个混合对象

var Component = Vue.extend({

mixins: [myMixin]

})

var component = new Component() // -> "hello from mixin!"

插件

install

第一个参数是 Vue 构造器

一个可选的选项对象

MyPlugin.install = function (Vue, options) {  

// 1. 添加全局方法或属性

Vue.myGlobalMethod = ...

// 2. 添加全局资源

Vue.directive(\'my-directive\', {})

// 3. 添加实例方法

Vue.prototype.$myMethod = ...

}

Vue.use()全局方法使用插件:

// 调用 `MyPlugin.install(Vue)`

Vue.use(MyPlugin)

也可以传入一个选项对象:

Vue.use(MyPlugin, { someOption: true })

// 通过 Browserify 或 Webpack 使用 CommonJS 兼容模块

var Vue = require(\'vue\')

var VueRouter = require(\'vue-router\')

// 不要忘了调用此方法

Vue.use(VueRouter)

路由

通过不同的HRL访问不同的内容

Vue.js路由需要载入vue-router库

CDN

https://unpkg.com/vue-router/dist/vue-router.js

Vue.js + vue-router 可以很简单的实现单页应用

<script src="https://unpkg.com/vue/dist/vue.js"></script>

<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

<div id="app">

<h1>Hello App!</h1>

<p>

<!-- 使用 router-link 组件来导航. -->

<!-- 通过传入 `to` 属性指定链接. -->

<!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->

<router-link to="/foo">Go to Foo</router-link>

<router-link to="/bar">Go to Bar</router-link>

</p>

<!-- 路由出口 -->

<!-- 路由匹配到的组件将渲染在这里 -->

<router-view></router-view>

</div>


请点赞!因为你们的赞同/鼓励是我写作的最大动力!

欢迎关注达叔小生的简书!

这是一个有质量,有态度的博客

[外链图片转存失败(img-BroAgdip-1563338047364)(https://upload-images.jianshu.io/upload_images/11158618-9ab0d3fef85d80ce?imageMogr2/auto-orient/strip|imageView2/2/w/1240)]

以上是 【一起来烧脑】一步学会Vue.js系统 的全部内容, 来源链接: utcz.com/z/375184.html

回到顶部