一、vue简单示例
一、django模板变量和vue冲突解决 {{ }}如果不可避免的在同一个页面里既有 django 渲染又有 vue 渲染的部分,可有 2 种方式解决方法一:采用 vue 的 delimiters分隔符。new Vue({delimiters: ["{[", "]}"] // 可自定义符号})方法二:建议把 vue 的部分用 {% verbatim %} 包起来。我这里使用这种方法见文档:http
一、django模板变量和vue冲突解决 {{ }}
如果不可避免的在同一个页面里既有 django 渲染又有 vue 渲染的部分,可有 2 种方式解决
方法一:采用 vue 的 delimiters 分隔符。
new Vue({
delimiters: ["{[", "]}"] // 可自定义符号
})
方法二:建议把 vue 的部分用 {% verbatim %} 包起来。我这里使用这种方法
见文档:https://docs.djangoproject.com/en/2.2/ref/templates/builtins/#verbatim
{% verbatim %}
<div>{{ text }}</div>
{% endverbatim %}
二、示例
1、最简单的例子
一个 Vue 应用会将其挂载到一个 DOM 元素上 (对于这个例子是 #app) 然后对其进行完全控制。那个 HTML 是我们的入口,但其余都会发生在新创建的 Vue 实例内部。django部分不多描述了
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src={% static "vue.js" %}></script>
</head>
<body>
{% verbatim %}
<div id="app">
{{ message }}
</div>
{% endverbatim %}
<script>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
</script>
</body>
</html>
访问页面
打开你的浏览器的 JavaScript 控制台 (就在这个页面打开),并修改 app.message 的值,你将看到上例相应地更新。
app.message="hello wangxiaoyu"
2、v-text 指令
用于渲染普通文本,无论何时,绑定的数据对象上 msg属性发生了改变,插值处的内容都会更新。v-text和{{}}表达式渲染数据,不解析标签。
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src={% static "vue.js" %}></script>
</head>
{% verbatim %}
<body>
<div id="app" v-text="message"></div>
<script>
// 数据模板引擎
// v-开头的指令是帮助我们渲染数据用的
new Vue({
el: "#app",
data: {
message: "Hello Vue Text",
}
})
</script>
</body>
{% endverbatim %}
</html>
访问页面
3、v-html 指令
如果你想输出真正的 HTML,你需要使用 v-html指令,v-text仅渲染标签,不能解析 HTML 代码。
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src={% static "vue.js" %}></script>
</head>
{% verbatim %}
<body>
<div id="app" v-html="message"></div>
<script>
// 数据模板引擎
// v-开头的指令是帮助我们渲染数据用的
new Vue({
el: "#app",
data: {
message: "<h1>Hello Vue</h1>",
}
})
</script>
</body>
{% endverbatim %}
</html>
访问页面
4、v-for 指令
可以绑定数组的数据来渲染一个项目列表
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src={% static "vue.js" %}></script>
</head>
{% verbatim %}
<body>
<div id="app">
<ol>
<li v-for="todo in todos">
{{ todo.text }}
</li>
</ol>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
todos: [
{ text: '学习 JavaScript' },
{ text: '学习 Vue' },
{ text: '整个牛项目' }
]
}
})
</script>
</body>
{% endverbatim %}
</html>
访问页面
在控制台里,输入 app.todos.push({ text: ‘新项目’ }),你会发现列表最后添加了一个新项目。
绑定字典,并且获取value、key和index值
5、v-if、v-else-if、v-else 条件判断
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src={% static "vue.js" %}></script>
</head>
{% verbatim %}
<body>
<div id="app">
<div v-if="role == 'wangxiaoyu'">
<h1>欢迎王小雨</h1>
</div>
<div v-else-if="role == 'wangdayu'">
<h1>欢迎王大雨</h1>
</div>
<div v-else>
<h1>欢迎 {{ role }}</h1>
</div>
</div>
<script>
// 数据模板引擎
// v-开头的指令是帮助我们渲染数据用的
var app = new Vue({
el: "#app",
data: {
role: "wangxiaoyu"
}
})
</script>
</body>
{% endverbatim %}
</html>
访问页面
在控制台输入app.role=“wangdayu” 修改数据
匹配到v-else-if="role == 'wangdayu'
,页面也跟着修改了
在控制台输入app.role=“elsetest” 修改数据,此时前面两个都没匹配到,则使用v-else的流程
6、v-show指令控制显示或隐藏
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src={% static "vue.js" %}></script>
</head>
{% verbatim %}
<body>
<div id="app">
<div v-show="isShow">Hello Vue</div>
</div>
<script>
let app = new Vue({
el: "#app",
data: {
isShow: false,
}
})
</script>
</body>
{% endverbatim %}
</html>
上面设置默认不显示,在控制台输入app.isShow=true
,然后可以看到有显示
7、v-bind
v-bind用于绑定数据和元素属性,比方你的class属性,style属性,value属性,href属性等等,只要是属性,就可以用v-bind指令进行绑定。
参考 https://www.cnblogs.com/liuchuanfeng/p/6742631.html
(1)、绑定绑定a标签的href属性
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src={% static "vue.js" %}></script>
</head>
{% verbatim %}
<body>
<div id="app">
<a v-bind:href="jingdong">去京东</a>
</div>
<script>
// 数据模板引擎
// v-开头的指令是帮助我们渲染数据用的
var app = new Vue({
el: "#app",
data: {
jingdong: "https://www.jd.com",
}
})
</script>
</body>
{% endverbatim %}
</html>
访问页面
(2)使用v-bind:class="{ }绑定class属性,例如 v-bind:class="{ blockclass: isBlockclass,center: isCenter }"
,可以在对象中传多个属性,动态绑定多个class
v-bind:class指令可以与普通的class特性共存,由于使用频繁,通常将v-bind:属性名=" “的格式简写成:属性名=” "
先设置一个名称为blockclass的class样式,在div中使用v-bind:class="{ blockclass: isBlockclass }",里面的blockclass就是要绑定的class,isBlockclass的值决定了是否要绑定class,并且v-bind绑定的class也不会覆盖元素上已经存在的test类。
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src={% static "vue.js" %}></script>
<style>
.blockclass {
width: 500px;
height: 500px;
background-color: lawngreen;
}
</style>
</head>
{% verbatim %}
<body>
<div id="app">
<a v-bind:href="jingdong">去京东</a>
<div class="test" v-bind:class="{ blockclass: isBlockclass,center:isCenter }"></div>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
jingdong: "https://www.jd.com",
isBlockclass:true,
isCenter:true,
}
})
</script>
</body>
{% endverbatim %}
</html>
我们可以看到data里面的isActive设成了true,所以最后渲染出来会是这样:
(3)v-bind:class 直接绑定数据里的一个对象
因为v-bind指令的初衷就是为了动态的切换class,如果绑定的对象属性太多的话,就会影响代码的可阅读性了,因此我们很多时候会绑定一个定义在data上的对象,或者绑定一个返回对象的计算属性,可以通过对这个对象的修改来修改class。
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src={% static "vue.js" %}></script>
<style>
.blockclass {
width: 500px;
height: 500px;
background-color: lawngreen;
}
</style>
</head>
{% verbatim %}
<body>
<div id="app">
<a v-bind:href="jingdong">去京东</a>
<div class="test" v-bind:class="classObject"></div>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
jingdong: "https://www.jd.com",
classObject:{ blockclass:true, center:true,}
}
})
</script>
</body>
{% endverbatim %}
</html>
(4)v-bind:class 数组语法、我们可以把一个数组传给v-bind:class,以应用一个class列表,数组里面的变量名表示类名,在vue对象中设置。
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src={% static "vue.js" %}></script>
<style>
.blockclass {
width: 500px;
height: 500px;
background-color: lawngreen;
}
</style>
</head>
{% verbatim %}
<body>
<div id="app">
<a v-bind:href="jingdong">去京东</a>
<div class="test" v-bind:class="[classA,classB]"></div>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
jingdong: "https://www.jd.com",
classA:"blockclass",
classB:"center",
}
})
</script>
</body>
{% endverbatim %}
</html>
8、v-on 用于绑定事件
作用:绑定事件监听器
缩写:@ v-on:click可以缩写为@cli
- List item
ck
预期:Function | Inline Statement | Object
参数:event
如下使用v-on:click="reverseMessage"
绑定click事件执行reverseMessage()这个方法,在vue对象中的methods:{}
字段中新建方法
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src={% static "vue.js" %}></script>
</head>
{% verbatim %}
<body>
<div id="app">
<p>{{ message }}</p>
<button v-on:click="reverseMessage">反转消息</button>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
message: 'Hello Vue!'
},
methods: {
reverseMessage: function () {
this.message = this.message.split('').reverse().join('')
}
}
})
</script>
</body>
{% endverbatim %}
</html>
访问页面
如果方法不需要额外参数,那么方法后的()可以不添加。
如果方法本身中有一个参数,那么会默认将原生事件event参数传递进去
如果需要同时传入某个参数,同时需要event时,可以通过$event传入事件。下面方法中使用es6的写法省略了function
v-on修饰符
Vue提供了修饰符来帮助我们方便的处理一些事件:
.stop - 调用 event.stopPropagation()。
.prevent - 调用 event.preventDefault()。
.{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
.native - 监听组件根元素的原生事件。
.once - 只触发一次回调。
9、v-model 指令实现表单输入和应用状态之间的双向绑定
v-model 指令用来在 input、select、textarea、checkbox、radio 等表单控件元素上创建双向数据绑定,根据表单上的值,自动更新绑定的元素的值。
参考:https://www.cnblogs.com/mark5/p/11603428.html
v-model其实是一个语法糖,它的背后本质上是包含两个操作:
- v-bind绑定一个value属性
- v-on指令给当前元素绑定input事件
<input type="text" v-model="message">
等同于
<input type="text" v-bind:value="message" v-on:input="message = $event.target.value">
(1)、v-model 绑定input输入框
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src={% static "vue.js" %}></script>
</head>
{% verbatim %}
<body>
<div id="app">
<p>{{ message }}</p>
<input v-model="message">
</div>
<script>
var app = new Vue({
el: "#app",
data: {
message: 'Hello Vue!',
},
})
</script>
</body>
{% endverbatim %}
</html>
查看页面
message变量和input输入框和
标签绑定,如果修改输入框的值,则message值有变化,上面的
标签也会跟着修改
(2)、v-model 绑定select单选框
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src={% static "vue.js" %}></script>
</head>
{% verbatim %}
<body>
<div id="app">
<select v-model="selected">
<option value="A被选">A</option>
<option value="B被选">B</option>
<option value="C被选">C</option>
</select>
<p>{{ selected }}</p>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
selected: "",
},
})
</script>
</body>
{% endverbatim %}
</html>
这里selected变量与单选框和
标签进行绑定,可以看到选择后
标签内容也会跟着变化,通过selected也可以设置value默认值,达到默认选择的效果,这里这是的是空字符串,比如要默认选择B,可以设为B的value=“B被选”
(3)、v-model 绑定checkbox复选框
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src={% static "vue.js" %}></script>
</head>
{% verbatim %}
<body>
<div id="app">
<input type="checkbox" id="one" value="value_one" v-model="checkedNames">
<label for="one">选项一</label>
<input type="checkbox" id="two" value="value_two" v-model="checkedNames">
<label for="two">选项二</label>
<input type="checkbox" id="three" value="value_three" v-model="checkedNames">
<label for="three">选项三</label>
<p>{{ checkedNames }}</p>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
checkedNames: [],
},
})
</script>
</body>
{% endverbatim %}
</html>
因为是多选,这里的data中的变量用数组[ ]来表示默认值,选择后同样会进行改变
10、vue指令计算属性
计算属性在vue对象的computed:{}
字段里定义并设置返回值,例如在这里定义了sumScore这个变量,返回值为其他input标签绑定的v-model.number.lazy
值相加。
- 使用
v-model.numbe
指令来绑定input标签,因为input默认都是字符串类型的,如果需要数字类型的则需要加上number。 - 使用
v-model.lazy
,改变input框中的内容并不会使得span中的内容发生变化,此时当输入框失去焦点后触发change事件.控制台中输出相应内容,如果不添加的话,在input中修改是便会每次都触发computed的计算函数,这样有一定的损耗,加上lazy属性后,当输入框数去焦点后才进行计算
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src={% static "vue.js" %}></script>
</head>
{% verbatim %}
<body>
<div id="app">
<table border="1">
<thead>
<tr>
<th>学科</th>
<th>成绩</th>
</tr>
</thead>
<tbody>
<tr>
<td>Python</td>
<td><input type="text" v-model.number.lazy="python"/></td>
</tr>
<tr>
<td>Vue</td>
<td><input type="text" v-model.number.lazy="vue"/></td>
</tr>
<tr>
<td>Go</td>
<td><input type="text" v-model.number.lazy="go"/></td>
</tr>
<tr>
<td>总成绩</td>
<td>{{ sumScore }}</td>
</tr>
</tbody>
</table>
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
python: 88,
vue: 100,
go: 65
},
computed: {
sumScore: function () {
return this.python + this.vue + this.go;
},
},
})
</script>
</body>
{% endverbatim %}
</html>
访问页面
如果进行修改input的值,那么sumScore也会改变,从而显示的值也改变
每个计算属性都包含一个getter和一个setter,在上面的例子中,我们只是使用getter来读取。在某些情况下,你也可以提供一个setter方法(不常用)。
在需要写setter的时候,代码如下
计算属性会进行缓存,如果多次使用时,计算属性只会调用一次
11、vue 监听属性
下面示例创建了两个输入框,data 属性中, kilometers 和 meters 初始值都为 0。watch 对象创建了两个方法 kilometers 和 meters。当我们再输入框输入数据时,watch 会实时监听数据变化并改变自身的值。
- 可以在vue对象的 watch: {}字段中进行设置,例如
watch: {kilometers: function (val) {}}
,监听kilometers属性的变化,function定义的方法中接收变化后的值参数。 - 也可以在vue对象外部,调用vue对象的属性进行设置,例如
app.$watch('kilometers', function (newValue, oldValue) {}
,监听app这个vue对象中kilometers属性的变化,function定义的方法中接收旧的和新的两个值参数。
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src={% static "vue.js" %}></script>
</head>
{% verbatim %}
<body>
<div id="app">
千米 : <input type="text" v-model="kilometers">
米 : <input type="text" v-model="meters">
</div>
<p id="info"></p>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
kilometers: 0,
meters: 0
},
methods: {},
computed: {},
watch: {
kilometers: function (val) {
this.kilometers = val;
this.meters = this.kilometers * 1000
},
meters: function (val) {
this.kilometers = val / 1000;
this.meters = val;
}
}
});
// $watch 是一个实例方法
app.$watch('kilometers', function (newValue, oldValue) {
// 这个回调将在 vm.kilometers 改变后调用
document.getElementById("info").innerHTML = "修改前值为: " + oldValue + ",修改后值为: " + newValue;
})
</script>
</body>
{% endverbatim %}
</html>
访问页面,然后修改input框的值,可以看到有相互转换
三、综合实例 购物车
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<script src="../static/vue.js"></script>
<body>
<style>
thead {
background-color: rgb(243, 243, 243);
}
td,
th {
border: solid 1px rgb(226, 226, 226);
}
table {
border-collapse: collapse;
}
.end {
color: black;
font-size: 30px;
}
</style>
<div id="app">
<table>
<thead>
<tr>
<th></th>
<th>书籍名称</th>
<th>出版日期</th>
<th>价格</th>
<th>购买数量</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item,key) in books">
<td>{{ key+1 }}</td>
<td>{{item.name}}</td>
<td>{{item.publish}}</td>
<td>{{item.price | singlePrice}}</td>
<td>
<!-- 减少数量的按钮,click事件绑定decrement方法 当数量为 1 时不能再减少按钮变为不可用-->
<button @click="decrement(key)" :disabled="item.count===1">-</button>
<button>{{item.count}}</button>
<!-- 增加数量的按钮,click事件绑定increment方法-->
<button @click="increment(key)">+</button>
</td>
<!--移除商品的按钮,click时间绑定remove方法,传入key将当前数组中当前key的商品删除--> <!---->
<td><button @click="remove(key)">移除</button></td>
</tr>
</tbody>
</table>
<!-- 当books数组的长度不为0,显示总价格,如果长度为0则表示商品都被移除了,显示购物车为空 -->
<div class="end">
<div v-if="books.length!==0">
总价格{{totalPrice}}
</div>
<div v-else> 购物车为空 </div>
</div>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
books: [{
name: '《算法导论》',
publish: '2006-9',
price: 85,
count: 1
},
{
name: '《UNIX编程艺术》',
publish: '2006-2',
price: 59,
count: 1
},
{
name: '《编程珠玑》',
publish: '2008-10',
price: 39,
count: 1
},
{
name: '《代码大全》',
publish: '2006-3',
price: 128,
count: 1
}
]
},
methods: {
increment(key) {
this.books[key].count++;
},
decrement(key) {
this.books[key].count--;
},
remove(key) {
this.books.splice(key, 1);
}
},
computed: {
//计算属性,表示总价格,当监听相关数据有变化时会跟着改变
totalPrice() {
//for in 遍历写法
let sum = 0;
for (let i in this.books) {
sum += this.books[i].price * this.books[i].count;
}
//高阶函数reduce写法
//let sum = this.books.reduce((prev, item) => prev + item.price, 0);
return '¥' + sum.toFixed(2);
}
},
filters: {
//过滤器,将价格进行格式化
singlePrice(value) {
return '¥' + value.toFixed(2);
}
}
})
</script>
</body>
</html>
更多推荐
所有评论(0)