项目完善:
算法推荐
item-CF
算法推荐我主要写的是协同过滤算法,然后协同过滤算法分成俩种——
- 基于用户的 user-CF
- 基于物品的 item-CF
因为害怕用户冷启动,和数据量的原因 我选择了 item-CF
主要思路是——根据用户的点赞列表,来找到点赞的相应的文章,通过这些文章去找到 相似度高的物品,然后进行推荐,如果数据不够,我会把浏览量最多的数据给顶上去。
下面是一个demo
数据库对应的数据:(点赞列表的数据)
因此可以看到会推荐三条数据。
Vue
vue是是一个用于构建用户界面的渐进式框架
- {{ }}是插值表达式
- 使用的数据必须要存在
- 支持的是表达式,不能写JavaScript的关键字如 if for
- 不能在标签的属性里面使用
Vue指令
vue会根据不同的指令针对标签实现不同的功能
都是带有v-前缀的特殊标签属性
v-html 相当一innerHTML
v-show 控制元素显示隐藏 v-show后接的是表达式,为true是显示,例如:v-show=“true” 代表显示,false代表隐藏 本质上是通过css的dispaly来控制显示隐藏
v-if 控制元素显示隐藏(条件渲染) v-if也是接表达式,根据表达式的值来进行控制显示隐藏 这个是通过创建和删除元素来控制元素
v-else 后面不接表达式
v-else if 接表达式
v-on 这个是处理监听事件
v-on:事件名:="内联语句"
v-on:事件名称=“methods中的函数名称”
也可以直接写@事件名称=“”
v-bind:动态的设置html的标签属性,比如说src ur title 语法:v-bind:属性名称=“表达式”
可以直接写成 :属性=“表达式”
v-for:基于数据循坏,多次渲染整个元素 语法:v-for="{item,index} in 数组"
v-for里面的key的作用: 给元素添加的唯一标识,便于vue进行列表项的正确排序复用(如果没有设置key,那么删除元素,是把最后一个删除,并且把数据往前面移动)
key的值只能是字符串或者数字类型
key的值必须是具有唯一性
v-model: 给表单元素使用 双向数据绑定 可以快速获取或者设置 表单元素内容 语法:v-model="变量"
案列:
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
body
{
background: #eee;
}
.box
{
margin:50px auto;
background: #fff;
width: 500px;
}
.header
{
display: flex;
margin:0 auto;
box-sizing: border-box;
}
.header .inputTask
{
width: 70%;
padding-left: 20px;
margin-top:10px;
margin-bottom: 10px;
margin-left: 50px;
height: 40px;
box-sizing: border-box;
border-bottom-left-radius: 20px;
border-top-left-radius: 20px;
border: 2px solid #609dbf;
font-size: 16px;
outline: none;
}
.header .addTask
{
width: 30%;
margin-right: 50px;
margin-top:10px;
height: 40px;
box-sizing: border-box;
border: none;
outline: none;
color:#fff;
font-size: 16px;
background: #609dbf;
border-bottom-right-radius: 20px;
border-top-right-radius: 20px;
}
li
{
list-style: none;
}
.taskLi
{
margin-left: 20px;
padding-bottom: 10px;
}
.taskLi
{
margin-top:20px;
display: flex;
margin-right:50px;
border-bottom:2px solid #eee;
}
.taskLi .numLi
{
}
.taskContent
{
flex:1;
margin-left: 20px;
}
.delTask
{
display: none;
}
.taskLi:hover .delTask
{
display: block;
}
.total
{
display: flex;
height: 50px;
line-height: 40px;
font-size: 14px;
color:#666;
}
.totalNum
{
flex:1;
margin-left: 55px;
}
.delAllTask
{
margin-right:50px;
}
</style>
</head>
<body>
<div id="app">
<div class="box">
<div class="header">
<input v-model="content" type="text" class="inputTask" placeholder="请输入任务">
<button class="addTask" @click="addNewTask">添加任务</button>
</div>
<div class="footer">
<ul>
<li class="taskLi" v-for="(item,index) in list" :key="item.id">
<span class="numLi">{{ index + 1 }}</span>
<span class="taskContent">{{ item.name }}</span>
<button class="delTask" @click="delTask(item.id)">x</button>
</li>
</ul>
<div class="total" v-show="list.length!=0">
<span class="totalNum">合计 : {{ list.length }}</span>
<span class="delAllTask" @click="delAllTask">清空任务</span>
</div>
</div>
</div>
</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
content:"",
list:[
{ id:1,name:"开心" },
{ id:2,name:"吃饭" },
{ id:3,name:"看电影" },
{ id:4,name:"睡觉" }
]
},
methods:{
addNewTask()
{
if(this.content.trim()==='')
{
this.content='';
return 0;
}
this.list.unshift({id:+new Date(),name:this.content})
this.content=""
},
delTask(id)
{
this.list=this.list.filter(item => item.id!==id)
},
delAllTask()
{
this.list=[]
}
}
})
</script>
</body>
</html>
指令修饰符
通过 “ . ” 指明一些指令后缀,不同 后缀 封装了 不同的处理操作
按键修饰符
@keyup.enter 就是键盘回车监听事件
v-model修饰符
@v-model.trim 去除首尾空格
事件修饰符号
@事件名.stop 阻止冒泡
@事件名.prevent 阻止默认行为
v-bind 对于1样式控制的增强
- 操作class 语法 :class="对象/数组"
对象: 键就是类名 值是布尔值 如果值为true 有这个类,否则没有
数组:数组中所有的类,都会添加到盒子上,本质是一个class列表
案列:
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.nav
{
margin:20px auto;
width: 600px;
background: #eee;
}
.nav ul
{
display: flex;
padding:0px;
}
li
{
list-style: none;
padding:20px 20px;
font-weight: bold;
}
.active
{
background: #609dbf;
color:#fff;
}
</style>
</head>
<body>
<div id="app">
<div class="nav">
<ul>
<li v-for="(item,index) in list" @click="activeIndex=index" :class="{active:activeIndex==index}">{{ item }}</li>
</ul>
</div>
</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
activeIndex:0,
list:[
'lzy','helios','ares','king'
]
},
methods:{
}
})
</script>
</body>
</html>
- 操作style
语法 :style="样式对象"
案列:
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.bigBox
{
box-sizing: border-box;
margin:40px auto;
width: 400px;
height: 40px;
padding: 5px;
background: black;
border-radius: 20px;
}
.bigBox .smallBox
{
background: aqua;
height: 30px;
width: 390px;
border-radius: 20px;
transition: all 1s;
}
.percent
{
margin:0 auto;
width: 60px;
}
.button
{
width: 250px;
margin: 0 auto;
}
</style>
</head>
<body>
<div id="app">
<div class="bigBox">
<div class="smallBox" :style="{width:percent+'%'}">
</div>
</div>
<div class="percent">{{percent}}%</div>
<div class="button">
<button @click="changePercent(0)">0%</button>
<button @click="changePercent(25)">25%</button>
<button @click="changePercent(50)">50%</button>
<button @click="changePercent(75)">75%</button>
<button @click="changePercent(100)">100%</button>
</div>
</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
percent:0
},
methods:{
changePercent(num)
{
this.percent=num;
}
}
})
</script>
</body>
</html>
计算属性
基于现有的数据,计算出来的新属性,依赖的数据变化,自动重新计算
语法:声明在computed配置项中,一个计算属性对应一个函数 使用起来和普通属性一样使用 也是{{ }}
案列:
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
table,th,td
{
border:1px solid black;
}
table
{
margin:20px auto;
}
th,td
{
padding: 5px 20px;
}
h3
{
width: 180px;
margin: 0 auto;
}
h3 span
{
position: absolute;
transform: translateX(-30px);
transform: translateY(-10px);
background: red;
border-radius: 50%;
width: 20px;
height: 20px;
line-height: 20px;
text-align: center;
color: #fff;
}
</style>
</head>
<body>
<div id="app">
<h3>lzy的购物清单 🛒<span>{{totalSize}}</span></h3>
<table>
<thead>
<th>名称</th>
<th>数量</th>
</thead>
<tbody>
<tr v-for="(item,index) in list" :key="index">
<td>{{item.name}}</td>
<td>{{item.num}}</td>
</tr>
<tr>
<td>总计</td>
<td>{{totalSize}}</td>
</tr>
</tbody>
</table>
</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
percent:0,
list:[
{name:"太阳",num:1},
{name:"月亮",num:1},
{name:"星星",num:7}
]
},
methods:{
},
computed:{
totalSize()
{
return this.list.reduce((sum,item)=>sum+item.num,0);
}
}
})
</script>
</body>
</html>
计算属性和method的区别是 计算属性是由缓存的,method方法是会一直执行
计算属性默认的简写,是只能读取访问,不能修改的
如果需要修改,需要写计算属性的完整写法
computed:{
计算属性名称:{
get()
{}
set(修改的值)
{代码逻辑}
}
}
案列
代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#app
{
width: 300px;
height: 300px;
margin: 0 auto;
}
input
{
margin-left: 10px;
width: 50px;
margin-bottom: 20px;
border-radius: 5px;
}
</style>
</head>
<body>
<div id="app">
姓:<input type="text" v-model="firstName"> + 名:<input type="text" v-model="lastName"> = <span>{{name}}</span>
<br>
<button @click="changeName">改名卡</button>
</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
firstName:'',
lastName:''
},
methods:{
changeName()
{
this.name='lzy'
}
},
computed:{
name:{
get()
{
return this.firstName+this.lastName;
},
set(value)
{
this.firstName=value.slice(0,1);
this.lastName=value.slice(1)
}
}
}
})
</script>
</body>
</html>
案列:
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
th
{
background: skyblue;
height: 40px;
}
td
{
background: #eee;
height: 40px;
}
th,td
{
padding: 0 20px;
}
table
{
margin: 0 auto;
}
.Fail
{
color:red;
}
.dealDel span
{
text-decoration-line: underline;
font-style:italic;
color:deepskyblue;
}
form
{
width: 300px;
margin: 0 auto;
}
form input
{
margin-bottom: 10px;
height: 30px;
padding-left: 10px;
}
button
{
padding: 5px 20px;
background: blue;
outline: none;
border: 0;
color: #fff;
}
</style>
</head>
<body>
<div id="app">
<table>
<thead>
<th>编号</th>
<th>科目</th>
<th>成绩</th>
<th>操作</th>
</thead>
<tbody v-if="list.length > 0">
<tr v-for="(item,index) in list">
<td>{{ index+1 }}</td>
<td>{{ item.subject }}</td>
<td :class="{Fail:item.score<60}">{{item.score}}</td>
<td class="dealDel">
<span @click="delOne(index)">删除</span>
</td>
</tr>
</tbody>
<tbody v-else>
<tr>
<td colspan="4" style="text-align: center;">
暂无数据
</td>
</tr>
</tbody>
<tr>
<td colspan="4">
总分:<span>{{ sum }}</span>
平均分:<span>{{ average }}</span>
</td>
</tr>
</table>
<br>
<form action="">
科目:<input type="text" v-model.trim="subject" placeholder="请输入科目">
<br>
成绩:<input type="text" v-model="score" placeholder="请输入成绩">
<br>
<button type="button" class="ensure" @click="addNew">确认</button>
</form>
</div>
<script src="js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
list:[
{subject:'语文',score:46},
{subject:'数学',score:80},
{subject:'英语',score:60}
],
subject:'',
score:''
},
methods:{
delOne(i)
{
this.list=this.list.filter((item,index)=>index!=i);
},
addNew()
{
this.list.push({subject:this.subject,score:+this.score})
this.score=''
this.subject=''
}
},
computed:{
sum(){
return this.list.reduce((sum,item)=>sum+=item.score,0);
},
average(){
if(this.list.length>0)
return this.sum/this.list.length*100/100;
else return 0
}
}
})
</script>
</body>
</html>