python 全栈开发,Day89(sorted面试题,Pycharm配置支持vue语法,Vue基础语法,小清单练习)
一、sorted面试题
面试题:
[11, 33, 4, 2, 11, 4, 9, 2] 去重并保持原来的顺序
答案1:
list1 = [11, 33, 4, 2, 11, 4, 9, 2]
ret = set(list1)
list2 = []
for i in list1:
if i not in list2:
list2.append(i) print(list2)
执行输出:
[11, 33, 4, 2, 9]
答案2:
list1 = [11, 33, 4, 2, 11, 4, 9, 2]
ret = list(set(list1))
ret2 = sorted(ret,key=list1.index)
print(ret2)
执行输出:
[11, 33, 4, 2, 9]
说明:list1.index接收的参数,是ret里面的每一个元素。
index() 函数用于从列表中找出某个值第一个匹配项的索引位置。
扩展题:
按照年龄从小到大排序
list3 = [{"name":"zhang","age":30},{"name":"lisi","age":18},{"name":"wang","age":29}]
答案:
list3 = [{"name":"zhang","age":30},{"name":"lisi","age":18},{"name":"wang","age":29}]
ret3 = sorted(list3,key=lambda x:x["age"])
print(ret3)
执行输出:
[{'age': 18, 'name': 'lisi'}, {'age': 29, 'name': 'wang'}, {'age': 30, 'name': 'zhang'}]
二、Pycharm配置支持vue语法
PyCharm 2017.1 EAP 8 发布了,这是 PyCharm 2017.1 的第 8 个 Early Access Program (EAP) 版。本次主要更新如下:
新特性:
Vue.js 初始支持。Vue 是一个 MVVM(Model-View-ViewModel)JavaScript 框架,它变得越来越流行。要使用该功能,需要先安装 Vue.js 插件。可通过 Settings | Plugins | Install JetBrains Plugins,然后选择 Vue.js 进行安装。(仅限专业版使用)
点击File-->Settings,搜索vue
点击安装
重启pycharm
再次查看,就有了
三、Vue基础语法
Vue 实例
创建一个 Vue 实例
每个 Vue 应用都是通过用 Vue
函数创建一个新的 Vue 实例开始的:
语法:
var vm = new Vue({
// 选项
})
数据与方法
当一个 Vue 实例被创建时,它向 Vue 的响应式系统中加入了其 data
对象中能找到的所有的属性。当这些属性的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。
举例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<p>name:{{name}}</p>
<span>age:{{age}}</span>
</div>
<script>
// 我们的数据对象
var d = {name:'xiao',age:23};
// 该对象被加入到一个 Vue 实例中
var app = new Vue({
el:"#app", //关联dom对象
data:d
}) </script>
</body>
</html>
访问网页:
当这些数据改变时,视图会进行重渲染。值得注意的是只有当实例被创建时 d
中存在的属性才是响应式的。
举例:
使用浏览器控制台修改age时,页面会发生改变
模板语法
Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。所有 Vue.js 的模板都是合法的 HTML ,所以能被遵循规范的浏览器和 HTML 解析器解析。
在底层的实现上,Vue 将模板编译成虚拟 DOM 渲染函数。结合响应系统,Vue 能够智能地计算出最少需要重新渲染多少组件,并把 DOM 操作次数减到最少。
如果你熟悉虚拟 DOM 并且偏爱 JavaScript 的原始力量,你也可以不用模板,直接写渲染 (render) 函数,使用可选的 JSX 语法。
原始 HTML
双大括号会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML,你需要使用 v-html
指令:
举例:使用普通方法渲染
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<p>{{message}}</p>
</div>
<script>
var app = new Vue({
el:"#app", //关联dom对象
data:{
message:'<a href="http://www.py3study.com/">点击</a>'
}
}) </script>
</body>
</html>
刷新网页,效果如下:
网页的内容,并不是我们想要的,它应该是一个a标签才对。
修改html,使用v-html。注意:不需要使用{{ }}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<p v-html="message"></p>
</div>
<script>
var app = new Vue({
el:"#app", //关联dom对象
data:{
message:'<a href="http://www.py3study.com/">点击</a>'
}
}) </script>
</body>
</html>
刷新网页,效果如下:
使用 JavaScript 表达式
迄今为止,在我们的模板中,我们一直都只绑定简单的属性键值。但实际上,对于所有的数据绑定,Vue.js 都提供了完全的 JavaScript 表达式支持。
{{ number + 1 }} {{ ok ? 'YES' : 'NO' }} {{ message.split('').reverse().join('') }} <div v-bind:id="'list-' + id"></div>
这些表达式会在所属 Vue 实例的数据作用域下作为 JavaScript 被解析。有个限制就是,每个绑定都只能包含单个表达式。
举例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!-- 使用空格切割,reverse颠倒数组中元素的顺序,join('')将数组转换为字符串 -->
<p>{{ message.split('').reverse().join('') }}</p>
</div>
<script>
var app = new Vue({
el:"#app", //关联dom对象
data:{
message:'旺财'
}
}) </script>
</body>
</html>
刷新网页,效果如下:
指令
指令 (Directives) 是带有 v-
前缀的特殊特性。指令特性的值预期是单个 JavaScript 表达式 (v-for
是例外情况,稍后我们再讨论)。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。
举例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!--判断ok变量是否为true-->
<p v-if="ok">带你装逼,带你飞</p>
</div>
<script>
var app = new Vue({
el:"#app", //关联dom对象
data:{
ok:true
}
}) </script>
</body>
</html>
这里,v-if
指令将根据表达式 ok
的值的真假来插入/移除 <p>
元素。
刷新网页,效果如下:
如果ok的值为false,那么就不会显示p标签
查看网页的html代码,发现p标签消失了
参数
一些指令能够接收一个“参数”,在指令名称之后以冒号表示。例如,v-bind
指令可以用于响应式地更新 HTML 特性:
语法:
<a v-bind:href="url">...</a>
在这里 href
是参数,告知 v-bind
指令将该元素的 href
特性与表达式 url
的值绑定。
举例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<a v-bind="url">来嘛,点我呀!</a>
</div>
<script>
var app = new Vue({
el:"#app", //关联dom对象
data:{
url:'http://www.py3study.com/'
}
}) </script>
</body>
</html>
刷新网页,效果如下:
网页是不能点击的,绑定href特性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<a v-bind:href="url">来嘛,点我呀!</a>
</div>
<script>
var app = new Vue({
el:"#app", //关联dom对象
data:{
url:'http://www.py3study.com/'
}
}) </script>
</body>
</html>
刷新网页,效果如下:
另一个例子是 v-on
指令,它用于监听 DOM 事件:
语法:
<a v-on:click="doSomething">...</a>
在这里参数是监听的事件名。我们也会更详细地讨论事件处理。
举例:阻止默认的表单提交,使用自定义的方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!-- 监听submit事件,触发onSubmit(自定义方法) -->
<form action="" v-on:submit.prevent="onSubmit">
<input type="text" name="name">
<input type="submit" value="提交">
</form>
</div>
<script>
var app = new Vue({
el:"#app", //关联dom对象
data:{
url:'http://www.py3study.com/'
},
//定义方法
methods:{
onSubmit:function () {
alert("不许刷新页面")
}
}
}) </script>
</body>
</html>
刷新网页,点击提交,效果如下:
计算属性和侦听器
计算属性
模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。例如:
<div id="example">
{{ message.split('').reverse().join('') }}
</div>
在这个地方,模板不再是简单的声明式逻辑。你必须看一段时间才能意识到,这里是想要显示变量 message
的翻转字符串。当你想要在模板中多次引用此处的翻转字符串时,就会更加难以处理。
所以,对于任何复杂逻辑,你都应当使用计算属性。
举例:普通写法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<p>{{ message.split('').reverse().join('') }}</p>
</div>
<script>
var app = new Vue({
el:"#app", //关联dom对象
data:{
message:'旺财'
},
}) </script>
</body>
</html>
上面的代码,看这不够简洁。涉及到复杂逻辑时,应该使用计算属性。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<p>{{ reversedMessage }}</p>
</div>
<script>
var app = new Vue({
el: "#app", //关联dom对象
data: {
message: '旺财'
},
//定义计算属性
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 app 实例
return this.message.split('').reverse().join('')
}
}
}) </script>
</body>
</html>
刷新网页,效果同上!
计算属性缓存 vs 方法
你可能已经注意到我们可以通过在表达式中调用方法来达到同样的效果:
<p>Reversed message: "{{ reversedMessage() }}"</p>
在组件中
// 在组件中
methods: {
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}
我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。这就意味着只要 message
还没有发生改变,多次访问 reversedMessage
计算属性会立即返回之前的计算结果,而不必再次执行函数。
举例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<p>{{ reversedMessage }}</p>
<!-- 调用方法,使用括号 -->
<p>{{reversedMessage2()}}</p>
</div>
<script>
var app = new Vue({
el: "#app", //关联dom对象
data: {
message: '旺财'
},
//定义计算属性
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 app 实例
console.log("这是计算属性...");
return this.message.split('').reverse().join('')
}
},
methods:{
reversedMessage2:function () {
console.log("这是方法...");
return this.message.split('').reverse().join('')
}
},
}) </script>
</body>
</html>
刷新网页,使用浏览器控制台,修改message的值。并分别调用属性和方法。
发现,调用计算属性时,它没有执行console.log代码。而调用方法时,执行了console.log代码。
所以:计算属性,只要数据不变化,它不会执行,直接使用缓存。
计算属性 vs 侦听属性
Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性。当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch
——特别是如果你之前使用过 AngularJS。然而,通常更好的做法是使用计算属性而不是命令式的 watch
回调。细想一下这个例子:
html代码:
<div id="demo">{{ fullName }}</div>
js代码:
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar'
},
watch: {
firstName: function (val) {
this.fullName = val + ' ' + this.lastName
},
lastName: function (val) {
this.fullName = this.firstName + ' ' + val
}
}
})
上面代码是命令式且重复的。将它与计算属性的版本进行比较:
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar'
},
computed: {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
}
})
好得多了,不是吗?
举例:显示全名
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>侦听器</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body> <div id="app">
<p>{{quanming2}}</p> </div> <script>
var app = new Vue({
el: "#app",
data: {
ming: '海燕', //名
xing: '赵', //姓
quanming: '赵 世奇' //姓名
},
computed:{
// 计算属性
quanming2: function () {
//组合姓名
return this.xing + " " + this.ming
}
},
watch: {
xing: function (val) {
//当姓改变时,更新全名
this.quanming = val + " " + this.ming
},
ming: function (val) {
//当名改变时,更新全名
this.quanming = this.xing + " " + val
}
}
})
</script> </body>
</html>
访问网页,效果如下:
使用浏览器控制台,修改姓
使用浏览器控制台,修改名
Class 与 Style 绑定
操作元素的 class 列表和内联样式是数据绑定的一个常见需求。因为它们都是属性,所以我们可以用 v-bind
处理它们:只需要通过表达式计算出字符串结果即可。不过,字符串拼接麻烦且易错。因此,在将 v-bind
用于 class
和 style
时,Vue.js 做了专门的增强。表达式结果的类型除了字符串之外,还可以是对象或数组。
绑定 HTML Class
对象语法
我们可以传给 v-bind:class
一个对象,以动态地切换 class:
<div v-bind:class="{ active: isActive }"></div>
上面的语法表示 active
这个 class 存在与否将取决于数据属性 isActive
的 truthiness。
你可以在对象中传入更多属性来动态切换多个 class。此外,v-bind:class
指令也可以与普通的 class 属性共存。
举例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
/*红色圆*/
.c {
height: 150px;
width: 150px;
border-radius: 50%;
background-color: red;
}
/*绿色背景*/
.c1 {
background-color: green;
}
</style>
</head>
<body>
<div id="app">
<!-- 当ok的值为true时,增加class属性c1 -->
<div class="c" v-bind:class="{c1:ok}"></div>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
ok: true,
},
})
</script>
</body>
</html>
刷新网页,效果如下:
使用控制台工具,修改ok的值
如何做到,点击圆时,就变换颜色呢?
将当前值取反就可以了,使用!this.ok
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
/*红色圆*/
.c {
height: 150px;
width: 150px;
border-radius: 50%;
background-color: red;
}
/*绿色背景*/
.c1 {
background-color: green;
}
</style>
</head>
<body>
<div id="app">
<!-- 当ok的值为true时,增加class属性c1。监听点击事件 -->
<div class="c" v-bind:class="{c1:ok}" v-on:click="change"></div>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
ok: true,
},
methods:{
change:function () {
//!this.ok 表示取反
this.ok = !this.ok
}
}
})
</script>
</body>
</html>
刷新网页,效果如下:
条件渲染
v-if
在字符串模板中,比如 Handlebars,我们得像这样写一个条件块:
<!-- Handlebars 模板 -->
{{#if ok}}
<h1>Yes</h1>
{{/if}}
在 Vue 中,我们使用 v-if
指令实现同样的功能:
<h1 v-if="ok">Yes</h1>
也可以用 v-else
添加一个"else 块":
<h1 v-if="ok">Yes</h1>
<h1 v-else>No</h1>
v-else
元素必须紧跟在带 v-if
或者 v-else-if
的元素的后面,否则它将不会被识别。
举例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
/*红色圆*/
.c {
height: 150px;
width: 150px;
border-radius: 50%;
background-color: red;
}
/*绿色背景*/
.c1 {
background-color: green;
}
</style>
</head>
<body>
<div id="app">
<p v-if="ok">想要带你去浪漫的土耳其</p>
<p v-else>呵呵,python学不好,还想泡妹子,做梦!</p>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
ok: true,
},
})
</script>
</body>
</html>
刷新网页,效果如下:
使用浏览器控制台,修改ok的值
使用 v-if
条件渲染分组
因为 v-if
是一个指令,所以必须将它添加到一个元素上。但是如果想切换多个元素呢?此时可以把一个 <template>
元素当做不可见的包裹元素,并在上面使用 v-if
。最终的渲染结果将不包含 <template>
元素。
<template v-if="ok">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
举例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<template v-if="ok">
<p>世情薄,人情恶,雨送黄昏花易落</p>
<p>晓风干,泪痕残</p>
<p>欲笺心事,独语斜阑</p>
<p>难,难,难!</p>
</template>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
ok: true,
},
})
</script>
</body>
</html>
刷新网页,效果如下:
查看浏览器html代码
v-show
另一个用于根据条件展示元素的选项是 v-show
指令。用法大致一样:
<h1 v-show="ok">Hello!</h1>
不同的是带有 v-show
的元素始终会被渲染并保留在 DOM 中。v-show
只是简单地切换元素的 CSS 属性 display
。
注意,v-show
不支持 <template>
元素,也不支持 v-else
。
举例:
使用浏览器工具,修改ok的值
发现消失了,查看html代码,增加了属性display:none
v-if
vs v-show
v-if
是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
v-if
也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
相比之下,v-show
就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
一般来说,v-if
有更高的切换开销,而 v-show
有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show
较好;如果在运行时条件很少改变,则使用 v-if
较好。
列表渲染
用 v-for
把一个数组对应为一组元素
我们用 v-for
指令根据一组数组的选项列表进行渲染。v-for
指令需要使用 item in items
形式的特殊语法,items
是源数据数组并且 item
是数组元素迭代的别名。
html代码:
<ul id="example-1">
<li v-for="item in items">
{{ item.message }}
</li>
</ul>
js代码:
var example1 = new Vue({
el: '#example-1',
data: {
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})
举例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<ul>
<li v-for="i in list">{{ i }}</li>
</ul>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
list: [
"吃饭","睡觉","打豆豆"
],
},
})
</script>
</body>
</html>
刷新网页,效果如下:
增加一个元素
一个对象的 v-for
你也可以用 v-for
通过一个对象的属性来迭代。
html代码:
<ul id="v-for-object" class="demo">
<li v-for="value in object">
{{ value }}
</li>
</ul>
js代码:
new Vue({
el: '#v-for-object',
data: {
object: {
firstName: 'John',
lastName: 'Doe',
age: 30
}
}
})
举例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<ul>
<li v-for="v,k,i in obj">No {{ i }}:{{k}}:{{v}}</li>
</ul>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
obj: {
name:"xiao",age:23
}
},
})
</script>
</body>
</html>
刷新网页,效果如下:
表单输入绑定
基础用法
你可以用 v-model
指令在表单 <input>
及 <textarea>
元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但 v-model
本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。
v-model 会忽略所有表单元素的 value、checked、selected 特性的初始值而总是将 Vue 实例的数据作为数据来源。你应该通过 JavaScript 在组件的 data 选项中声明初始值。
文本
<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>
举例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="message">
<p>{{message}}</p>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
message:''
},
})
</script>
</body>
</html>
刷新网页,效果如下:
复选框
单个复选框,绑定到布尔值:
html代码:
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>
多个复选框,绑定到同一个数组:
html代码:
<div id='example-3'>
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="checkedNames">
<label for="john">John</label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
<label for="mike">Mike</label>
<br>
<span>Checked names: {{ checkedNames }}</span>
</div>
js代码:
new Vue({
el: '#example-3',
data: {
checkedNames: []
}
})
举例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<div id='example-3'> <input type="checkbox" id="jack" value="basketball" v-model="hobby">
<label for="jack">篮球</label> <input type="checkbox" id="john" value="football" v-model="hobby">
<label for="john">足球</label> <input type="checkbox" id="mike" value="doublecolorball" v-model="hobby">
<label for="mike">双色球</label>
<br> <span>我的爱好: {{ hobby }}</span>
</div>
</div> <script>
var app = new Vue({
el: "#app",
data: {
message: '',
hobby:[]
}
})
</script>
</body>
</html>
刷新网页,效果如下:
修饰符
.trim
如果要自动过滤用户输入的首尾空白字符,可以给 v-model
添加 trim
修饰符:
语法:
<input v-model.trim="msg">
举例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model.trim="message">
<p>{{message}}</p>
</div> <script>
var app = new Vue({
el: "#app",
data: {
message: '',
}
})
</script>
</body>
</html>
刷新网页,效果如下:
查看网页html,发现左右2边的空格,给过滤掉了!
四、小清单练习
先来看一下效果:
准备html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>小清单</title>
<!--bootstrap-->
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet">
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body> <div class="container">
<div class="row">
<!--col-md-offset-3 向右移动3个格子。-->
<div id="app" class="col-md-6 col-md-offset-3" style="margin-top: 70px">
<!--面板开始-->
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">小清单</h3>
</div>
<div class="panel-body">
<!-- 输入框 开始-->
<div class="input-group">
<input type="text" class="form-control" placeholder="Search for..."/>
<span class="input-group-btn">
<button class="btn btn-default" type="button">
<!--glyphicon glyphicon-plus加号图标-->
<span class="glyphicon glyphicon-plus"></span>
</button>
</span>
</div>
<!-- 输入框 结束-->
<hr/>
<!--列表组 开始-->
<div class="list-group">
<div class="list-group-item">
<!--glyphicon glyphicon-ok-sign勾选图标-->
<span class="glyphicon glyphicon-ok-sign"> </span>
吃饭
<!--glyphicon glyphicon-remove删除图标,pull-right表示右对齐-->
<span class="glyphicon glyphicon-remove pull-right"></span>
</div>
</div>
<!--列表组 结束-->
</div>
</div>
<!--面板结束-->
</div>
</div>
</div> </body>
</html>
刷新网页,效果如下:
点击勾选变绿
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>小清单</title>
<!--bootstrap-->
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet">
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
/*first-child选择属于其父元素的首个子元素的每个 <span> 元素,并为其设置样式:*/
.c1> span:first-child {
color: green;
}
</style>
</head>
<body> <div class="container">
<div class="row">
<!--col-md-offset-3 向右移动3个格子。-->
<div id="app" class="col-md-6 col-md-offset-3" style="margin-top: 70px">
<!--面板开始-->
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">小清单</h3>
</div>
<div class="panel-body">
<!-- 输入框 开始-->
<div class="input-group">
<input type="text" class="form-control" placeholder="Search for..."/>
<span class="input-group-btn">
<button class="btn btn-default" type="button">
<!--glyphicon glyphicon-plus加号图标-->
<span class="glyphicon glyphicon-plus"></span>
</button>
</span>
</div>
<!-- 输入框 结束-->
<hr/>
<!--列表组 开始-->
<div class="list-group">
<!--v-bind:class动态地增加 class c1-->
<div class="list-group-item" v-bind:class="{c1:ok}">
<!--glyphicon glyphicon-ok-sign勾选图标-->
<!--v-on:click绑定点击事件-->
<span v-on:click="bianlv" class="glyphicon glyphicon-ok-sign"> </span>
吃饭
<!--glyphicon glyphicon-remove删除图标,pull-right表示右对齐-->
<span class="glyphicon glyphicon-remove pull-right"></span>
</div>
</div>
<!--列表组 结束-->
</div>
</div>
<!--面板结束-->
</div>
</div>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
ok:false,
},
methods: {
bianlv:function () {
this.ok=true; //更改为true
}
}
})
</script>
</body>
</html>
刷新网页,点击勾选按钮,就会变绿
当ok值为true时增加class c1,否则没有class c1
无限增加选项
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>小清单</title>
<!--bootstrap-->
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet">
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
/*first-child选择属于其父元素的首个子元素的每个 <span> 元素,并为其设置样式:*/
.c1> span:first-child {
color: green;
}
</style>
</head>
<body> <div class="container">
<div class="row">
<!--col-md-offset-3 向右移动3个格子。-->
<div id="app" class="col-md-6 col-md-offset-3" style="margin-top: 70px">
<!--面板开始-->
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">小清单</h3>
</div>
<div class="panel-body">
<!-- 输入框 开始-->
<div class="input-group">
<!--v-model创建双向数据绑定,它会根据控件类型自动选取正确的方法来更新元素-->
<input v-model="newItem.title" type="text" class="form-control" placeholder="Search for..."/>
<span class="input-group-btn">
<!--v-on:click监听点击事件,add表示自定义的方法-->
<button v-on:click="add" class="btn btn-default" type="button">
<!--glyphicon glyphicon-plus加号图标-->
<span class="glyphicon glyphicon-plus"></span>
</button>
</span>
</div>
<!-- 输入框 结束-->
<hr/>
<!--列表组 开始-->
<div class="list-group">
<!--用 v-for 把一个数组对应为一组元素,item为元素,index为索引-->
<!--v-bind:class动态地增加 class c1,当item.ok为true时,增加class-->
<div v-for="(item,index) in todoList" v-bind:class="{c1: item.ok}" class="list-group-item">
<!--v-on:click绑定点击事件,index表示for循环的索引-->
<!--glyphicon glyphicon-ok-sign勾选图标-->
<span v-on:click="bianlv(index)" class="glyphicon glyphicon-ok-sign"> </span>
<!--显示title-->
{{item.title}}
<!--glyphicon glyphicon-remove删除图标,pull-right表示右对齐-->
<span class="glyphicon glyphicon-remove pull-right"></span>
</div>
</div>
<!--列表组 结束-->
</div>
</div>
<!--面板结束-->
</div>
</div>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
todoList: [], //空数组
newItem: { //每一增加的项目,都是独立的
title: '', //标题默认值
ok: false, //默认为false,为true时,变成绿色
}
},
methods: {
bianlv:function (index) { //变绿
// alert(index);
// 在这里面怎么知道我点击的是哪个待办事项
// 根据索引去todoList里面找对应的待办事项,把它的ok属性变为投入true
this.todoList[index].ok = true
},
add:function () {
// Object.assign({},obj,obj1);表示深拷贝,花括号叫目标对象,后面的obj、obj1是源对象
// 把新待办事项添加到todoList
// 将this.newItem 深拷贝之后 传到 todoList
var obj = Object.assign({}, this.newItem);
this.todoList.push(obj); //追加到数组中 this.newItem.title = ''; //清空输入框
},
}
})
</script>
</body>
</html>
刷新网页,增加几个,效果如下:
删除选项
删除数组,使用splice
splice() 方法可删除从 index 处开始的零个或多个元素,并且用参数列表中声明的一个或多个值来替换那些被删除的元素。
如果从 arrayObject 中删除了元素,则返回的是含有被删除的元素的数组
举例:
a.splice(1,1) 左边的1,表示从索引值为1的元素开始删除,1对应的元素为22。注意:索引是从0开始计算的
右边的1表示,删除1个元素。也就是把22给删除了。
执行之后,返回的结果是被删除的元素
所以最后查看a时,只有3个元素。
举例:
由于只有参数1,表示将索引为1后面的所有元素删除。
所有a只有一个元素11
修改html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>小清单</title>
<!--bootstrap-->
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet">
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
/*first-child选择属于其父元素的首个子元素的每个 <span> 元素,并为其设置样式:*/
.c1> span:first-child {
color: green;
}
</style>
</head>
<body> <div class="container">
<div class="row">
<!--col-md-offset-3 向右移动3个格子。-->
<div id="app" class="col-md-6 col-md-offset-3" style="margin-top: 70px">
<!--面板开始-->
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">小清单</h3>
</div>
<div class="panel-body">
<!-- 输入框 开始-->
<div class="input-group">
<!--v-model创建双向数据绑定,它会根据控件类型自动选取正确的方法来更新元素-->
<input v-model="newItem.title" type="text" class="form-control" placeholder="Search for..."/>
<span class="input-group-btn">
<!--v-on:click监听点击事件,add表示自定义的方法-->
<button v-on:click="add" class="btn btn-default" type="button">
<!--glyphicon glyphicon-plus加号图标-->
<span class="glyphicon glyphicon-plus"></span>
</button>
</span>
</div>
<!-- 输入框 结束-->
<hr/>
<!--列表组 开始-->
<div class="list-group">
<!--用 v-for 把一个数组对应为一组元素,item为元素,index为索引-->
<!--v-bind:class动态地增加 class c1,当item.ok为true时,增加class-->
<div v-for="(item,index) in todoList" v-bind:class="{c1: item.ok}" class="list-group-item">
<!--v-on:click绑定点击事件,index表示for循环的索引-->
<!--glyphicon glyphicon-ok-sign勾选图标-->
<span v-on:click="bianlv(index)" class="glyphicon glyphicon-ok-sign"> </span>
<!--显示title-->
{{item.title}}
<!--v-on:click绑定点击事件,index表示for循环的索引-->
<!--glyphicon glyphicon-remove删除图标,pull-right表示右对齐-->
<span v-on:click="remove(index)" class="glyphicon glyphicon-remove pull-right"></span>
</div>
</div>
<!--列表组 结束-->
</div>
</div>
<!--面板结束-->
</div>
</div>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
todoList: [], //空数组
newItem: { //每一增加的项目,都是独立的
title: '', //标题默认值
ok: false, //默认为false,为true时,变成绿色
}
},
methods: {
bianlv:function (index) { //变绿
// alert(index);
// 在这里面怎么知道我点击的是哪个待办事项
// 根据索引去todoList里面找对应的待办事项,把它的ok属性变为投入true
this.todoList[index].ok = true
},
add:function () {
// Object.assign({},obj,obj1);表示深拷贝,花括号叫目标对象,后面的obj、obj1是源对象
// 把新待办事项添加到todoList
// 将this.newItem 深拷贝之后 传到 todoList
var obj = Object.assign({}, this.newItem);
this.todoList.push(obj); //追加到数组中 this.newItem.title = ''; //清空输入框
},
remove:function (index) { //删除选项
console.log(index);
//删除一个索引值
this.todoList.splice(index,1)
}
}
})
</script>
</body>
</html>
刷新页面,添加3个元素
然后删除中间一个
它返回的索引为1,表示第二个元素
颜色取消和增加删除线
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>小清单</title>
<!--bootstrap-->
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet">
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
/*first-child选择属于其父元素的首个子元素的每个 <span> 元素,并为其设置样式:*/
.c1> span:first-child {
color: green;
}
/*删除线*/
.c2 {
text-decoration:line-through;
}
</style>
</head>
<body> <div class="container">
<div class="row">
<!--col-md-offset-3 向右移动3个格子。-->
<div id="app" class="col-md-6 col-md-offset-3" style="margin-top: 70px">
<!--面板开始-->
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">小清单</h3>
</div>
<div class="panel-body">
<!-- 输入框 开始-->
<div class="input-group">
<!--v-model创建双向数据绑定,它会根据控件类型自动选取正确的方法来更新元素-->
<input v-model="newItem.title" type="text" class="form-control" placeholder="Search for..."/>
<span class="input-group-btn">
<!--v-on:click监听点击事件,add表示自定义的方法-->
<button v-on:click="add" class="btn btn-default" type="button">
<!--glyphicon glyphicon-plus加号图标-->
<span class="glyphicon glyphicon-plus"></span>
</button>
</span>
</div>
<!-- 输入框 结束-->
<hr/>
<!--列表组 开始-->
<div class="list-group">
<!--用 v-for 把一个数组对应为一组元素,item为元素,index为索引-->
<!--v-bind:class动态地增加 class c1,当item.ok为true时,增加class-->
<div v-for="(item,index) in todoList" v-bind:class="{c1: item.ok}" class="list-group-item">
<!--v-on:click绑定点击事件,index表示for循环的索引-->
<!--glyphicon glyphicon-ok-sign勾选图标-->
<span v-on:click="bianlv(index)" class="glyphicon glyphicon-ok-sign"></span>
<!--显示title-->
<!--v-bind:class,动态增加删除线-->
<span v-on:click="strickout(index)" v-bind:class="{c2: item.to}" style="margin-left: 10px;">{{item.title}}</span> <!--v-on:click绑定点击事件,index表示for循环的索引-->
<!--glyphicon glyphicon-remove删除图标,pull-right表示右对齐-->
<span v-on:click="remove(index)" class="glyphicon glyphicon-remove pull-right"></span>
</div>
</div>
<!--列表组 结束-->
</div>
</div>
<!--面板结束-->
</div>
</div>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
todoList: [], //空数组
newItem: { //每一增加的项目,都是独立的
title: '', //标题默认值
ok: false, //默认为false,为true时,变成绿色
to: false,
}
},
methods: {
bianlv:function (index) { //变绿
// alert(index);
// 在这里面怎么知道我点击的是哪个待办事项
// 根据索引去todoList里面找对应的待办事项,把它的ok属性变为投入true
// !this.todoList[index].ok 表示取反
this.todoList[index].ok = !this.todoList[index].ok
},
add:function () {
// Object.assign({},obj,obj1);表示深拷贝,花括号叫目标对象,后面的obj、obj1是源对象
// 把新待办事项添加到todoList
// 将this.newItem 深拷贝之后 传到 todoList
var obj = Object.assign({}, this.newItem);
this.todoList.push(obj); //追加到数组中 this.newItem.title = ''; //清空输入框
},
remove:function (index) { //删除选项
console.log(index);
//删除一个索引值
this.todoList.splice(index,1)
},
strickout:function (index) { //删除线
console.log(index);
// !this.todoList[index].to 表示取反
this.todoList[index].to = !this.todoList[index].to
}
}
})
</script>
</body>
</html>
刷新网页,效果如下:
python 全栈开发,Day89(sorted面试题,Pycharm配置支持vue语法,Vue基础语法,小清单练习)的更多相关文章
- Python 全栈开发【第0篇】:目录
Python 全栈开发[第0篇]:目录 第一阶段:Python 开发入门 Python 全栈开发[第一篇]:计算机原理&Linux系统入门 Python 全栈开发[第二篇]:Python基 ...
- Python全栈开发【基础三】
Python全栈开发[基础三] 本节内容: 函数(全局与局部变量) 递归 内置函数 函数 一.定义和使用 函数最重要的是减少代码的重用性和增强代码可读性 def 函数名(参数): ... 函数体 . ...
- python 全栈开发,Day99(作业讲解,DRF版本,DRF分页,DRF序列化进阶)
昨日内容回顾 1. 为什么要做前后端分离? - 前后端交给不同的人来编写,职责划分明确. - API (IOS,安卓,PC,微信小程序...) - vue.js等框架编写前端时,会比之前写jQuery ...
- python全栈开发从入门到放弃之迭代器生成器
1.python中的for循环 l = [1,2,3,4,5,6] for i in l: #根据索引取值 print(i) 输出结果: 1 2 3 4 5 6 2.iterable 可迭代的 可迭 ...
- Python全栈开发【面向对象进阶】
Python全栈开发[面向对象进阶] 本节内容: isinstance(obj,cls)和issubclass(sub,super) 反射 __setattr__,__delattr__,__geta ...
- Python全栈开发【面向对象】
Python全栈开发[面向对象] 本节内容: 三大编程范式 面向对象设计与面向对象编程 类和对象 静态属性.类方法.静态方法 类组合 继承 多态 封装 三大编程范式 三大编程范式: 1.面向过程编程 ...
- Python全栈开发【模块】
Python全栈开发[模块] 本节内容: 模块介绍 time random os sys json & picle shelve XML hashlib ConfigParser loggin ...
- Python全栈开发【基础四】
Python全栈开发[基础四] 本节内容: 匿名函数(lambda) 函数式编程(map,filter,reduce) 文件处理 迭代器 三元表达式 列表解析与生成器表达式 生成器 匿名函数 lamb ...
- Python全栈开发【基础二】
Python全栈开发[基础二] 本节内容: Python 运算符(算术运算.比较运算.赋值运算.逻辑运算.成员运算) 基本数据类型(数字.布尔值.字符串.列表.元组.字典) 其他(编码,range,f ...
随机推荐
- Windows环境墙内搭建Go语言集成开发环境
1 安装go环境 太简单略 2 安装vs code 找到微软的官方网站,下载Visual Studio Code,官网地址https://code.visualstudio.com/ 安装完成后进入V ...
- HDU - 3521 An easy Problem(矩阵快速幂)
http://acm.hdu.edu.cn/showproblem.php?pid=3521 题意 对于矩阵A,求e^A的值. 分析 这个定眼一看好像很熟悉,就是泰勒展开,可惜自己的高数已经还给老师了 ...
- Visual Studio Code 常用快捷键
VsCode 快捷键有五种组合方式(科普) Ctrl + Shift + ? : 这种常规组合按钮 Ctrl + V Ctrl +V : 同时依赖一个按键的组合 Shift + V c : 先组合后单 ...
- Grooming Meeting及测试人员所扮演的角色
Grooming Meeting的中文翻译是“梳理会议”,它并不是Scrum框架中标准的会议(标准会议为Planning Meeting, Daily Scrum Meeting, Review Me ...
- JavaScript之不规则Table转化为可定点索引td节点的网格矩阵【插件】
由于解析课程表的缘故,有如下需求: 1. 将任意表格解析成独立的单元格矩阵[本次博文的缘由] 2. 根据矩阵坐标,确定任意一格的节点 /* 表格-->网格化 标记表格的位置及其对应的节点 * ...
- 让 IE9 以下的浏览器支持 Media Queries
1. 如何让 IE9 以下的浏览器支持 css3 的media query 需要用到的 min-width/max-width 属性 css3 的媒体查询 IE 浏览器的支持程度是从 IE9开始支持, ...
- HTML5实现全屏API【进入和退出全屏】
现在主流浏览器基本上实现了全屏效果,但是不同浏览器实现不一样: [进入和退出全屏] // Webkit (works in Safari5.1 and Chrome 15)element.webkit ...
- C - Portals Gym - 102006C (网络流最小割)
题目链接:https://cn.vjudge.net/contest/283918#problem/C 题目大意:T个测试数据,然后给你一个字符串,每一个字符串包括‘s’,‘t’,‘o’,‘#’,‘. ...
- Android UI组件之自定义控件实现IP地址控件
http://www.cnblogs.com/razerlack/p/4273282.html
- SpringBoot整合Email(电子邮件服务)
(1).导入starter依赖 <dependency> <groupId>org.springframework.boot</groupId> <artif ...