组件
组件注册
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="vm">
<my-com></my-com>
<my-com2></my-com2>
<my-com3></my-com3>
<my-com4></my-com4>
<login></login>
</div>
<template id="temp1">
<h4>
通过template元素在外部定义组件结构,会有代码提示和高亮
</4>
</template>
<template id="temp2">
<h5>
私有组件注册
</h5>
</template>
</body>
<script>
var com = Vue.extend({
// 通过这个属性指定组件要展示的HTML结构
template: '<h3>全局注册组件方式一</h3>'
})
Vue.component('myCom', com)
Vue.component('myCom2', Vue.extend({
template: '<h2>全局注册组件方式二</h2>'
}))
Vue.component('myCom3', {
template: '<h1>全局注册组件方式三</h1>'
})
Vue.component('myCom4', {
template: '#temp1'
})
new Vue({
el: '#vm',
components: {
// 这里的组件只有在该vm实例中有效
login: {
template: '#temp2'
}
}
})
</script>
</html>
运行结果
image
全局组件
示例代码如下
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>全局组件入门</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<button-counter></button-counter>
</div>
</body>
<script>
// 注册一个名为button-counter的全局组件
Vue.component('button-counter', {
data: function() {
return {
count: '全局组件'
}
},
template: '<h3>{{count}}</h3>'
})
new Vue({
el: '#app'
})
</script>
</html>
运行结果
image
之组件中的data
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="vm">
<my-com3></my-com3>
</div>
</body>
<script>
Vue.component('myCom3', {
template: '<h1>{{msg}}</h1>',
data:function(){
return {
msg:'组件中的data必须为一个方法且返回一个对象,当中的数据使用方式完全和实例中的data的使用方式一样'
}
}
})
new Vue({
el: '#vm'
})
</script>
</html>
运行结果
image
组件切换
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="vm">
<a href="" @click.prevent="flag=true">登录</a>
<a href="" @click.prevent="flag=false">注册</a>
<login v-if="flag"></login>
<register v-else="flag"></register>
</div>
</body>
<script>
Vue.component('login', {
template: '<h1>登录组件</h1>'
})
Vue.component('register',{
template:'<h1>注册组件</h1>'
})
new Vue({
el: '#vm',
data:{
flag:true
}
})
</script>
</html>
运行结果
image
组件切换2
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="vm">
<a href="" @click.prevent="comName='login'">登录</a>
<a href="" @click.prevent="comName='register'">注册</a>
<transition mode="out-in">
<component :is="comName"></component>
</transition>
</div>
</body>
<script>
Vue.component('login', {
template: '<h1>登录组件</h1>'
})
Vue.component('register',{
template:'<h1>注册组件</h1>'
})
new Vue({
el: '#vm',
data:{
flag:true,
comName:'login'
}
})
</script>
<style type="text/css">
.v-enter,.v-leave-to{
opacity: 0;
transform: translateX(150px);
}
.v-enter-active,.v-leave-active{
transition: all 0.5s ease;
}
</style>
</html>
运行结果
image
vue之动画
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="demo">
<button v-on:click="show = !show">
Toggle
</button>
<transition>
<p v-if="show">hello</p>
</transition>
<button v-on:click="flag = !flag">
Toggle2
</button>
<transition name="fade">
<p v-if="flag">过渡的类名</p>
</transition>
</div>
</body>
<script>
new Vue({
el: '#demo',
data: {
show: true,
flag: true
}
})
</script>
<style>
.v-enter-active,
.v-leave-active {
transition: opacity .5s;
}
.v-enter,
.v-leave-to {
opacity: 0;
}
.fade-enter-active,
.fade-leave-active {
transition: all 0.4s ease;
}
.fade-enter,
.fade-leave-to
/* .fade-leave-active below version 2.1.8 */
{
opacity: 0;
transform: translateX(100px);
}
</style>
</html>
运行结果
image
动画animate
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<link rel="stylesheet" href="https://unpkg.com/animate.css@3.5.2/animate.min.css">
<style>
.box{height: 100px;width: 100px;background-color: lightblue}
</style>
</head>
<body>
<div class="box animated rotateIn"></div>
<div id="app">
<button v-on:click="flag = !flag">
Toggle2
</button>
<transition
enter-active-class="bounceIn"
leave-active-class="bounceOut"
:duration="{enter:200,leave:800}">
<p v-if="flag" class="animated">animate</p>
</transition>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
flag: true
}
})
</script>
</html>
运行结果
image
局部组件
示例代码如下
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>局部组件入门</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<button-counter></button-counter>
</div>
</body>
<script>
new Vue({
el: '#app',
data:{
msg:'父组件向子组件传值'
},
components: {
// 注册一个名为button-counter的局部组件
'button-counter': {
data: function() {
return {
count:'局部组件'
}
},
template: '<h3>{{count}}</h3>'
}
}
})
</script>
</html>
运行结果
image
父组件向子组件传值
示例代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<link rel="stylesheet" href="https://unpkg.com/animate.css@3.5.2/animate.min.css">
</head>
<body>
<div id="app">
<com1 :sonmsg="msg"></com1>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
msg:'这是父组件的数据'
},
components:{
com1:{
template:'<h1>子组件中的模板-----{{sonmsg}}</h1>',
props:['sonmsg']
}
}
})
</script>
</html>
运行结果
image
子组件向父组件传递数据
示例代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<link rel="stylesheet" href="https://unpkg.com/animate.css@3.5.2/animate.min.css">
</head>
<body>
<div id="app">
<com1 @func="show"></com1>
</div>
<template id="tmp1">
<div>
<h1>这是子组件</h1>
<input type="button" value="点击调用父组件的方法" @click="myclick">
</div>
</template>
</body>
<script>
var com1={
template:'#tmp1',
methods:{
myclick(){
this.$emit('func',this.sonmsg)
}
},
data(){
return {
sonmsg:{name:'张三',age:'20'}
}
}
}
new Vue({
el:'#app',
data:{
dataFormson:null
},
methods:{
show:function(data){
this.dataFormson=data;
console.log("父组件方法"+this.dataFormson);
}
},
components:{
com1
}
})
</script>
</html>
运行结果
image
vue之$refs操作DOM元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<link rel="stylesheet" href="https://unpkg.com/animate.css@3.5.2/animate.min.css">
</head>
<body>
<div id="app">
<input type="button" name="" id="" value="获取元素" @click="getElement" ref="mybtn"/>
<h3 ref="myh3">哈哈,快七夕了</h3>
<login ref="mylogin"></login>
</div>
</body>
<script>
var login={
template:'<h1>登录</h1>',
data(){
return {
msg:'login数据'
}
},
methods:{
show(){
console.log("这是登录组件的方法")
}
}
}
new Vue({
el:'#app',
methods:{
getElement:function(){
// console.log(this.$refs.myh3.innerText);
// console.log(this.$refs.mybtn);
// console.log(this.$refs.mylogin.msg);
this.$refs.mylogin.show()
}
},
components:{
login
}
})
</script>
</html>
运行结果
image
组件监听事件
示例代码如下
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="blog-posts-events-demo">
<div :style="{ fontSize: postFontSize + 'em' }">
<blog-post v-for="post in posts" v-bind:key="post.id" v-bind:post="post" v-on:enlarge-text="postFontSize += 0.1"></blog-post>
</div>
</div>
</body>
<script>
Vue.component('blog-post', {
props: ['post'],
template: `
<div class="blog-post">
<h3>{{ post.title }}</h3>
<button v-on:click="$emit('enlarge-text')">
Enlarge text
</button>
<div v-html="post.content"></div>
</div>
`
})
new Vue({
el: '#blog-posts-events-demo',
data: {
posts: [{
id: 1,
title: 'My journey with Vue',
content: '内容1'
},
{
id: 2,
title: 'Blogging with Vue',
content: '内容2'
},
{
id: 3,
title: 'Why Vue is so fun',
content: '内容3'
}
],
postFontSize: 1
}
})
</script>
</html>
运行结果
image
组件上使用v-model
示例代码如下
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="blog-posts-events-demo">
<input v-model="searchText">
<br>
<!-- 等价于 -->
<input v-bind:value="searchText" v-on:input="searchText = $event.target.value">
<br>
<!-- 当用在组件上时,v-model 则会这样 -->
<custom-input v-bind:value="searchText" v-on:input="searchText = $event"></custom-input>
<br>
<!-- 现在 v-model 就应该可以在这个组件上完美地工作起来了 -->
<custom-input v-model="searchText"></custom-input>
<br>
{{searchText}}
</div>
</body>
<script>
Vue.component('custom-input', {
props: ['value'],
template: `
<input
v-bind:value="value"
v-on:input="$emit('input', $event.target.value)"
>
`
})
new Vue({
el: '#blog-posts-events-demo',
data: {
searchText: ''
}
})
</script>
</html>
运行结果
image
vue之过滤器
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="components-demo">
<!-- 在双花括号中 -->
{{ message | capitalize | formatId |filterB('参数1','参数2')}}
<br>
{{msg|filterA('私有')}}
<!-- 在 `v-bind` 中 -->
<div v-bind:id="rawId | formatId"></div>
</div>
</body>
<script>
Vue.filter('capitalize', function(value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
})
Vue.filter('formatId', function(value) {
return value + 'zxcvbnm'
})
Vue.filter('filterB', function(value, arg, arg2) {
return value + arg + arg2
})
var vm = new Vue({
el: '#components-demo',
data: {
message: 'java',
rawId: 78,
msg: '测试'
},
filters: {
filterA: function(msg, arg) {
return msg + arg
}
}
})
</script>
</html>
运行结果
image
按键修饰符
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="components-demo">
<input type="text" v-model="message" @keyup.enter="add" />
{{message}}
</div>
</body>
<script>
var vm = new Vue({
el: '#components-demo',
data: {
message: ''
},
methods:{
add:function(){
alert(this.message+'按键修饰符');
}
}
})
</script>
</html>
在输入框中输入内容回车,运行结果
image
vue之自定义指令
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="hook-arguments-example">
<input v-focus v-color="'red'">
<div id="hook-arguments-example" v-demo:foo.a.b="message"></div>
<div v-fontweight="'900'">私有指令</div>
</div>
</body>
<script>
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……,js操作用这个
inserted: function(el) {
// 聚焦元素
el.focus()
}
})
Vue.directive('color', {
// css操作用只用bind就可以了
bind: function(el, binding) {
console.log(binding.value)
el.style.color = binding.value
}
})
Vue.directive('demo', {
bind: function(el, binding, vnode) {
var s = JSON.stringify
el.innerHTML =
'name: ' + s(binding.name) + '<br>' +
'value: ' + s(binding.value) + '<br>' +
'expression: ' + s(binding.expression) + '<br>' +
'argument: ' + s(binding.arg) + '<br>' +
'modifiers: ' + s(binding.modifiers) + '<br>' +
'vnode keys: ' + Object.keys(vnode).join(', ')
}
})
new Vue({
el: '#hook-arguments-example',
data: {
message: 'hello!'
},
// 自定义私有属性
directives: {
'fontweight': {
bind: function(el, binding) {
el.style.fontWeight = binding.value
}
}
}
})
</script>
</html>
在输入框输入内容,运行结果
image
路由
路由入门
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router@2.0.0/dist/vue-router.js"></script>
</head>
<style type="text/css">
/* 默认高亮样式 */
/* .router-link-active{
color: red;
font-size: 80px;
font-weight: 800;
font-style: initial;
text-decoration: underline;
background-color: green;
} */
/* 或者自定义 */
.myactive{
color: #0000FF;
font-size: 50px;
}
</style>
<body>
<div id="app">
<a href="#/login">登录</a>
<a href="#/register">注册</a>
<!-- 也可以这么写 -->
<router-link to="/login">登录2</router-link>
<router-link to="/register">注册2</router-link>
<router-view></router-view>
</div>
</body>
<script>
var login={
template:'<h1>登录组件</h1>'
}
var register={
template:'<h1>注册组件</h1>'
}
var routerobj=new VueRouter({
routes:[
{path:'/login',component:login},
{path:'/register',component:register},
// 重定向
{path:'/',redirect:'/login'}
],
linkActiveClass:'myactive'
})
var vm=new Vue({
el:'#app',
router:routerobj
})
</script>
</html>
运行结果
image
路由query和params
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router@2.0.0/dist/vue-router.js"></script>
</head>
<body>
<div id="app">
<router-link to="/login?id=10&name=query应用">登录</router-link>
<router-link to="/register/12/params应用">注册</router-link>
<router-view></router-view>
</div>
</body>
<script>
var login={
template:'<h3>登录组件----{{$route.query.id}}----{{$route.query.name}}</h3>',
// 生命周期勾子函数
created(){
console.log(this.$route.query.id);
console.log(this.$route.query.name)
}
}
var register={
template:'<h3>注册组件---{{$route.params.id}}---{{$route.params.name}}</h3>',
created(){
console.log(this.$route.params.id);
console.log(this.$route.params.name)
}
}
var router=new VueRouter({
routes:[
{path:'/login',component:login},
{path:'/register/:id/:name',component:register}
]
})
var vm=new Vue({
el:'#app',
router:router
})
</script>
</html>
运行结果
image
二级路由
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router@2.0.0/dist/vue-router.js"></script>
</head>
<body>
<div id="app">
<router-link to="/account">Account组件</router-link>
<router-view></router-view>
</div>
<template id="temp">
<div>
<h4>这是account的组件模板</h4>
<router-link to="/login">登录</router-link>
<router-link to="/register">注册</router-link>
<router-view></router-view>
</div>
</template>
</body>
<script>
var login = {
template: '<h5>登录组件</h5>'
}
var register = {
template: '<h5>注册组件</h5>'
}
var account = {
template: '#temp',
}
var router = new VueRouter({
routes: [{
path: '/account',
component: account,
children: [{
path: '/login',
component: login
},
{
path: '/register',
component: register
}
]
}
]
})
var vm = new Vue({
el: '#app',
router: router
})
</script>
</html>
运行结果
image
命名视图案例实现经典布局
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router@2.0.0/dist/vue-router.js"></script>
</head>
<style type="text/css">
.header{
background-color: #0000FF;
height: 100px;
}
.left{
flex: 2;
background-color:red;
}
.main{
background-color: green;
flex: 8;
}
.containar{
display: flex;
height: 600px;
}
h1{
margin: 0;
padding: 0;
}
html,body{
margin: 0;
padding: 0;
}
</style>
<body>
<div id="app">
<router-view></router-view>
<div class="containar">
<router-view name="left"></router-view>
<router-view name="main"></router-view>
</div>
</div>
</body>
<script>
var header = {
template: '<h1 class="header">header组件</h1>'
}
var left = {
template: '<h1 class="left">left组件</h1>'
}
var main = {
template: '<h1 class="main">main组件</h1>'
}
var router = new VueRouter({
routes: [{
path: '/',
components: {
'default':header,
'left':left,
'main':main
}
}
]
})
var vm = new Vue({
el: '#app',
router: router
})
</script>
</html>
运行结果
image
命名视图之组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router@2.0.0/dist/vue-router.js"></script>
</head>
<body>
<div id="app">
<router-view class="view one"></router-view>
<router-view class="view two" name="a"></router-view>
<router-view class="view three" name="b"></router-view>
</div>
</body>
<script>
var Foo = {
template: '<h1>这是Foo组件</h1>'
}
var Bar = {
template: '<h1>这是Bar组件</h1>'
}
var Baz = {
template: '<h1>这是Baz组件</h1>'
}
const router = new VueRouter({
routes: [
{
path: '/',
components: {
default: Foo,
a: Bar,
b: Baz
}
}
]
})
var vm = new Vue({
el: '#app',
data: {
msg: 123
},
components: {
Foo,
Bar,
Baz
},
router
})
</script>
</html>
运行结果
image
vue之watch
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" name="" id="" value="" v-model="firstname"/>
<input type="text" name="" id="" value="" v-model="lastname"/>
<input type="text" name="" id="" value="" v-model="fullname"/>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data:{
firstname:'',
lastname:'',
fullname:''
},
watch:{
firstname:function(oldVal,newVal){
// this.fullname=this.firstname+this.lastname
console.log(oldVal+'======='+newVal)
this.fullname=newVal+this.lastname
},
lastname:function(newVal){
// this.fullname=this.firstname+this.lastname
this.fullname=this.firstname+newVal
}
}
})
</script>
</html>
运行结果
image
vue之keyup
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" name="" id="" value="" v-model="firstname" @keyup="getFullname"/>
<input type="text" name="" id="" value="" v-model="lastname" @keyup="getFullname"/>
<input type="text" name="" id="" value="" v-model="fullname"/>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data:{
firstname:'',
lastname:'',
fullname:''
},
methods:{
getFullname(){
this.fullname=this.firstname+'---'+this.lastname
}
}
})
</script>
</html>
运行结果
image
74 vue之render函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<div>5678</div>
<login></login>
</div>
</body>
<script>
var login={
template:'<h1>登录组件</h1>'
}
var vm=new Vue({
el:'#app',
data:{
msg:123
},
render:function(createElements){
return createElements(login)
}
})
</script>
</html>
运行结果
image
75 vue之slot插槽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<login></login>
<login><span slot='right'>替换右边</span></login>
<login><button slot='left'>替换左边</button></login>
<login><h4 slot='center'>替换中间</h4></login>
</div>
<template id='tem'>
<div>
<h1>你好呀</h1>
<!-- <slot><button type="button">默认</button></slot> -->
<slot name='left'><span>左边</span></slot>
<slot name='center'><span>中间</span></slot>
<slot name='right'><span>右边</span></slot>
</div>
</template>
</body>
<script>
var login = {
template: '#tem'
}
var vm = new Vue({
el: '#app',
data: {
msg: 123
},
components: {
login
}
})
</script>
</html>
运行结果
image