作为一个Java Script的初学者,以此记录做小练习时途中遇到的一点点小问题。
在网上找了很多关于无法找到“xxx”实例的消息,但是要么是太过于高级亦或者太过于不想关的例子,java与前端相关的js技术现在都是用VUE3来实现,以下只是单独抽出来一个js里的小练习里遇到的小错误,以此文章来记录。
第一个例子:(错误例子)
报错信息为:
[Vue warn]: Property "tdl" was accessed during render but is not defined on instance
意思是在执行v-for循环的过程中,tdl被认证通过但是没有实例
也就是说在data(){return {} }里没有拿回到tdl的数据
<form action="" >
<tr v-for="tdl in todoList" :key="tdl.id">
<td>{{tdl.title}} </td>
<td>{{tdl.completed}}</td>
<input type="checkbox" v-model="tdl.completed" @click="changeCompleted(tdl)">
</tr>
</form>
第二个例子:
可是在使用ul+li的时候是没有问题的
例如:
<div>
<!--
methods事件为addTodoAllItem
v-model好像只能用于input标签下
[Vue warn]: Template compilation error: v-model can only be used on <input>, <textarea> and <select> element
-->
<button @click="addTodoAllItem">add</button>
<ul>
<li v-for="todoItem in todosAll" :key="todoItem.id">
{{todoItem.text}}
<input type="button" value="delete" @click="deleteTodoSingleItem(todoItem.id)">
</li>
</ul>
</div>
在以上的ul+li的例子中使用v-for的时候没有报错,也就是说 todoItem in todosAll的时候,被作为接受todosAll数组的数据的参数在被传入的时候没有问题,可以识别出来
第三个例子:
同时,在另一个用form的例子中也没有问题:
例如:
<form action="" >
<table>
<tr v-for="student in studentList">
<td v-if="student.age >=18">
<span class="span1">{{student.name}}</span>
{{student.age}}
</td>
<td v-else>
<span class="span2">{{student.name}}</span>
{{student.age}}
</td>
</tr>
</table>
</form>
但唯独在第一个错误例子中用上form时报错了?
实际上慢慢去对比与剖析发现,在第一个例子中我使用了form的标签,但是里面却没有table标签,同时input标签也不在<td>标签里面。
我没有翻底层源码,不过个人猜测估计是封装底层的时候要把信息给封在<table>组合的<td>之类的标签里才行,不然算不上一个表格,他们应该是整体的,不可划分的。
如果有空还是得看看底层......
所以正确的代码应该是加了<table>和<td>的。即:
<form action="" >
<table>
<tr v-for="tdl in todoList" :key="tdl.id">
<td>{{tdl.title}} </td>
<td>{{tdl.completed}}</td>
<td><input type="checkbox" v-model="tdl.completed" @click="changeCompleted(tdl)"></td>
</tr>
</table>
</form>
这时候就可以正确显示了:
不过值得注意的是如果<table>里有<input>的话也是需要包含在<td>标签里的,不然会报错......嗐,也不知道el-element是不是也这样,我得去试试......
例如:
<td>{{tdl.title}} </td>
<td>{{tdl.completed}}</td>
<input type="checkbox" v-model="tdl.completed" @click="changeCompleted(tdl)">
至此,问题解决:
以下是小练习里的所有代码,个人记录,可供参考------
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>5.10</title>
<style >
.span1{
font-weight: bold;
}
</style>
</head>
<body>
<div id="app">
<!-- 有一个名为 `fruitList` 的数组,数组包含多个水果名称。请使用 `v-for` 循环渲染出
一个无序列表(`ul` 标签),列表中包含数组中所有水果的名称。
例如,如果 `fruitList` 数组为 `['苹果', '香蕉', '橙子', '草莓']`,则渲染出来 -->
<ul>
<li v-for="item in items" >{{item.message}}</li>
<li v-for="item in fruitList1" >{{item.name}}</li>
<li v-for="item1 in fruitList2">
<span v-for="item2 in item1 ">
name={{item2.name}}, price={{item2.price}}
</span>
</li>
<!-- [Vue warn]: Property "todo" was accessed during render but is not defined on instance. at <App> -->
<li v-for="todo in todos" >
<span v-if="todo.isComplete">
{{todo.name}}
</span>
</li>
</ul>
<div>
<!--
methods事件为addTodoAllItem
v-model好像只能用于input标签下
[Vue warn]: Template compilation error: v-model can only be used on <input>, <textarea> and <select> element
-->
<button @click="addTodoAllItem">add</button>
<ul>
<li v-for="todoItem in todosAll" :key="todoItem.id">
{{todoItem.text}}
<input type="button" value="delete" @click="deleteTodoSingleItem(todoItem.id)">
</li>
</ul>
</div>
<!--
有一个名为 `studentList` 的数组,数组包含多个学生对象,
每个学生对象包含 `name` 和 `age` 两个属性。请使用 `v-for` 循环渲染出一个表格,
表格中包含数组中所有学生的姓名和年龄信息。同时,如果某个学生的年龄大于等于 18 岁,则将该学生的姓名显示为粗体。
例如,如果 `studentList` 数组为 `[{name: '小明', age: 16}, {name: '小红', age: 20}, {name: '小刚', age: 17}, {name: '小芳', age: 19}]`
-->
<form action="" >
<table>
<tr v-for="student in studentList">
<td v-if="student.age >=18">
<span class="span1">{{student.name}}</span>
{{student.age}}
</td>
<td v-else>
<span class="span2">{{student.name}}</span>
{{student.age}}
</td>
</tr>
</table>
</form>
<!--
有一个名为 `todoList` 的数组,数组包含多个待办事项对象,
每个待办事项对象包含 `id`、`title`、`completed` 三个属性。
请使用 `v-for` 循环渲染出一个待办事项列表,列表中包含数组中所有待办事项的标题和完成状态。
同时,为每个待办事项渲染一个复选框,当用户点击复选框时,应该触发一个事件,将该待办事项的 `completed` 属性取反。
例如,如果 `todoList` 数组为 `[{id: 1, title: '买牛奶', completed: false}, {id: 2, title: '做作业', completed: true}, {id: 3, title: '打篮球', completed: false}]`
-->
<form action="" >
<table>
<tr v-for="tdl in todoList" :key="tdl.id">
<td>{{tdl.title}} </td>
<td>{{tdl.completed}}</td>
<td><input type="checkbox" v-model="tdl.completed" @click="changeCompleted(tdl)"></td>
</tr>
</table>
</form>
</div>
<script type="module">
import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
let id=0
createApp({
data(){
return {
items : [{message : '111'},{message : '222'},{message : '333'},{message : '444'}],
fruitList1:[{name : '苹果'},{name : '菠萝'},{name : '香蕉'},{name : '榴莲'}],
fruitList2:[[{name : '苹果',price : '0'},{name : '菠萝',price : '5'},{name : '香蕉',price : '10'},{name : '榴莲',price : '20'}]],
todos:[
{name :'1',isComplete: true},
{name :'2',isComplete: true},
{name :'3',isComplete: false},
{name :'4',isComplete: true}
],
newTodo :'',
todosAll :[
{id : id++,text : 'Learn1'},
{id : id++,text : 'Learn2'},
{id : id++,text : 'Learn3'},
{id : id++,text : 'Learn4'}
],
studentList : [
{name: '小明', age: 16},
{name: '小红', age: 20},
{name: '小刚', age: 17},
{name: '小芳', age: 19}
],
todoList :[
{id: 1, title: '买牛奶', completed: false},
{id: 2, title: '做作业', completed: true},
{id: 3, title: '打篮球', completed: false}
]
}
},
methods : {
addTodoAllItem(){
id++;//id自增1
this.newTodo='Learn'+id+'';//将新内容跟id拼接自动组成新的text赋值给newTodo
this.todosAll.push({id:id, text:this.newTodo});//呃,自动装填,设定一个固定对象放里面放,如果时this:newTodo则会报错找不到newTodo
console.log(this.todosAll);
},
deleteTodoSingleItem(todoItemId){//传入一个参数作为主键id来识别唯一的符号
console.log("the is"+todoItemId);
var new_arr=[];
this.todosAll.forEach(item => (item.id != todoItemId && new_arr.push(item)))
this.todosAll = new_arr;
console.log(this.todosAll);
},
//改变todosAll数组里的Completd属性
changeCompleted(tdl){
var new_arr =[];
if(tdl.completed===true){
this.todoList.forEach(element => {
if(element===tdl){
tdl.completed=false;
element=tdl;
new_arr.push(element);
}
else{
new_arr.push(element)
}
});
this.todosAll=new_arr;
}
}
}
}).mount('#app')
</script>
</body>
</html>