Vue01_Vue基础入门
Vue01_入门语句引入 Vue 的 cdn<script src="https://cdn.bootcss.com/vue/2.5.2/vue.min.js"></script>Vue入门程序<div id="app">{{message}}</div><script>var vm = new Vue({el: "#app",data:
Vue基础入门
Vue入门
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
{{message}}
</div>
<script>
var vm = new Vue({
el: "#app",
data:{
message: "hello,vue!"
}
});
</script>
Vue的基础指令
<div id="app">
<!-- v-text 会覆盖元素中原本的内容,未完全加载时会显示‘哈哈’-->
<h4 v-text="msg">哈哈</h4>
<!-- v-html 会将内容转义成html页面-->
<p v-html="msg2"></p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
msg: '123',
msg2: '<h1>H1大标题</h1>',
}
</script>
<div id="app">
<span v-bind:title="message">鼠标悬停此处查看动态绑定的提示信息</span>
</div>
<script>
var vm = new Vue({
el: "#app",
data:{
message: "hello,vue!"
}
});
</script>
<div id="app">
<h1 v-show="ok">Yes</h1>
</div>
<script>
var vm = new Vue({
el: "#app",
data:{
ok: false
}
});
</script>
<div id="app">
<h1 v-if="ok">Yes</h1>
<h1 v-else>NO</h1>
</div>
<script>
var vm = new Vue({
el: "#app",
data:{
ok: false
}
});
</script>
<div id="app">
<h1 v-if="type==='A'">a</h1>
<h1 v-else-if="type==='B'">b</h1>
<h1 v-else-if="type==='C'">c</h1>
<h1 v-else>d</h1>
</div>
<script>
var vm = new Vue({
el: "#app",
data:{
type: 'B'
}
});
</script>
v-if 与 v-show 有啥区别
答案:
1. 实现原理不一样
v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
v-show 不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
即通过设置元素的 display:none,达到显示隐藏的作用。
2. 开销不一样
如果频繁的切换元素的状态,v-if 的开销会比较大,因为它涉及到条件块内各组件的重建和销
毁,(造成回流)而 v-show 只是切换元素的 css,v-show 的开销比较小。
3. 适用场景不一样
如果频繁的切换元素的状态,v-if 的开销会比较大,,v-show 的开销比较小。因此,v-show 更适合频繁切换的场景。
当然,v-show 只是设置了元素的 display 为 none,元素 dom 结构还是在那里的。
如果你不想让其他人看到这些 dom,需要使用 v-if。
<div id="app">
<li v-for="(item, index) in items">
num: {{item.id}} message: {{item.message}} index: {{index}}
</li>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
items: [
{id: 1, message: 'BLU1'},
{id: 2, message: 'BLU2'},
{id: 3, message: 'BLU3'}
]
}
});
</script>
<div id="app">
<button v-on:click="sayHi">Click Me</button>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
message: "Hello, BLU!"
},
methods: {
sayHi: function () {
alert(this.message);
}
}
});
</script>
<div id="app">
输入的文本:<input type="text" v-model="message"><br>
{{message}}
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
message: ""
}
});
</script>
<body>
<div id="vm" v-once>
{{key}}
</div>
</body>
<script>
var vm = new Vue({
el: '#vm',
data: {
key: 'Hello, Vue'
}
})
</script>
自定义指令
<div id="app">
<input type="text" >
<input type="text" v-blu>
</div>
<script>
//参数1指定指令的名称,参数2指定指令的业务逻辑
Vue.directive('blu', {
// 参数el表示指令所绑定的元素
inserted: function(el) {
el.focus();
}
});
var vm = new Vue({
el: '#app'
})
</script>
此时,加了自定义指令 v-blu 的输入框在页面一加载时就处于选中(focus)状态
<div id="app">
<input type="text" v-color='msg'>
</div>
<script>
Vue.directive('color', {
// 参数 binding 对象中的 value 属性指定了指令的绑定值
bind: function(el, binding) {
console.log(binding);
el.style.backgroundColor = binding.value;
}
});
var vm = new Vue({
el: '#app',
data: {
msg: 'red'
}
})
</script>
指令定义对象的钩子函数:
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
<div id="app">
<input type="text" v-color='msg'>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
msg: 'blue'
},
directives: {
color: {
bind: function(el, binding) {
el.style.backgroundColor = binding.value;
}
}
}
})
</script>
Vue 计算属性 computed
将计算出来的结果放入缓存,以节约系统的开销
<div id="app">
<!-- 调用方法 -->
<p>{{currentTime1()}}</p>
<!-- 调用计算属性 -->
<p>{{currentTime2}}</p>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
message: "Hello, BLU!"
},
methods: {
currentTime1: function () {
return Date.now();
}
},
computed: {
currentTime2: function () {
return Date.now();
}
}
});
</script>
当依赖的属性发生改变时,计算属性与方法都会被重新调用,此时二者没有区别。
当依赖的属性再次调用时,计算属性会自动获取数据的缓存,而不是重新调用计算属性计算过程。
而无论依赖的属性方法是否发生变化,只要再次调用方法,就会重新执行方法的内容。
所以计算属性的效率更高
Vue 侦听器 watch
响应数据的变化
<div id="app">
<input type="text" v-model="firstName">
<input type="text" v-model="lastName">
<p>{{fullName}}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
firstName: 'Yin',
lastName: 'Yang',
fullName: 'Yin Yang'
},
watch: {
firstName: function(val) {
this.fullName = val + ' ' + this.lastName;
},
lastName: function(val) {
this.fullName = this.firstName + ' ' + val;
}
}
})
</script>
<div id="app">
用户名:<input type="text" v-model.lazy="userName">
<span>{{tip}}</span>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
userName: '',
tip: ''
},
watch: {
userName: function(val) {
this.tip = '正在验证...';
this.checkName(val);
}
},
methods: {
checkName: function(uname) {
var that = this;
setTimeout(function() {
//模拟接口调用
if (uname == 'admin') {
that.tip = "用户名已经存在";
} else {
that.tip = "用户名可用";
}
}, 2000);
}
}
})
</script>
Vue 过滤器 filter
直接将首字母变成大写
<div id="app">
<input type="text" v-model="msg">
<div>{{msg | upper}}</div>
</div>
<script>
Vue.filter('upper', function(val) {
return val.charAt(0).toUpperCase() + val.slice(1);
})
var vm = new Vue({
el: '#app',
data: {
msg: ''
}
})
</script>
先将全部字母变成小写,再将首字母变成大写
<div id="app">
<input type="text" v-model="msg">
<div>{{msg | lower | upper}}</div>
</div>
<script>
Vue.filter('upper', function(val) {
return val.charAt(0).toUpperCase() + val.slice(1);
});
Vue.filter('lower', function(val) {
return val.toLowerCase();
})
var vm = new Vue({
el: '#app',
data: {
msg: ''
}
})
</script>
<div id="app">
<div>{{date | format('yyyy-MM-dd')}}</div>
</div>
<script>
Vue.filter('format', function(val, arg) {
if (arg == 'yyyy-MM-dd') {
var ret = '';
ret += val.getFullYear() + '-' + (val.getMonth() + 1) + '-' + val.getDate();
return ret
}
});
var vm = new Vue({
el: '#app',
data: {
date: new Date()
}
})
</script>
- Axios 异步通信
1. 引入 Axios 的 cdn
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
2. 准备 json 文件
{
"name": "BLU",
"url": "http://www.baidu.com",
"page": 1,
"address": {
"country": "China",
"city": "南京",
"street": "安德门大街"
}
}
Vue 生命周期
主要阶段:
- 挂载
beforecreated:el 和 data 并未初始化
created:完成了 data 数据的初始化,el没有
beforeMount:完成了 el 和 data 初始化
mounted:完成挂载
- 更新
beforeUpdate:数据更新之前
updated:数据更新之后
- 销毁
beforeDestroy:实例销毁之前
destroyed:实例销毁之后
<body>
<div id="vm">
{{key}}
</div>
</body>
<script>
var vm = new Vue({
el: '#vm',
data: {
key: 'Hello, Vue'
},
beforeCreate: function() {
console.log("beforeCreate");
console.log("key:" + this.key);
},
created: function() {
console.log("created");
console.log("key:" + this.key);
},
beforeMount: function() {
console.log("beforeMount");
console.log("key:" + this.key);
},
mounted: function() {
console.log("mounted");
console.log("key:" + this.key);
},
beforeUpdate: function() {
console.log("beforeUpdate");
console.log("key:" + this.key);
},
updated: function() {
console.log("updated");
console.log("key:" + this.key);
},
beforeDestroy: function() {
console.log("beforeDestroy");
console.log("key:" + this.key);
},
destroyed: function() {
console.log("destroyed");
console.log("key:" + this.key);
}
});
</script>
Vue 组件化开发
<div id="app">
<button-counter></button-counter>
</div>
<script>
Vue.component('button-counter', {
// 组件模板必须只包含一个根元素
template: '<button @click="handle()">点击了{{count}}次</button>',
// 组件的 data 必须是一个函数
data: function() {
return {
count: 0
}
},
methods: {
handle: function() {
this.count++;
}
}
})
var vm = new Vue({
el: '#app'
})
</script>
<div id="app">
<hello-world></hello-world>
<hello-blu></hello-blu>
</div>
<script>
// 局部组件只能在定义它的父组件中使用
var HelloBLU = {
data: function() {
return {
msg: 'Hello,BLU!'
}
},
template: '<div>{{msg}}</div>'
};
var HelloWorld = {
data: function() {
return {
msg: 'Hello,World!'
}
},
template: '<div>{{msg}}</div>'
};
var vm = new Vue({
el: '#app',
components: {
'hello-world': HelloWorld,
'hello-blu': HelloBLU
}
})
</script>
注意点1:
如果在子组件 props 中接收的参数命名为驼峰形式(例如:menuTitle)
则父组件给子组件传递的参数写法必须为短横杠形式(例如::menu-title=“xxx”)
但如果使用的是字符串模板的形式,则该不存在该限制
注意点2:
如果父组件传递的是 num=‘12’,则子组件接收到的是字符串形式的‘12’
如果父组件传递的是 :num=‘12’,则子组件接收到的是数值类型的12
如果父组件传递的是 pboo=‘true’,则子组件接收到的是字符串形式的‘true’
如果父组件传递的是 :pboo=‘true’,则子组件接收到的是布尔类型的true
<div id="app">
<blu title="来自父组件的值"></blu>
<blu :title="ptitle" :content="pcontent"></blu>
</div>
<script>
Vue.component('blu', {
template: '<div>{{msg + "----" + title + "----" + content}}</div>',
props: ['title', "content"],
data: function() {
return {
msg: '子组件本身的数据'
}
}
})
var vm = new Vue({
el: '#app',
data: {
ptitle: '动态绑定的标题',
pcontent: '动态绑定的内容'
}
})
</script>
注:通过 props 传递的值是单向的,虽然可以,但千万不要通过修改 props 传过来的值来直接修改父组件的值
Vue 可能会报如下警告:
[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value.
[Vue警告]:避免直接更改prop,因为每当父组件重新渲染时,该值都会被覆盖。 而是使用基于属性值的数据或计算属性。
<div id="app">
<!-- 父组件监听子组件发起的自定义事件并调用对应的方法,$event代表子组件传过来的参数值 -->
<blu :parr='parr' :pnum='pnum' @add-lemon="addlemon" @add-num="add($event)"></blu>
</div>
<script>
Vue.component('blu', {
template: `
<div>
<ul>
<li :key='index' v-for='(item,index) in parr'>{{item}}</li>
</ul>
<div>{{pnum}}</div>
<div><button @click='parr.push("lemon")'>不要通过这种方式修改父组件中的值</button></div>
<div><button @click='pnum++'>不要通过这种方式修改父组件中的值</button></div>
<div><button @click='$emit("add-lemon")'>子组件发起add-lemon事件</button></div>
<div><button @click='$emit("add-num",1000)'>子组件发起add-num事件,并传递一个参数1000</button></div>
</div>
`,
props: ['parr', 'pnum']
})
var vm = new Vue({
el: '#app',
data: {
pnum: 10,
parr: ["orange", "apple", "bunana"]
},
methods: {
addlemon: function() {
this.parr.push("lemon");
},
add: function(val) {
this.pnum = val;
}
}
})
</script>
<div id="app">
<div>父组件<button @click="handle">销毁事件</button></div>
<blu-a></blu-a>
<blu-b></blu-b>
</div>
<script>
//定义全局事件中心
var hub = new Vue();
Vue.component('blu-a', {
template: `
<div>
<div>A:{{num}}</div>
<div>
<button @click="handle()">点击</button>
</div>
</div>
`,
data: function() {
return {
num: 0
}
},
methods: {
handle: function() {
hub.$emit('b-event', 1)
}
},
mounted: function() {
//监听事件
hub.$on('a-event', (val) => {
this.num += val;
})
}
}),
Vue.component('blu-b', {
template: `
<div>
<div>B:{{num}}</div>
<div>
<button @click="handle()">点击</button>
</div>
</div>
`,
data: function() {
return {
num: 0
}
},
methods: {
handle: function() {
hub.$emit('a-event', 10)
}
},
mounted: function() {
//监听事件
hub.$on('b-event', (val) => {
this.num += val;
})
}
})
var vm = new Vue({
el: '#app',
data: {},
methods: {
handle: function() {
hub.$off('a-event');
hub.$off('b-event');
}
}
})
</script>
点击组件A的按钮,组件B的数字加1,点击组件B的按钮,组件A的数字加10,点击父组件的按钮,两个子组件按钮失效:
组件插槽基本用法:
<div id="app">
<blu>404</blu>
<blu>有一个错误信息</blu>
<blu></blu>
</div>
<script>
Vue.component('blu', {
template: `
<div>
<strong>ERROR:</strong><slot>默认内容</slot>
</div>
`
})
var vm = new Vue({
el: '#app',
data: {}
})
</script>
具名插槽用法:
指定了 slot 的标签会插入到指定的插槽位置,没有指定的会插入到默认插槽
<div id="app">
<blu>
<p slot="header">标题内容</p>
<p>主要内容1</p>
<p>主要内容2</p>
<p slot="footer">底部内容</p>
</blu>
</div>
<script>
Vue.component('blu', {
template: `
<div>
<slot name='header'></slot>
<slot></slot>
<slot name='footer'></slot>
</div>
`
})
var vm = new Vue({
el: '#app',
data: {}
})
</script>
父组件通过作用域插槽获取子组件的值:
<div id="app">
<blu :list='list'>
<!-- 父组件通过slotProps接收子组件传来的值 -->
<template slot-scope='slotProps'>
<strong v-if='slotProps.info.id==2' class="current">{{slotProps.info.name}}</strong>
<span v-else>{{slotProps.info.name}}</span>
</template>
</blu>
</div>
<script>
Vue.component('blu', {
// 子组件将数据绑定至info
template: `
<div>
<li :key='item.id' v-for='item in list'>
<slot :info="item"></slot>
</li>
</div>
`,
props: ['list']
})
var vm = new Vue({
el: '#app',
data: {
list: [{
id: 1,
name: 'apple'
}, {
id: 2,
name: 'banana'
}, {
id: 3,
name: 'orange'
}]
}
})
</script>
<style type="text/css">
.current {
color: red;
}
</style>
Axios 异步通信
- 1. 引入 Axios 的 js
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
- 2. 准备 json 文件
{
"name": "BLU",
"url": "http://www.baidu.com",
"page": 1,
"address": {
"country": "China",
"city": "南京",
"street": "安德门大街"
}
}
- 3. Axios 异步请求获取数据
<div id="app" v-clock>
<div>{{info.name}}</div>
<div>{{info.address.country}}</div>
<div>{{info.address.city}}</div>
<div>{{info.address.street}}</div>
<a v-bind:href="info.url">链接</a>
</div>
<script>
var vm = new Vue({
el: "#app",
data() {
return {
info: {
name: null,
address: {
country: null,
city: null,
street: null
},
url: null
}
}
},
mounted(){
axios.get('data.json').then(response=>(this.info=response.data));
}
});
</script>
利用 v-clock 解决闪烁问题
<style>
[v-clock]{
display: none;
}
</style>
- 4. 结果
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">
<div>
<router-link to="/a">link A</router-link>
<router-link to="/b">link B</router-link>
</div>
<div>
<!-- 路由占位符 -->
<router-view></router-view>
</div>
</div>
<script>
var Acomponent = {
template: '<h1>A component content</h1>'
}
var Bcomponent = {
template: '<h1>B component content</h1>'
}
//创建路由实例对象
var router = new VueRouter({
routes: [{
path: '/',
redirect: '/a'
}, {
path: '/a',
component: Acomponent
}, {
path: '/b',
component: Bcomponent
}]
})
var vm = new Vue({
el: '#app',
data: {},
//挂载路由实例对象
router: router
})
</script>
<div id="app">
<div>
<router-link to="/a">link A</router-link>
<router-link to="/b">link B</router-link>
</div>
<div>
<router-view></router-view>
</div>
</div>
<script>
var Acomponent = {
template: '<h1>A 组件内容</h1>'
}
var Bcomponent = {
template: `
<div>
<h1>B 组件</h1>
<div>
<router-link to="/ba">链接1</router-link>
<router-link to="/bb">链接2</router-link>
</div>
<router-view/>
</div>`,
}
var BAComponent = {
template: '<div>B中的a组件</div>'
}
var BBComponent = {
template: '<div>B中的b组件</div>'
}
var router = new VueRouter({
routes: [{
path: '/',
redirect: '/a'
}, {
path: '/a',
component: Acomponent
}, {
path: '/b',
component: Bcomponent,
children: [{
path: '/ba',
component: BAComponent
}, {
path: '/bb',
component: BBComponent
}]
}]
})
var vm = new Vue({
el: '#app',
data: {},
router: router
})
</script>
<div id="app">
<div>
<router-link to="/user/1">User1</router-link>
<router-link to="/user/2">User2</router-link>
<router-link to="/user/3">User3</router-link>
</div>
<div>
<router-view></router-view>
</div>
</div>
<script>
var User = {
template: '<div><p> User的id是:{{$route.params.id}} </p></div>'
}
var router = new VueRouter({
routes: [{
path: '/user/:id',
component: User
}]
})
var vm = new Vue({
el: '#app',
data: {},
router: router
})
</script>
注:使用 $route 进行路由组件传参耦合性高,不灵活,你还可以使用以下方式传参:
<script>
var User = {
props: ['id', 'uname', 'age'],
template: '<div><p> User的id是:{{id}} 用户名是:{{uname}} 年龄是: {{age}}</p></div>'
}
var router = new VueRouter({
routes: [{
path: '/user/:id',
component: User,
props: route => ({
uname: 'zhangsan',
age: '20',
id: route.params.id
})
}]
})
var vm = new Vue({
el: '#app',
data: {},
router: router
})
</script>
<div id="app">
<div>
<router-link to="/user">User</router-link>
</div>
<div>
<router-view></router-view>
</div>
</div>
<script>
var User = {
template:
`<div>
<h1>User 组件</h1>
<button @click="goRegister">点击进入注册组件</button>
</div>`,
methods: {
goRegister: function() {
this.$router.push('/register');
}
}
}
var Register = {
template:
`<div>
<p>注册组件</p>
<button @click="goBack">点击返回</button>
</div>`,
methods: {
goBack: function() {
this.$router.go(-1);
}
}
}
var router = new VueRouter({
routes: [{
path: '/user',
component: User
}, {
path: '/register',
component: Register
}]
})
var vm = new Vue({
el: '#app',
data: {},
router: router
})
</script>
更多推荐
所有评论(0)