Vue基本的语法
Vue的基本代码结构及插值表达式(Mustache)
<body>
<!-- Vue 实例所控制的元素区域 -->
<div id="app">
{{ message }}
</div>
<script>
//创建一个Vue的实例
var vm = new Vue({
el: '#app',// 表示当前new的这个Vue实例要控制页面上的哪个区域
data: {
message: 'Hello Vue!'
}
})
</script>
</body>
Vue指令之v-text
和v-html
<body>
<div id="app">
<div>{{ msg }} - I'm coming</div>
<div v-text='htmlText'>I'm coming</div>
<div v-html="htmlText"></div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
msg: 'Hello Vue',
htmlText: '<h1>我是一个大标题</h1>'
}
})
</script>
</body>
Vue指令之v-bind
的三种用法
-
直接使用指令
v-bind
-
使用简化指令
:
-
在绑定的时候,拼接绑定内容:
:title="btnTitle + ', 这是追加的内容'"
<body>
<div id="app">
<div>{{ msg }} - I'm coming</div>
<div v-text='htmlText'>I'm coming</div>
<div v-html="htmlText"></div>
<div v-html="htmlText" v-bind:title="msg"></div>
<div v-html="htmlText" :title="msg"></div>
<div v-html="htmlText" :title="msg+' I am coming'"></div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
msg: 'Hello Vue',
htmlText: '<h1>我是一个大标题</h1>'
}
})
</script>
</body>
Vue指令之v-on
和跑马灯效果
<body>
<div id="app">
<h3>{{info}}</h3>
<input type="button" value="开启" v-on:click="start">
<input type="button" value="停止" @click="stop">
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
info: '猥琐发育,别浪~!',
intervalId: null
},
methods: {
start() {
if (this.intervalId != null) { // 如果当前有定时器在运行,则直接return
return;
}
this.intervalId = setInterval(() => { // 开始定时器
this.info = this.info.substring(1) + this.info.substring(0, 1);
}, 200);
},
stop() {
clearInterval(this.intervalId);
}
}
});
</script>
</body>
Vue指令之事件修饰符
-
.stop 阻止冒泡
-
.prevent 阻止默认事件
-
.capture 添加事件侦听器时使用事件捕获模式
-
.self 只当事件在该元素本身(比如不是子元素)触发时触发回调
-
.once 事件只触发一次
<body>
<style type="text/css">
.inner {height: 150px;background-color: darkcyan;}
.outer {padding: 40px;background-color: blue;}
</style>
<div id="app">
<h4>正常事件</h4>
<div class="inner" @click="div1Handler">
<input type="button" value="戳他" @click="btnHandler">
</div>
<h4> 使用 .prevent 阻止默认行为</h4>
<a href="http://www.baidu.com" @click.prevent="linkClick">有问题,先去百度</a>
<h4> 使用 .capture 实现捕获触发事件的机制</h4>
<div class="inner" @click.capture="div1Handler">
<input type="button" value="戳他" @click="btnHandler">
</div>
<h4> 使用 .once 只触发一次事件处理函数 </h4>
<a href="http://www.baidu.com" @click.prevent.once="linkClick">有问题,先去百度</a>
<h4> 使用 .stop 阻止冒泡 </h4>
<div class="outer" @click="div2Handler">
<div class="inner" @click="div1Handler">
<input type="button" value="戳他" @click.stop="btnHandler">
</div>
</div>
<h4> 使用 .self 只会阻止自己身上冒泡行为的触发,并不会真正阻止冒泡的行为 </h4>
<div class="outer" @click="div2Handler">
<div class="inner" @click.self="div1Handler">
<input type="button" value="戳他" @click="btnHandler">
</div>
</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {},
methods: {
div1Handler() {
console.log('这是触发了 inner div 的点击事件')
},
btnHandler() {
console.log('这是触发了 btn 按钮 的点击事件')
},
linkClick() {
console.log('触发了连接的点击事件')
},
div2Handler() {
console.log('这是触发了 outer div 的点击事件')
}
}
});
</script>
</body>
Vue指令之v-model
和双向数据绑定
<body>
<div id="app">
<h4 v-text="msg"></h4>
<input type="text" v-model="msg">
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
msg:"我是初始值"
},
});
</script>
</body>
Vue指令之v-for
和key
属性
- 迭代数组
<ul>
<li v-for="(item, i) in list">
索引:{{i}} - 姓名:{{item.name}} - 年龄:{{item.age}}
</li>
</ul>
- 迭代对象中的属性
<div v-for="(val, key, i) in user">{{val}}-{{key}}-{{i}}</div>
- 迭代数字
<p v-for="i in 10">这是第 {{i}} 个P标签</p>
- key与列表筛选
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。
<body>
<div id="app">
<div>
<label>Id:
<input type="text" v-model="id">
</label>
<label>Name:
<input type="text" v-model="name">
</label>
<input type="button" value="添加" @click="add">
</div>
<!-- search(name) :key="item.id"-->
<p v-for="item in list" >
<input type="checkbox">{{item.id}} --- {{item.name}}
</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
id: '',
name: '',
list: [
{ id: 1, name: '盖伦' },
{ id: 2, name: '寒冰' },
{ id: 3, name: '瑞兹' },
]
},
methods: {
add() { // 添加方法
this.list.unshift({ id: this.id, name: this.name })
this.id=this.name='';
},
search(name) {
return this.list.filter(x => {
return x.name.indexOf(name) != -1;
});
}
}
});
</script>
</body>
Vue指令之v-if
和v-show
- v-if:每次都会重新删除或创建元素 有较高的切换性能消耗
- v-show: 每次不会重新进行DOM的删除和创建操作,只是切换了元素的 display:none 样式 有较高的初始渲染消耗
<body>
<div id="app">
<input type="button" value="toggle" @click="flag=!flag">
<h3 v-if="flag">这是用v-if控制的元素</h3>
<h3 v-show="flag">这是用v-show控制的元素</h3>
</div>
<script>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
flag: false
},
});
</script>
</body>
一般来说,v-if 有更高的切换消耗而 v-show 有更高的初始渲染消耗。因此,如果需要频繁切换 v-show 较好,如果在运行时条件不大可能改变 v-if 较好。
使用内联样式
直接在元素上通过 :style
的形式,书写样式对象
<h1 :style="{color: 'red','font-size':'40px'}">这是一个H1</h1>
将样式对象,定义到 data
中,并直接引用到 :style
中
- 在data上定义样式:
data: {
h1StyleObj: { color: 'red', 'font-size': '40px' }
}
- 在元素中,通过属性绑定的形式,将样式对象应用到元素中:
<h1 :style="h1StyleObj">这是一个H1</h1>
在 :style
中通过数组,引用多个 data
上的样式对象
- 在data上定义样式:
data: {
h1StyleObj: { color: 'red', 'font-size': '40px'},
h1StyleObj2: { fontStyle: 'italic' }
}
- 在元素中,通过属性绑定的形式,将样式对象应用到元素中:
<h1 :style="[h1StyleObj, h1StyleObj2]">这是一个H1</h1>
Vue自定义过滤器
Vue.js 允许你自定义过滤器,可被用作一些常见的文本格式化。过滤器可以用在两个地方:mustache 插值和 v-bind 表达式。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符指示;
- 私有过滤器
<body>
<div id="app">
<select v-model="message">
<option value="1">开心</option>
<option value="2">失落</option>
<option value="3">狂躁</option>
</select>
<p>选中值: {{message}}</p>
<p :title="message | tran('我很')">翻译后: {{ message | tran('我很')}}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
message: ''
},
filters: {
tran(str, mood = "") {
switch (str) {
case "1": mood = mood + '开心';
break;
case "2": mood = mood + '失落';
break;
case "3": mood = mood + '狂躁';
break;
default: mood = "";
}
return mood;
}
}
})
</script>
</body>
- 全局过滤器
Vue.filter('tran', function (str, mood = "") {...})
注意:当有局部和全局两个名称相同的过滤器时候,会以就近原则进行调用,即:局部过滤器优先于全局过滤器被调用!
Vue自定义指令
Vue过渡动画
Vue生命周期函数
new Vue({
data: {
a: 1
},
created: function () {
// `this` 指向 vm 实例
console.log('a is: ' + this.a)
},
...
})
Vue组件
定义Vue组件
什么是组件: 组件的出现,就是为了拆分Vue实例的代码量的,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样的功能,就可以去调用对应的组件即可;
组件化和模块化的不同:
- 模块化: 是从代码逻辑的角度进行划分的;方便代码分层开发,保证每个功能模块的职能单一;
- 组件化: 是从UI界面的角度进行划分的;前端的组件化,方便UI组件的重用;
Vue组件的定义
全局定义的三种方式
- 使用 Vue.extend 配合 Vue.component 方法:
var login = Vue.extend({
template: '<h1>登录</h1>'
});
Vue.component('login', login);
- 直接使用 Vue.component 方法:
Vue.component('register', {
template: '<h1>注册</h1>'
});
- 将模板字符串,定义到script标签种:
<script id="tmpl" type="x-template">
<div><a href="#">登录</a> | <a href="#">注册</a></div>
</script>
//同时,需要使用 Vue.component 来定义组件
Vue.component('account', {
template: '#tmpl'
});
注意: 组件中的DOM结构,有且只能有唯一的根元素(Root Element)来进行包裹!
使用components
属性定义局部子组件
<body>
<div id="app">
<!-- 组件的引用 -->
<account></account>
</div>
<script>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {},
methods: {},
components: { // 定义当前实例的子组件
account: { // account 组件
template: '<div><h1> 这是Account组件{{ name }}</h1 ><login></login></div > ',
components: { // 定义account 组件的子组件
login: {
template: "<h3>这是登录组件</h3>"
},
regist: {
template: "<h3>这是注册组件</h3>"
}
}
}
}
});
</script>
</body>
组件中展示数据和响应事件
- 在组件中,
data
需要被定义为一个方法并返回一个对象
,例如:
Vue.component('account', {
template: '#tmpl',
data() {
return {
msg: '大家好!'
}
},
methods: {
login() {
alert('点击了登录按钮');
}
}
});
- 在子组件中,如果将模板字符串,定义到了script标签中,那么,要访问子组件身上的
data
属性中的值,需要使用this
来访问;
组件切换 使用component
标签,来引用组件,并通过:is
属性来指定要加载的组件
<body>
<style>
.v-enter,.v-leave-to {opacity: 0;transform: translateX(30px);}
.v-enter-active,.v-leave-active { position: absolute;transition: all 0.3s ease;}
</style>
<div id="app">
<a href="#" @click.prevent="comName='login'">登录</a>
<a href="#" @click.prevent="comName='regist'">注册</a>
<transition mode="out-in">
<component :is="comName"></component>
</transition>
</div>
<script>
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
comName:'login'
},
methods: {},
components: { // 定义当前实例的子组件
login: {
template: "<h3>这是登录组件</h3>"
},
regist: {
template: "<h3>这是注册组件</h3>"
}
}
});
</script>
</body>
Vue组件间的传值
父组件向子组件传值
注意:一定要使用
props
属性来定义父组件传递过来的数据
<body>
<div id="app">
<son :finfo="msg"></son>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
msg: '这是父组件中的消息'
},
components: {
son: {
template: '<h1>这是子组件 - {{finfo}}</h1>',
props: ['finfo']
}
}
});
</script>
</body>
子组件向父组件传值
-
原理:父组件将方法的引用,传递到子组件内部,子组件在内部调用父组件传递过来的方法,同时把要发送给父组件的数据,在调用方法的时候当作参数传递进去;
-
父组件将方法的引用传递给子组件,其中,
getMsg
是父组件中methods
中定义的方法名称,func
是子组件调用传递过来方法时候的方法名称 -
子组件内部通过
this.$emit('方法名', 要传递的数据)
方式,来调用父组件中的方法,同时把数据传递给父组件使用实例如下:
<body>
<div id="app">
<p v-text="msg"></p>
<son @func="getMsg" :finfo="msg"></son>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
msg: '这是父组件中的消息'
},
methods: {
getMsg(val){
this.msg = val;
}
},
components: {
son: {
template: `
<div>
<input type="text" v-model="finfo" />
<input type="button" value="向父组件传值" @click="sendMsg" />
</div>
`,
methods: {
sendMsg(){
this.$emit('func', this.finfo);
}
},
props: ['finfo']
}
}
});
</script>
</body>
Vue-Router的使用
什么是路由
-
对于普通的网站,所有的超链接都是URL地址,所有的URL地址都对应服务器上对应的资源;
-
对于单页面应用程序来说,主要通过URL中的hash(#号)来实现不同页面之间的切换,同时,hash有一个特点:HTTP请求中不会包含hash相关的内容;所以,单页面程序中的页面跳转主要用hash实现;
-
在单页面应用程序中,这种通过hash改变来切换页面的方式,称作前端路由(区别于后端路由);
vue-router的基本使用
- 导入 vue-router 组件类库:
<script src="./lib/vue-router-3.0.1.js"></script>
- 使用 router-link 组件来导航
<router-link to="/login">登录</router-link>
<router-link to="/regist">注册</router-link>
- 使用 router-view 组件来显示匹配到的组件
<router-view></router-view>
- 创建使用
Vue.extend
创建组件
var login = Vue.extend({
template: '<h1>登录组件</h1>'
});
var regist = Vue.extend({
template: '<h1>注册组件</h1>'
});
- 创建一个路由 router 实例,通过 routers 属性来定义路由匹配规则
var router = new VueRouter({
routes: [
{ path: '/', redirect: '/login' },
{ path: '/login', component: login },
{ path: '/regist', component: register }
]
});
- 使用 router 属性来使用路由规则
var vm = new Vue({
el: '#app',
router: router // 使用 router 属性来使用路由规则
});
- 完整示例
<body>
<div id="app">
<router-link to="/login">登录</router-link>
<router-link to="/regist">注册</router-link>
<router-view></router-view>
</div>
<script>
var login = Vue.extend({
template: '<h1>登录组件</h1>'
});
var regist = Vue.extend({
template: '<h1>注册组件</h1>'
});
var router = new VueRouter({
routes: [
{ path: '/login', component: login },
{ path: '/regist', component: regist }
]
});
var vm = new Vue({
el: '#app',
router: router
});
</script>
</body>
使用redirect
实现重定向
{ path: '/', redirect: '/login' }
在路由规则中定义参数
定义参数:参数名
{ path: '/register/:id', component: register }
获取参数this.$route.params
var regist = Vue.extend({
template: '<h1>注册组件 --- {{this.$route.params.id}}</h1>'
});
使用 children
属性实现路由嵌套
var router = new VueRouter({
routes: [
{ path: '/', redirect: '/account/login' },
{
path: '/account',
component: account,
// 通过 children 数组属性,来实现路由的嵌套
children: [
// 注意,子路由的开头位置,不要加 / 路径符
{ path: 'login', component: login },
{ path: 'regist', component: regist}
]
}
]
});
用Vue-cli3初始化一个Vue项目
安装
npm install -g @vue/cli
# OR
yarn global add @vue/cli
安装之后,你就可以在命令行中访问 vue 命令。你可以通过简单运行 vue,看看是否展示出了一份所有可用命令的帮助信息,来验证它是否安装成功。
创建一个项目
- 运行以下命令来创建一个新项目:
vue create hello-world
你会被提示选取一个 preset。你可以选默认的包含了基本的 Babel + ESLint 设置的 preset,也可以选“手动选择特性”来选取需要的特性。
- 通过
vue ui
命令以图形化界面创建和管理项目
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UTd8PTGp-1575449673653)(https://cli.vuejs.org/ui-new-project.png)]
使用命令启动或打包
在一个 Vue CLI 项目中,@vue/cli-service 安装了一个名为 vue-cli-service 的命令。你可以在 npm scripts 中以 vue-cli-service、或者从终端中以 ./node_modules/.bin/vue-cli-service 访问这个命令。
这是使用默认 preset 的项目的 package.json:
{
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
}
}
通过 npm 或 Yarn 调用这些 script:
//启动项目
npm run serve
# OR
yarn serve
//打包项目
npm run build
# OR
yarn build
build
会在 dist/ 目录产生一个可用于生产环境的包,带有JS/CSS/HTML的压缩
Ant Design of Vue 组件库的基本使用
整理中…
Ant Design Pro of Vue 的基本使用
整理中…